2011-11-24 24 views
6

In JAX-WS, per convalidare la richiesta in arrivo, uno dei modi è utilizzare @SchemaValidation come suggerito nel link sottostante.Convalida della richiesta JAX-WS utilizzando JAXB

JAX-WS and XSD Validation

Tuttavia l'application server (WAS 7) Sto usando non supporta ancora @SchemaValidation. (Si prega di correggermi se WAS 7 supporta questa annotazione)

Quindi sto osservando altre opzioni come implementare un gestore per convalidare la richiesta in arrivo. Sia nel gestore che nella classe dell'endpoint stesso, posso creare il JAXBContext e utilizzare il validatore JAXB. Devo creare esplicitamente JAXBContext o è disponibile come risorsa/annotazione poiché JAX-WS utilizza internamente JAXB? È un buon modo per implementare la validazione in JAX-WS? (In assenza di convalida @SchemaValidation)

È una pratica standard per convalidare la richiesta xml in entrata nei servizi Web o è data una saltata a causa del colpo di prestazioni che potrebbe richiedere?

risposta

2

È buona norma convalidare la richiesta xml in entrata, come nel caso di ogni sistema MVC. (MVC potrebbe non adattarsi qui, ma in linea di principio, è lo stesso solo che la vista è XML). Se l'annotazione citata (@SchemaValidation) non è supportata, l'unica via d'uscita è il gestore di utilizzo che convaliderà la richiesta in arrivo utilizzando JAXB Validation.

+2

Grazie Santosh. Ho implementato il gestore per convalidare la richiesta in arrivo. Il seguente collegamento è stato molto utile [collegamento] (http://java.dzone.com/articles/jax-ws-payload-validation-and). – PrasadB

+0

Bel collegamento davvero. Grazie per la condivisione. – Santosh

+0

collegamento è rotto ora = ( – secario

0

Una pratica migliore se si è un'organizzazione GRANDE è l'uso di DataPower. Farà le convalide per voi insieme a una varietà di funzionalità. Per quanto riguarda le migliori pratiche, suggerirei DataPower solo perché è stato progettato per questo, ma è necessario assicurarsi di sviluppare codice che possa essere validato altrimenti si verifichino problemi di convalida in fase di runtime.

Inoltre NON è consigliabile utilizzare @SchemaValidation poiché è specifico del fornitore piuttosto che standard.

Detto ciò, ho scritto quanto segue quando stavo giocando intorno agli intercettori per la mia applicazione Java EE di riferimento che non utilizza API specifiche del fornitore.

/** 
* 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

Grazie Archimedis. Controllerò se DataPower è un'opzione nella nostra organizzazione. Inoltre, ho pensato che @SchemaValidation sia parte dello standard JAX-WS e non specifico del fornitore. Ho utilizzato un gestore JAX-WS per convalidare come ho bisogno di convalidare il xml in arrivo prima di unmarshalling in oggetti Java – PrasadB

+0

Ho avuto una vecchia implementazione che utilizza gestori JAX-WS, ma ho trovato che fosse SOAP specifico, quindi ho deciso di provare gli intercettori perché non ha bisogno di essere specifici per SOAP. –

Problemi correlati