Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate soap requests against schema in a JAX-WS code-first approach

I created a JAX-WS webservice, using JAXB annotations on some request fields to make them mandatory.

@XmlElement(required = true)
protected String number;

The WSDL generated by cxf-java2ws-plugin is correct, there is no minOccurs="0" on the fields :

<xs:element name="number" type="xs:string"/>

But when the service receives a request that does not respect these constraints (missing fields), no SoapFault or exception is thrown.

I also tried adding @SchemaValidation to my WS class, with no effect.

How request validation against schmema (or rather validation against annotation-based constraints) can be automated?

like image 262
kgautron Avatar asked Dec 10 '14 10:12

kgautron


People also ask

How do you validate a SOAP request?

To validate a SOAP message, open the SOAP message file (screenshot below) and press F8 (or the menu command XML | Validate). Since no WSDL file has been linked to the SOAP message file, the SOAP message is validated according to the rules for SOAP messages.

What is JAX-WS how it is useful for describing SOAP web services?

JAX-WS is a technology for building web services and clients that communicate using XML. JAX-WS allows developers to write message-oriented as well as RPC-oriented web services. In JAX-WS, a web service operation invocation is represented by an XML-based protocol such as SOAP.


2 Answers

The default value for minOccurs is 1. So, your value must exist.
The default value for nillable is false. So, your value cannot be empty.
And you have activated the schema validation in your web service:

@WebService
@SchemaValidation(enabled = true)
public class MyService {
//...
}

And, last but not least, you have a resulting schema.

But, the JAXB reference implementation does not any validation for you.

You have to do this by your own, using the Java Xml Validation API

Here a simple example of schema validation

public class XmlSchemaValidation {

    public static void main(String[] args) throws Exception {
        Something myObject = new Something();
        validate(myObject);
    }
    public static void validate(Something myObject) throws Exception {

        Schema s = SchemaFactory
                   .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
                   .newSchema(new File("Something.xsd"));

        Validator validator = s.newValidator();
        //You can set an error handler
        //validator.setErrorHandler(errorHandler);
        validator.validate( new JAXBSource(JAXBContext.newInstance(Something.class), myObject));
    }

}
like image 102
Gren Avatar answered Sep 27 '22 21:09

Gren


I propose two workarounds to your problem, if you can't solve it :

  1. Validate your bean after JAXB unmarshaling
  2. Use CXF Validation Feature

Validation after JAXB unmarshaling

I think you can add a JAXB callback afterUnmarshal() in your Java request bean (as described here), and perform all validation you want in it (format validation, or others).

For example :

@XmlRootElement
public class YourRequest {

    @XmlElement(required = true)
    protected String number;

    // some code here

    public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
       if(number == null) {
           // Throw validation exception
       }
    }

}

CXF Validation feature

Another possibility is to use Bean Validation with CXF (as documented here). Usually, it's not necessary for a schema-based validation, but if you need to have a more complex validation than a schema-based one, I think it can be a solution to your problem after all.

I hope it can help you while waiting a better answer.

like image 39
KevinHol Avatar answered Sep 27 '22 19:09

KevinHol