I am currently developing a few Web services using the JAX-WS reference implementation (version 2.1.7). They are contract-based, that is, the WSDL and XSD files are not generated by wsgen.
This allows me to freely use XSD restrictions to strengthen validation of values passed to my services through SOAP messages. Here are two examples of such “restricted” XSD elements:
<xsd:element name="maxResults" minOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:minInclusive value="1"/>
<xsd:maxInclusive value="1000"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="lastName" minOccurs="0">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="1"/>
<xsd:maxLength value="25"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
I added the @SchemaValidation annotation to my service classes to enforce schema validation. However, JAX-WS does not enforce validation rules as expected. The behaviour is as follows:
- Missing mandatory elements are correctly reported (e.g., missing
maxResults). - Invalid values (e.g., character data in an integer field) are correctly reported too.
- Interval restriction violations (e.g.,
maxResults> 1000 ormaxResults< 1) pass through the validation process without being reported and are injected into my JAXB-generated Java structures. Even negative values are considered valid despite thexsd:positiveIntegertype! - String length constraint violations (e.g.,
lastNamelength over 25 characters) are not reported either.
In other words, restrictions that appear in <xsd:element> tags are correctly enforced but <xsd:restriction> elements seem to be totally ignored by JAXB when used in a JAX-WS-based context.
I wrote a test class to check my XSD restrictions using bare JAXB (no JAX-WS). As a result, all restrictions are correctly enforced.
This gives me the feeling that there might be a bug in the usage of JAXB by JAX-WS… unless there is something I am doing incorrectly, of course…
Am I missing something fundamental here?!?
Thanks in advance for any help,
Jeff
I finally found what’s wrong…
In order to get my Web services to work in a JUnit context, i.e. published through
Endpoint.publish(), I had to remove thewsdlLocationattribute from my@WebServiceannotations. If I don’t, thewsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl"passed to the@WebServiceannotation clashes with the URL value passed to theEndpoint.publish()method,http://127.0.0.1:9000/rpe-ws/SearchIndividuals.After reading Glen Mazza’s Weblog (http://www.jroller.com/gmazza/entry/soap_xml_schema_validation), Additional Notes section, I put back the
wsdlLocationattribute and all restrictions are now properly enforced.In other words, removing the
wsdlLocationin a@WebServiceannotation does not prevent the service itself from working, but prevents restrictions declared in<xsd:restrictions>elements from being properly enforced. Restrictions declared in<xsd:element>elements, however, are still correctly enforced.I am therefore getting back to having to solve that
wsdlLocationcompatibility problem to make my unit tests work properly, but this is way less critical than non-working validations in a production context…Just in case… Anyone has an idea about this WSDL location incompatibility when running a Web service in a non-Web context?
Thanks,
Jeff