Patrick Koorevaar
Patrick Koorevaar

Reputation: 1343

How to send custom response message instead of Fault message in case of an exception with JAXWS?

In my JAXWS web service I need to send a specific message back to the client when an exception occurs, not the standard Fault message with the description of the exception.

How can this be done?

I am using jaxws-rt version 2.1.3

I have already tried to use exception mappers like this but without luck (some how they are not called, this could also be caused by a mistake in the configuration):

@Provider
public class ThrowableExceptionMapper implements ExceptionMapper<Throwable> {

    public ThrowableExceptionMapper() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public Response toResponse(Throwable throwable) {
        if (throwable instanceof WebApplicationException) {
            return ((WebApplicationException) throwable).getResponse();
        } else {
            return Response.serverError().entity("").build();
        }
    }
}

The server we use is JBoss EAP 6.4.

Edit:
The exception mapper approach is not suited for my JAXWS web service, because this is for JAX-RS (thanks SRINIVAS K). Is there something similar available for JAXWS?

Upvotes: 1

Views: 3852

Answers (3)

Patrick Koorevaar
Patrick Koorevaar

Reputation: 1343

I managed to rewrite the response message with the help of this page:
http://www.java-tips.org/java-ee-tips-100042/156-java-api-for-xml-web-services/1958-writing-a-handler-in-jax-ws.html

And with some examples of this page:
http://www.programcreek.com/java-api-examples/index.php?api=javax.xml.ws.handler.MessageContext

I put together this class:

public class MyLogicalHandler implements LogicalHandler<LogicalMessageContext> {
    private final String RejectionResponseBody = "<ns2:MessageControllerResponse xmlns:ns2=\"http://some.namespace.com/\"><return>SOMEDATA</return></ns2:MessageControllerResponse>";

    @Override
    public boolean handleMessage(LogicalMessageContext context) {       
        return true;
    }

    @Override
    public boolean handleFault(LogicalMessageContext context) {
        processMessage(context);
        return true;
    }

    @Override
    public void close(MessageContext context) {

    }

    private void processMessage(LogicalMessageContext context) {
        Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (outboundProperty) {
            LogicalMessage msg = context.getMessage();
            msg.setPayload(new StreamSource(new ByteArrayInputStream(RejectionResponseBody.getBytes())));
        }
    }   
}

Edit, additional information added:

You also need to add the HandlerChain annotation to the web service:

...
@HandlerChain(file = "handler-chain.xml")
public class MyWebService {
...
}

And create a handler-chain xml file:

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">  
  <handler-chain>
    <handler>
      <handler-class>my.package.ws.jaxws.MyLogicalHandler</handler-class>
    </handler>
  </handler-chain>
</handler-chains>

And place this file in your resources folder of the web service, you need to use the same package structure as you did with the web service. So create the following package: my.package.ws in the resources folder if your web service class resides in the my.package.ws package.

Upvotes: 1

kswaughs
kswaughs

Reputation: 3087

Can you check if ExceptionMapper works with generic exceptions like Throwable or Exception.
I see some examples with custom defined exceptions that are configured with WebFault annotation.

Upvotes: 0

Garry
Garry

Reputation: 4533

Can you try using below?

String errorMessage = "this is custom error message";
return Response.status(e.getResponse().getStatus()).entity(errorMessage).build(); 

Upvotes: 1

Related Questions