Skip to content

Instantly share code, notes, and snippets.

@agaoglu
Created December 5, 2011 17:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agaoglu/1434472 to your computer and use it in GitHub Desktop.
Save agaoglu/1434472 to your computer and use it in GitHub Desktop.
An example exception handler for JAX-WS without code generation
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.DetailEntry;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPException;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class JaxWsExceptionCatcher {
private static final class MyExceptionHandler<T> implements
InvocationHandler {
private final T port;
private MyExceptionHandler(T port) {
this.port = port;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
return method.invoke(port, args);
} catch (InvocationTargetException e) {
Throwable bre = e.getTargetException().getCause();
if (bre != null && bre instanceof MyRuntimeException) {
throw bre.getCause();
}
throw e;
}
}
}
private static class MyRuntimeException extends RuntimeException {
private static final long serialVersionUID = -2143724572440079147L;
private MyRuntimeException(MyException cause) {
super(cause);
}
}
private static class MyFaultHandler implements
SOAPHandler<SOAPMessageContext> {
private final String namespace;
public MyFaultHandler(String namespace) {
this.namespace = namespace;
}
@Override
public boolean handleMessage(SOAPMessageContext context) {
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
try {
DetailEntry detailEntry = (DetailEntry) context.getMessage()
.getSOAPBody().getFault().getDetail()
.getDetailEntries().next();
if (detailEntry.getNamespaceURI().equals(namespace)
&& detailEntry.getLocalName().equals("MyException")) {
String code = ((Node) detailEntry.getChildElements(
new QName("code")).next()).getTextContent();
String message = ((Node) detailEntry.getChildElements(
new QName("message")).next()).getTextContent();
if (code != null && message != null) {
throw new MyRuntimeException(new MyException(code,
message));
}
}
return true;
} catch (NullPointerException e) {
// Soap fault is not in the format we expected
return true;
} catch (SOAPException e) {
return true;
}
}
@Override
public void close(MessageContext context) {
}
@Override
public Set<QName> getHeaders() {
return null;
}
}
public final static <T> T catchOn(final T port, String namespace) {
Binding binding = ((BindingProvider) port).getBinding();
List<Handler> handlerChain = binding.getHandlerChain();
handlerChain.add(new MyFaultHandler(namespace));
binding.setHandlerChain(handlerChain);
Object pi = Proxy.newProxyInstance(port.getClass().getClassLoader(),
port.getClass().getInterfaces(),
new MyExceptionHandler<T>(port));
return (T) pi;
}
}
@agaoglu
Copy link
Author

agaoglu commented Dec 6, 2011

See the post for some explanation on using this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment