通过定义一个配置文件来管理这些处理程序是一个比较好的做法,但是还可以采用其他方法。用配置文件的方式可以保持客户端和服务端代码相对清洁。这些SOAP处理程序一般不是应用程序逻辑的主体内容,因此,通常较好的做法就是通过像handle-chain.xml这样的元数据文件来管理它们。虽然如此,通过编码的方式来管理这些SOAP处理程序也非难事。
我们使用的例子还是HelloWord示例,服务端完全一样,客户端只有服务调用客户端程序HelloWordClient1.java需要修改,另外还要增加两个类:一个是SOAP消息处理链类,一个是额外增加的一个SOAP处理程序。
TestHandler.java:
package fibC;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class TestHandler implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
System.out.println("TestHandler-->handleMessage");
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
System.out.println("TestHandler-->handleFault!!");
return true;
}
@Override
public void close(MessageContext context) {
}
@Override
public Set<QName> getHeaders() {
return null;
}
}
ClientHandlerResolver.java:
package hw1;
import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
import fibC.TestHandler;
import fibC.UUIDHandler;
public class ClientHandlerResolver implements HandlerResolver {
@SuppressWarnings("rawtypes")
@Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> hchain = new ArrayList<Handler>();
hchain.add(new UUIDHandler());
hchain.add(new TestHandler());
return hchain;
}
}
HelloWordClient1.java:
package hw1;
import javax.xml.ws.Holder;
public class HelloWordClient1 {
public static void main(String[] args) {
String name = "老师";
Holder<String> wh = new Holder<String>();
wh.value = "你好";
Holder<String> hf = new Holder<String>();
HelloWordImplService service = new HelloWordImplService();
//设置SOAP消息处理程序链
service.setHandlerResolver(new ClientHandlerResolver());
HelloWord port = service.getPort(HelloWord.class);
port.sayHello(name, wh, hf);
System.out.println(hf.value + "," + wh.value);
}
}
ClientHandlerResolver类实现了HandlerResolver接口,接口HandlerResolver只定义了一个getHandlerChain方法。运行时服务程序通过调用这个方法获取一个SOAP消息处理程序链。在HelloWordClient1中,调用服务对象的setHandlerResolver方法设置一个ClientHandlerResolver对象实例。这样,在SOAP消息处理程序配置中,配置文件handle-chain.xml就不再起作用了,而是由代码来接管。在这个例子中,我们又增加了TestHandler处理程序,用来直观地演示处理程序的调用顺序。在处理程序链中,UUIDHandler处在第一位,因此也最先被执行。