2011-11-24 43 views
6

在JAX-WS中,要驗證傳入的請求,其中一種方法是使用@SchemaValidation,如下面的鏈接所示。使用JAXB的JAX-WS請求驗證

JAX-WS and XSD Validation

但是我使用還不支持@SchemaValidation應用服務器(WAS 7)。 (如果WAS 7確實支持這個註解,請糾正我)

所以我正在尋找其他選項,如執行處理程序來驗證傳入的請求。無論是在處理程序還是端點類本身,我都可以創建JAXBContext並使用JAXB驗證程序。我是否需要顯式創建JAXBContext,或者因爲JAX-WS內部使用JAXB,它是否可用作資源/註釋? 這是一個在JAX-WS中實現驗證的好方法嗎? (在沒有@SchemaValidation驗證)

這是一個標準的做法來驗證傳入的請求xml在Web服務中,還是由於它可能需要的性能打擊而被給予跳過?

回答

2

與每個MVC系統一樣,驗證傳入請求xml是一種很好的做法。 (MVC可能不適合這裏,但原則上,它只是視圖是XML)。如果上述註釋(@SchemaValidation)不被支持,那麼一個出路是使用處理程序,它將使用JAXB Validation驗證傳入的請求。

+2

謝謝Santosh。我已經實現了處理程序來驗證傳入的請求。以下鏈接非常有用[鏈接](http://java.dzone.com/articles/jax-ws-payload-validation-and)。 – PrasadB

+0

確實不錯。感謝分享。 – Santosh

+0

鏈接現在壞了=( – secario

0

如果您是一個大型組織,更好的做法是使用DataPower。它會爲你做驗證以及各種功能。就最佳實踐而言,我會建議DataPower僅僅是因爲它是爲此設計的,但是您需要確保開發可以驗證的代碼,否則就會在運行時遇到驗證問題。

我也不建議使用@SchemaValidation,因爲這是供應商特定的而不是標準。這就是說,我在爲我的參考Java EE應用程序(不使用任何供應商特定的API)進行攔截器操作時編寫了以下內容。

/** 
* Validates the XML streams going in the request and response if the log level 
* is {@link Level#FINER} or below against {@value #LOGGER_NAME}. If 
* {@link Level#FINEST} is used it will also dump the XML that were sent. 
* 
* @author Archimedes Trajano 
* 
*/ 
public class XmlValidationInterceptor { 
    /** 
    * Logger. 
    */ 
    private static final Logger LOG; 

    /** 
    * Name of the logger. 
    */ 
    public static final String LOGGER_NAME = "xml.validation"; //$NON-NLS-1$ 

    static { 
     LOG = Logger.getLogger(LOGGER_NAME, "Messages"); //$NON-NLS-1$ 
    } 

    /** 
    * Contains a composite of multiple schema files into one schema that used 
    * on all message validations. 
    */ 
    private final Schema schema; 

    /** 
    * Loads up the schema into memory. This uses the default 
    * 
    * @throws SAXException 
    *    problem parsing the schema files. 
    */ 
    public XmlValidationInterceptor() throws SAXException { 
     final SchemaFactory sf = SchemaFactory 
       .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     schema = sf.newSchema(); 
    } 

    /** 
    * Loads up the schema from the specified array of {@link Source} into 
    * memory. 
    * 
    * @param schemaSources 
    *   schema sources. 
    * @throws SAXException 
    *    problem parsing the schema files. 
    */ 
    public XmlValidationInterceptor(final Source... schemaSources) 
      throws SAXException { 
     final SchemaFactory sf = SchemaFactory 
       .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     schema = sf.newSchema(schemaSources); 
    } 

    /** 
    * Writes the object as XML to the logger. 
    * 
    * @param param 
    *   object to marshal 
    * @param context 
    *   invocation context used for logging. 
    * @throws JAXBException 
    *    problem with the Java binding except schema issues because 
    *    schema validation errors are caught and processed 
    *    differently. 
    */ 
    private void marshalObject(final Object param, 
      final InvocationContext context) throws JAXBException { 
     if (!param.getClass().isAnnotationPresent(XmlRootElement.class)) { 
      return; 
     } 

     // validate against known schemas 
     final JAXBContext jaxbContext = JAXBContext.newInstance(param 
       .getClass()); 
     final Marshaller m = jaxbContext.createMarshaller(); 
     m.setSchema(schema); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     try { 
      final StringWriter w = new StringWriter(); 
      m.marshal(param, w); 
      LOG.finest(w.toString()); 
     } catch (final MarshalException e) { 
      if (!(e.getLinkedException() instanceof SAXParseException)) { 
       throw e; 
      } 
      final SAXParseException parseException = (SAXParseException) e 
        .getLinkedException(); 
      LOG.log(Level.SEVERE, 
        "XmlValidationInterceptor.parseException", // $NON-NLS-1$ 
        new Object[] { context.getMethod(), param, 
          parseException.getMessage() }); 
      m.setSchema(null); 
      final StringWriter w = new StringWriter(); 
      m.marshal(param, w); 
      LOG.finest(w.toString()); 
     } 
    } 

    /** 
    * Validates the data in the parameters and return values. 
    * 
    * @param context 
    *   invocation context 
    * @return invocation return value 
    * @throws Exception 
    *    invocation exception 
    */ 
    @AroundInvoke 
    public Object validate(final InvocationContext context) throws Exception { 
     if (!LOG.isLoggable(Level.FINER)) { 
      return context.proceed(); 
     } 

     final Object[] params = context.getParameters(); 
     for (final Object param : params) { 
      marshalObject(param, context); 
     } 

     final Object ret = context.proceed(); 
     if (ret != null) { 
      marshalObject(ret, context); 
     } 
     return ret; 
    } 

} 
+0

感謝Archimedis,我會檢查DataPower是否是我們組織中的一個選項,並且我認爲@SchemaValidation是JAX-WS標準的一部分,而不是供應商特定的。驗證我需要在解組到Java對象之前驗證傳入的xml – PrasadB

+0

我有一個使用JAX-WS處理程序的舊實現,但是我發現它是特定於SOAP的,所以我決定嘗試使用攔截器,因爲它不需要是SOAP特定的。 –