在JAVA实现的Web service的客户端和服务器端都可以通过handler来实现对SOAP消息的访问,典型的应用可以用来保存SOAP消息(作为Log,或者在流程失败的时候重新发消息,或者操作SOAP header设定security信息等).
Handler有两类,一种是用来访问整个SOAP消息的:SOAPHandler<SOAPMessageContext>.另一种是用来访问SOAP消息的payload:LogicalHandler<LogicalMessageContext>.
1,服务器端是通过注解@HandlerChain(file="handlersdef.xml")在porttype对应的类上来指定handler的.
handlersdef.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-name>WSLogicalHandler</handler-name>
<handler-class>com.cxfws.test.WSLogicalHandler</handler-class>
</handler>
</handler-chain>
<handler-chain>
<handler>
<handler-name>WSSOAPHandler</handler-name>
<handler-class>com.cxfws.test.WSSOAPHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
2,客户端需要通过service指定HandlerResolver,HandlerResolver里需要将用到的handler返回给service.
service.setHandlerResolver(new RequestOrderHandlerResolver());
例子:
handler:
public class PersistMessageHandler implements SOAPHandler<SOAPMessageContext> {
public static final String PERSISTENCE_DIR_PROP = "persistent.directory";
public Set<QName> getHeaders() {
System.out.println("Entered PersistMessageHandler.getHeaders");
QName serviceQName = new QName("http://test.cxf.bt.com/", "WSCXFProviderService");
QName portQName = new QName("http://test.cxf.bt.com/", "WSCXFProviderPort");
Set<QName> set = new HashSet<QName>();
set.add(serviceQName);
set.add(portQName);
return set;
}
public boolean handleMessage(SOAPMessageContext ctxt) {
System.out.println("Entered PersistMessageHandler.handleMessage");
// return if inbound message
if (!((Boolean) ctxt.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue()) {
return true;
}
SOAPMessage msg = ctxt.getMessage();
String persistenceDir = (String)ctxt.get(PERSISTENCE_DIR_PROP);
try {
msg.writeTo(System.out);
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
public boolean handleFault(SOAPMessageContext ctxt) {
return false;
}
public void close(MessageContext ctxt) {
}
}
public class WSHandler implements LogicalHandler<LogicalMessageContext> {
public void close(MessageContext arg0) {
// TODO Auto-generated method stub
}
public boolean handleFault(LogicalMessageContext arg0) {
// TODO Auto-generated method stub
return false;
}
public boolean handleMessage(LogicalMessageContext arg0) {
System.out.println("WSHandler: handleMessage");
//arg0.getMessage().getPayload();
return true;
}
}
HandlerResolver:
public class RequestOrderHandlerResolver implements HandlerResolver {
public List<Handler> getHandlerChain(PortInfo arg) {
List<Handler> handlerChain = new ArrayList<Handler>();
handlerChain.add(new PersistMessageHandler());
handlerChain.add(new WSHandler());
return handlerChain;
}
}
在调用Web service的时候,将HandlerResolver指定给service:
URL wsdlURL = new URL("file:///D:/JAVAWorkspace/Repository/prjCXFWS/src/wsdl/prjCXFWS.wsdl");
QName serviceQName = new QName("http://test.cxfws.com/", "SimpleServiceService");
QName portQName = new QName("http://test.cxfws.com/", "SimpleServicePort");
Service service = Service.create(wsdlURL, serviceQName);
//set handler
service.setHandlerResolver(new RequestOrderHandlerResolver());
SimpleService port = (SimpleService) service.getPort(portQName, SimpleService.class);