Handlers extends com.sun.xml.ws.api.handler.MessageHandler
SoapBaseHandler
import com.sun.xml.ws.api.handler.MessageHandler;
import com.sun.xml.ws.api.handler.MessageHandlerContext;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import java.util.Set;
public abstract class SoapBaseHandler implements MessageHandler<MessageHandlerContext> {
public Set<QName> getHeaders() {
return null;
}
@Override
public void close(MessageContext context) {
}
protected static boolean isOutbound(MessageHandlerContext context) {
return (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
}
}
SoapLoggingHandler
import com.sun.xml.ws.api.handler.MessageHandlerContext;
import com.sun.xml.ws.api.message.Message;
import com.sun.xml.ws.api.streaming.XMLStreamWriterFactory;
import javanet.staxutils.IndentingXMLStreamWriter;
import ru.scartel.paymentsystems.common.context.AppContext;
import ru.scartel.paymentsystems.common.logging.Logger;
import ru.scartel.paymentsystems.common.utils.IOUtil;
import javax.xml.stream.XMLStreamWriter;
/**
* <p/>
* Refactored from:
*
* @see {http://weblogs.java.net/blog/ramapulavarthi/archive/2007/12/extend_your_web.html
* http://fisheye5.cenqua.com/browse/jax-ws-sources/jaxws-ri/samples/efficient_handler/src/efficient_handler/common/LoggingHandler.java?r=MAIN}
* <p/>
* This simple LoggingHandler will log the contents of incoming
* and outgoing messages. This is implemented as a MessageHandler
* for better performance over SOAPHandler.
*/
public abstract class SoapLoggingHandler extends SoapBaseHandler {
private static final Logger LOGGER = Logger.get(SoapLoggingHandler.class);
protected enum HANDLER {
NONE {
@Override
public boolean handleMessage(MessageHandlerContext mhc) {
return true;
}
@Override
public boolean handleFault(MessageHandlerContext mhc) {
return true;
}
},
ERROR_SERVER {
private static final String INBOUND_MSG = "INBOUND_MSG";
public boolean handleFault(MessageHandlerContext context) {
LOGGER.error("Fault SOAP request:\n" + getMessageText(((Message) context.get(INBOUND_MSG))), "SOAPServerFault");
return true;
}
public boolean handleMessage(MessageHandlerContext context) {
if (!isOutbound(context)) {
context.put(INBOUND_MSG, context.getMessage().copy());
}
return true;
}
},
ERROR_CLIENT {
private static final String OUTBOUND_MSG = "OUTBOUND_MSG";
public boolean handleFault(MessageHandlerContext context) {
LOGGER.error("Fault SOAP request:\n" + getMessageText(((Message) context.get(OUTBOUND_MSG))), "SOAPClientFault");
return true;
}
public boolean handleMessage(MessageHandlerContext context) {
if (isOutbound(context)) {
context.put(OUTBOUND_MSG, context.getMessage().copy());
}
return true;
}
},
FINE {
public boolean handleFault(MessageHandlerContext context) {
LOGGER.error("Fault SOAP message:\n" + getMessageText(context.getMessage().copy()), "SOAPFault");
return true;
}
public boolean handleMessage(MessageHandlerContext context) {
String str = isOutbound(context) ? "SOAP response:\n" : "SOAP request:\n";
LOGGER.info(str + getMessageText(context.getMessage().copy()));
return true;
}
};
public abstract boolean handleMessage(MessageHandlerContext mhc);
public abstract boolean handleFault(MessageHandlerContext mhc);
protected static String getMessageText(Message msg) {
try {
IOUtil.StringOutputStream out = new IOUtil.StringOutputStream();
XMLStreamWriter writer = XMLStreamWriterFactory.create(out);
//Class clazz = getClass().getClassLoader().loadClass("javanet.staxutils.IndentingXMLStreamWriter");
//Constructor c = clazz.getConstructor(XMLStreamWriter.class);
//wrap = (XMLStreamWriter) c.newInstance(writer);
IndentingXMLStreamWriter wrap = new IndentingXMLStreamWriter(writer);
msg.writeTo(wrap);
return out.toString();
} catch (Exception e) {
LOGGER.warn("Coudn't get SOAP message for logging", e);
return null;
}
}
}
abstract protected HANDLER getHandler(Logger.LOGGING_LEVEL level);
public boolean handleMessage(MessageHandlerContext mhc) {
return getHandler(AppContext.getLoggingLevel()).handleMessage(mhc);
}
public boolean handleFault(MessageHandlerContext mhc) {
return getHandler(AppContext.getLoggingLevel()).handleFault(mhc);
}
}
Логгирование на стороне JAX-WS client
SoapClientLoggingHandler
import ru.scartel.paymentsystems.common.logging.Logger;
import ru.scartel.paymentsystems.common.utils.Util;
import java.util.EnumMap;
public class SoapClientLoggingHandler extends SoapLoggingHandler {
private static EnumMap<Logger.LOGGING_LEVEL, HANDLER> HANDLER_MAP =
(EnumMap<Logger.LOGGING_LEVEL, HANDLER>) Util.asEnumMap(Logger.LOGGING_LEVEL.class,
Logger.LOGGING_LEVEL.NONE, HANDLER.NONE,
Logger.LOGGING_LEVEL.ERROR, HANDLER.ERROR_CLIENT,
Logger.LOGGING_LEVEL.FINE, HANDLER.FINE);
@Override
protected HANDLER getHandler(Logger.LOGGING_LEVEL level) {
return HANDLER_MAP.get(level);
}
}
JAX-WS client code
...
public <WS> WS initWebService(URL wsdlLocation, String targetNamspace, String servicename, String portName, Class<WS> clazz) throws MalformedURLException {
Service service = Service.create(wsdlLocation, new QName(targetNamspace, servicename));
WS port = (portName == null) ? service.getPort(clazz) : service.getPort(new QName(targetNamspace, portName), clazz);
WsUtil.setTimeout(port, 30000); // 30 sec default
Binding binding = ((BindingProvider) port).getBinding();
List<Handler> handlerList = binding.getHandlerChain();
if (handlerList == null) {
handlerList = Collections.singletonList((Handler) new SoapClientLoggingHandler());
} else {
handlerList.add(new SoapClientLoggingHandler());
}
binding.setHandlerChain(handlerList);
return port;
}
Логгирование на стороне JAX-WS service
SoapServerLoggingHandler
import ru.scartel.paymentsystems.common.logging.Logger;
import ru.scartel.paymentsystems.common.utils.Util;
import java.util.EnumMap;
public class SoapServerLoggingHandler extends SoapLoggingHandler {
private static EnumMap<Logger.LOGGING_LEVEL, HANDLER> HANDLER_MAP =
(EnumMap<Logger.LOGGING_LEVEL, HANDLER>) Util.asEnumMap(Logger.LOGGING_LEVEL.class,
Logger.LOGGING_LEVEL.NONE, HANDLER.NONE,
Logger.LOGGING_LEVEL.ERROR, HANDLER.ERROR_SERVER,
Logger.LOGGING_LEVEL.FINE, HANDLER.FINE);
@Override
protected HANDLER getHandler(Logger.LOGGING_LEVEL level) {
return HANDLER_MAP.get(level);
}
}
wsHandlers.xml
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-name>SoapLoggingHandler</handler-name>
<handler-class>ru.scartel.paymentsystems.common.ws.handlers.SoapServerLoggingHandler</handler-class>
</handler>
<handler>
<handler-name>SoapStatisticHandler</handler-name>
<handler-class>ru.scartel.paymentsystems.common.ws.handlers.SoapStatisticHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
JAX-WS Service
@WebService(serviceName = "...", endpointInterface = "...", targetNamespace = "...")
@HandlerChain(file = "wsHandlers.xml")
public class ...Service implements ... {