Search code examples
javaweb-servicessoapjbosswsdl

Jax-Ws Unmarshalling Error


I'm having an issue with Jax-Ws and also after searching the net for day I found no working solution. I'm running my Soap Ws on a local jboss eap7.

The relevant snippet of my wsdl looks like this:

<xs:complexType name="simpleTravelingDay">
<xs:sequence>
  <xs:element name="gid" type="xs:string"/>
  <xs:element name="dayType" type="xs:long"/>
  <xs:element name="date" type="xs:dateTime"/>
  <xs:element name="projectId" type="xs:long"/>

My webservice looks like this:

@WebService(name = "TravelTrackerWS")
public interface TravelTrackerWSLocal {

  @WebMethod(operationName = "fillSimpleTravelingDays")
  public WsAnswer fillSimpleAndTravelingDays(
      @XmlElement(required = true, nillable = false) @WebParam(name = "SimpleAndTravelingDays") List<SimpleTravelingDay> days)
      throws InsufficientRightsException;

}

If I do a request like this:

  <soapenv:Header/>
   <soapenv:Body>
  <ser:fillSimpleTravelingDays>
     <!--1 or more repetitions:-->
     <SimpleAndTravelingDays>
        <gid>Z0030UDK</gid>
        <date>2014-10-31</date>
        <country>AU</country>
        <projectId>a</projectId>
     </SimpleAndTravelingDays>
  </ser:fillSimpleTravelingDays>

I get an Unmarshalling Error, which is correct, because 'a' is a String and not Long.

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Client</faultcode>
     <faultstring>Unmarshalling Error: For input string: "a"</faultstring>
  </soap:Fault>

My Question right now is. How can I catch the Unmarshalling Error, so that I can throw a generic error message instead of the unmarshalling error.

I hope anyone can help me


Solution

  • You can change error message using ValidationEventHandler.

    Eg:

    import javax.xml.bind.ValidationEvent;
    import javax.xml.bind.helpers.DefaultValidationEventHandler;
    
    public class MyValidationEventHandler extends DefaultValidationEventHandler {    
        @Override
        public boolean handleEvent(ValidationEvent event) {
            if (event.getSeverity() == ValidationEvent.WARNING) {
                return super.handleEvent(event);
            } else {
                throw new RuntimeException("My custom message");
            }
        }
    }
    

    To configure your endpoint to use this handler you can add a interceptor that inserts handler to the context.

    public class ValidationInterceptor extends AbstractPhaseInterceptor<Message> {
    
    
        public ValidationInterceptor() {
            super(Phase.READ);
        }
    
        public void handleMessage(Message message) throws Fault {
            message.setContextualProperty("jaxb-validation-event-handler", new MyValidationEventHandler());
    
        }
    
    }
    

    Finally your endpoint looks like:

    @WebService(endpointInterface="org.jboss.test.schemavalidation.TestWS")
    @InInterceptors(classes = {ValidationInterceptor.class})
    public class TestWSImpl implements TestWS{
    
        public Integer sum(Integer a, Integer b) {
            return a + b;
        }
    
    }
    

    In JBoss 7 for this works you must add the dependency to cxf:

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-deployment-structure>
        <deployment>
            <dependencies>
                <module name="org.apache.cxf" services="import" />
            </dependencies>
        </deployment>
    </jboss-deployment-structure>
    

    You can see a full example in: https://github.com/fedesierr/schemavalidation-ws