出自:http://www.javaworld.com/javaworld/jw-02-2007/jw-02-handler.html?page=3
客户端以编码的方式配置handler chains
完成handlers的编码仅仅是第一步,为了使他们服务于web service应用,我们就必须把它部署到clent和server运行环境中。
一种典型的情况,如果有多个handlers,他们将被组织成一个chinas。
在JAX-WS中,有两种方式去配置handler chains,编码和metadata的方式。在client仅仅支持编码的方式。
下图是client配置handler chain一个比较详细的流程图:
Web service client程序必须去实现HandlerResolver接口,且要把HandlerResolver实例注册到Service实例中。
在getHandlerChain()方法中,通过PortInfo对象去构造一个handlers chains。下图是一个实例:
public class CardServiceHandlerResolver implements HandlerResolver { public List<Handler> getHandlerChain(PortInfo portInfo) { List<Handler> handlerChain = new ArrayList<Handler>(); ClientAuthenticationSOAPHandler authn = new ClientAuthenticationSOAPHandler(); EnvelopeLoggingSOAPHandler logging = new EnvelopeLoggingSOAPHandler(); ClientPerformanceMonitorLogicalHandler perf = new ClientPerformanceMonitorLogicalHandler(); JAXPPayloadLoggingLogicalHandler payload = new JAXPPayloadLoggingLogicalHandler(); QName serviceName = portInfo.getServiceName(); QName portName = portInfo.getPortName(); String bindingID = portInfo.getBindingID(); if (serviceName.getNamespaceURI().equals( "http://cardservice.handler.jaxws.company.com/service") && serviceName.getLocalPart().equalsIgnoreCase("CardService")) { handlerChain.add(authn); handlerChain.add(logging); } if (portName.getNamespaceURI().equals( "http://cardservice.handler.jaxws.company.com/service") && portName.getLocalPart().equalsIgnoreCase("CardServicePort")) { handlerChain.add(perf); } if (bindingID.equals("http://schemas.xmlsoap.org/wsdl/soap/http")) { handlerChain.add(payload); } if (bindingID .equals("http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/")) { handlerChain.add(payload); } return handlerChain; } }
下面的代码片段出自CreditCardServiceClient.java中,演示基于Dispatch client使用HandlerResolver
Service service = Service.create(wsdlLoc, serviceName); service.setHandlerResolver(ccResolver); if (mode.equals(Service.Mode.PAYLOAD)) { Dispatch<Source> disp = service.createDispatch(portName,Source.class, mode); Map<String, Object> requestCtx = ((BindingProvider) disp).getRequestContext(); requestCtx.put(AuthenticationHandlerConstants.REQUEST_USERID,"yyang"); requestCtx.put(AuthenticationHandlerConstants.REQUEST_PASSWORD,"mypassword"); xmlString = CreditCardUtil.readStringFromFile(requestXMLFile); Source xmlSource = (Source) new StreamSource(new StringReader(xmlString)); Source response = disp.invoke(xmlSource); System.out.println(CreditCardUtil.sourceToXMLString(response)); }
下面的代码片段演示,通过Binding 接口去配置handler chains:
if (mode.equals(Service.Mode.MESSAGE)) { Dispatch<SOAPMessage> disp = service.createDispatch(portName,SOAPMessage.class, mode); Map<String, Object> requestCtx = ((BindingProvider) disp).getRequestContext(); requestCtx.put(AuthenticationHandlerConstants.REQUEST_USERID,"yyang"); requestCtx.put(AuthenticationHandlerConstants.REQUEST_PASSWORD,"mypassword"); Binding cardServiceBinding = ((BindingProvider) disp).getBinding(); ClientAuthenticationSOAPHandler authnHandler = new ClientAuthenticationSOAPHandler(); List<Handler> handlerChain = new ArrayList<Handler>(); handlerChain.add(authnHandler); cardServiceBinding.setHandlerChain(handlerChain); xmlString = CreditCardUtil.readStringFromFile(requestSOAPXMLFile); MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage(); message.getSOAPPart().setContent((Source) new StreamSource(new StringReader(xmlString))); message.saveChanges(); SOAPMessage response = disp.invoke(message); SOAPPart sp = response.getSOAPPart(); Source resp = sp.getContent(); System.out.println(CreditCardUtil.sourceToXMLString(resp)); }