jaxbjax-wsjax-ws-customization

How to return SOAPFault from XMLAdapter?


I'm developing a SOAP based WebService (JAX-WS) and dates come with specific format "yyyymmdd". My WSDL defines the date as string but I would like to return a SOAP fault response when the expected format is not followed by the element value. I've defined an XMLAdapter for element and tried the following in unmarshall method:

public XMLGregorianCalendar unmarshal(String value) throws Exception {
    if (!checkCorrectFormat(value)){
        throw new RuntimeException();
    }

    return ParseHelper.getInstance().parseStrDateToXMLDate(value);
}

But the exception is lost and the WebService goes on without problem getting a null XMLGregorianCalendar value for the unmarshalled element. Perhaps this is not the right place to implement this format control... Any help would be appreciated.


Solution

  • Consider implementing this regex restriction in your xsd:

      <xsd:simpleType name="MySpecialDate">
        <xsd:restriction base="xsd:string">
          <xsd:pattern value="\d{4}\d{2}\d{2}"/>
          <xsd:whiteSpace value="collapse"/>
        </xsd:restriction>
      </xsd:simpleType>
    

    \d{4}-\d{2}-\d{2} might not be quite as strict as you need to follow the rules of a gregorian calendar. For instance, 20121312 would not be a valid gregorian date because there is no 13th month in the gregorian calendar but it would still pass your regex restriction. But you can definitely create a regex that conform to the gregorian rules with a couple google searches.

    And then, let JAXWS do the schema validation for you. see "To activate Service-side validation" on http://www.jroller.com/gmazza/entry/soap_xml_schema_validation

    Also, if you have to do the ccyymmdd format you can't use xsd:date which, in my mind, would be preferable because Jaxb will create a java.util.Date for you as your property right from the start. You can still achieve this (generating a java.util.Date) with your custom ccyymmdd format but it is a little more work. You would probably use a jaxb custom binding. Something like this would go into your .jxb file and used with the xjc task:

    <jxb:bindings node="//xs:simpleType[@name='MySpecialDate']">
      <jxb:javaType name="java.util.Date"
            parseMethod="com.company.DateConverter.parseMySpecialDate" 
            printMethod="com.wpsic.tricare.ws.converter.DateConverter.printMySpecialDate" />
    </jxb:bindings>