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

3

12

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?

Sleeping answered 10/12, 2014 at 10:1 Comment(2)
I just added the annotation @SchemaValidation on my WS and it began to work: cvc-complex-type.2.4.a: Invalid content was found starting with element 'email'. One of '{pwd}' is expectedCharleencharlemagne
yeap... 6 years later, working with SOAP again and CXF, adding the same @SchemaValidation but from org.apache.cxf.annotations.SchemaValidation workedCharleencharlemagne
S
4

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));
    }

}
Shilohshim answered 14/12, 2014 at 14:24 Comment(0)
H
2

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.

Homosporous answered 14/12, 2014 at 13:55 Comment(0)
H
1

Use some tool like jaxb2-maven-plugin to generate the JAXB Class. and Validate before sending the payload to the WebService or before accepting the payload in to your system using JSR 303 Specification. Click Here to see the JSR 303 Validator.

This will make your system Robust.

Hystero answered 16/12, 2014 at 20:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.