Provider and Dispatch services用用开发WebService进行处理Raw XML Message, 并且不通过方法调用。而
基于SEI的实现,消息是被使用JAXB进行转换成的XML。当Web Service Client与 Web Service Provider之间
需要传输大量的XML Message时比较适合。
JAX-WS提供了javax.xml.ws.Provider接口,该接口提供了功能用于创建处理XML Message的Service Provider;
他从Dispatcher Client中获取XML格式的消息请求,处理,生成响应。Provider实现将在Server上Publish一个
ServiceEndpoint.
JAX-WS提供了javax.xml.ws.Dispatch接口用于处理XML消息并且发送XML格式的响应给Service Provider.
完整代码参考http://springsfeng.iteye.com/blog/1634753附件。
1. Privider Service实现
import javax.xml.namespace.QName; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPMessage; import javax.xml.transform.dom.DOMSource; import javax.xml.ws.Provider; import javax.xml.ws.Service; import javax.xml.ws.ServiceMode; import javax.xml.ws.WebServiceProvider; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @WebServiceProvider() @ServiceMode(value = Service.Mode.MESSAGE) public class OrderProcessDOMProvider implements Provider<DOMSource> { public OrderProcessDOMProvider() { } public DOMSource invoke(DOMSource request) { DOMSource response = new DOMSource(); try { MessageFactory factory = MessageFactory.newInstance(); SOAPMessage soapReq = factory.createMessage(); soapReq.getSOAPPart().setContent(request); System.out.println("Incoming Client Request as a DOMSource data in MESSAGE Mode"); soapReq.writeTo(System.out); System.out.println("\n"); Node processOrderNode = soapReq.getSOAPBody().getFirstChild(); // Get arg0 - order element Node order = processOrderNode.getChildNodes().item(0); // Get list of child nodes associated with order and print it NodeList list = order.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { // Get the child nodes and value as per the order xml request. System.out.println(list.item(i).getNodeName() + "=" + list.item(i).getFirstChild().getNodeValue()); } SOAPMessage orderResponse = factory.createMessage(); QName processOrderQName = new QName("http://server.webservice.sample.pcdp.org/","processOrder"); QName responseQName = new QName("http://server.webservice.sample.pcdp.org/", "return"); // create the element - // <http://order.demo/:processOrder></http://order.demo/:processOrder> SOAPElement processOrderResponse = orderResponse.getSOAPBody().addChildElement(processOrderQName); // create the element inside processOrder - // <http://order.demo/:return>ORD1234</http://order.demo/:return> processOrderResponse.addChildElement(responseQName).addTextNode("ORD1234"); response.setNode(orderResponse.getSOAPPart()); } catch (Exception ex) { ex.printStackTrace(); } return response; } }
发布服务:
import javax.xml.ws.Endpoint; public class Server { protected Server() throws Exception { System.out.println("Starting Server"); Object implementor = new OrderProcessDOMProvider(); String address = "http://localhost:8080/OrderProcessDOMProvider"; Endpoint.publish(address, implementor); } public static void main(String args[]) throws Exception { new Server(); System.out.println("Server ready..."); Thread.sleep(50 * 60 * 1000); System.out.println("Server exiting"); System.exit(0); } }
2. Dispatcher Service实现
import java.net.URL; import javax.xml.namespace.QName; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPMessage; import javax.xml.transform.dom.DOMSource; import javax.xml.ws.Dispatch; import javax.xml.ws.Service; import javax.xml.ws.Service.Mode; public final class DispatcherClient { public static final String WSDLFile = "http://localhost:8080/OrderProcessDOMProvider?wsdl"; public DispatcherClient() { } public static void main(String args[]) throws Exception { URL wsdlURL = new URL(WSDLFile); MessageFactory factory = MessageFactory.newInstance(); QName domProvider = new QName("http://provider.sample.pcdp.org/","OrderProcessDOMProviderService"); QName portName = new QName("http://provider.sample.pcdp.org/","OrderProcessDOMProviderPort"); Service service = Service.create(wsdlURL, domProvider); SOAPMessage soapRequest = factory.createMessage(); QName processOrderQName = new QName("http://provider.sample.pcdp.org/","processOrder"); // create the element - <http://order.demo/:processOrder></http://order.demo/:processOrder> SOAPElement processOrderResponse = soapRequest.getSOAPBody().addChildElement(processOrderQName); SOAPElement order = processOrderResponse.addChildElement("arg0"); order.addChildElement("customerID").addTextNode("Naveen"); order.addChildElement("itemID").addTextNode("I001"); order.addChildElement("price").addTextNode("200.00"); order.addChildElement("qty").addTextNode("200"); DOMSource domRequestMsg = new DOMSource(soapRequest.getSOAPPart()); Dispatch<DOMSource> domMsg = service.createDispatch(portName,DOMSource.class, Mode.MESSAGE); DOMSource domResponseMsg = domMsg.invoke(domRequestMsg); SOAPMessage soapReq = factory.createMessage(); soapReq.getSOAPPart().setContent(domRequestMsg); System.out.println("Client Request as a DOMSource data in MESSAGE Mode"); soapReq.writeTo(System.out); System.out.println("\n"); System.out.println("Response from server: " + domResponseMsg.getNode().getLastChild().getTextContent()); } }
Client端输出:
Client Request as a DOMSource data in MESSAGE Mode <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><processOrder xmlns="http://provider.sample.pcdp.org/"><arg0><customerID>Naveen</customerID><itemID>I001</itemID><price>200.00</price><qty>200</qty></arg0></processOrder></SOAP-ENV:Body></SOAP-ENV:Envelope> Response from server: ORD1234
Server端输出:
Incoming Client Request as a DOMSource data in MESSAGE Mode <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><processOrder xmlns="http://provider.sample.pcdp.org/"><arg0><customerID>Naveen</customerID><itemID>I001</itemID><price>200.00</price><qty>200</qty></arg0></processOrder></SOAP-ENV:Body></SOAP-ENV:Envelope> customerID=Naveen itemID=I001 price=200.00 qty=200
3. Provider and Dispatch概念理解
(1) Message Mode
Provider and Dispatche有两种消息类型:Provider and Dispatche,Payload. 区别在于两者之间的内容上。
Message mode由真实的数据和控制信息(Header)组成,而Payload Mode只仅仅有真实的数据组成。
例如:
@WebServiceProvider() @ServiceMode(value = Service.Mode.MESSAGE) public class OrderProcessDOMProvider implements Provider<DOMSource> { . . .
@WebServiceProvider() @ServiceMode(value = Service.Mode.PAYLOAD) public class OrderProcessDOMProvider implements Provider<DOMSource> { . . .
(2) The type of Mesage Object
Provider and Dispatch实现操作时的输入输出有以下几种类型:
javax.xml.transform.Source, javax.xml.soap.SOAPMessage, javax.activation.DataSource.
其中javax.activation.DataSource分为:
DOMSource, SAXSource, StreamSource.