WebService客戶端調用的本質就是將SAOP格式的XML通過通信協議發送到WebService的服務器端,然后接收服務器端返回的XML.
本文簡單介紹一下如何通過Spring提供的WebServiceTemplate訪問Webservice,WebServiceTemplate與調用webservice的客戶端已及webservice服務器端示意圖如下(圖片來源於Spring in Action):
這里以SOAP over HTTP為例,開發步驟如下:
1,在Spring的配置文件中配置WebServiceTemplate,最簡單的配置如下:
- <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
- <property name="defaultUri" value="http://localhost:8080/prjCXFWS/services/SimpleServicePort"/>
- </bean>
*這種配置省略了MessageFactory和messageSender的配置,Spring默認會使用SaajSoapMessageFactory和HttpUrlConnectionMessageSender.等同於下面的配置
- <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
- <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
- <constructor-arg ref="messageFactory"/>
- <property name="messageSender">
- <bean class="org.springframework.ws.transport.http.HttpUrlConnectionMessageSender"/>
- </property>
- <property name="defaultUri" value="http://localhost:8080/prjCXFWS/services/SimpleServicePort" />
- </bean>
還可以使用CommonsHttpMessageSender作為messageSender,它提供了設置timeout,用戶名,密碼等選項的功能.(需要使用commons-httpclient.jar和commons-codec.jar)
MessageFactory還可以使用AxiomSoapMessageFactory和DomPoxMessageFactory.
- <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
- <property name="messageSender">
- <bean class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
- <property name="readTimeout" value="0" />
- </bean>
- </property>
- <property name="defaultUri" value="http://localhost:8080/prjCXFWS/services/SimpleServicePort" />
- </bean>
2,Java調用代碼:傳輸的是SOAP XML.
- private static final String MESSAGE =
- "<queryPeopleByID xmlns=\"http://test.cxfws.com\">1231ss</queryPeopleByID> ";
- public static void test() {
- ApplicationContext ac = new ClassPathXmlApplicationContext("conf/wsAppcontext.xml");
- WebServiceTemplate simpleService = (WebServiceTemplate) ac.getBean("webServiceTemplate");
- StreamSource source = new StreamSource(new StringReader(MESSAGE));
- StreamResult result = new StreamResult(System.out);
- simpleService.sendSourceAndReceiveToResult(source, result);
- }
*MESSAGE為需要發送到webservice服務器端的XML payload內容,SOAP body之內的XML內容.
Spring調用Webservice的另一種方法是通過Spring提供的JaxWsPortProxyFactoryBean,示意圖如下(圖片來源於Spring in Action):
Spring的配置如下:
- <bean id="simpleService"
- class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
- <property name="serviceInterface"
- value="com.cxfclient.test.SimpleService" />
- <property name="wsdlDocumentUrl"
- value="http://localhost:8080/prjCXFWS/services/SimpleServicePort?WSDL" />
- <property name="namespaceUri" value="http://test.cxfws.com/" />
- <property name="serviceName" value="SimpleServiceService" />
- <property name="portName" value="SimpleServicePort" />
- </bean>
**這種方式需要用工具通過Webservice 的wsdl文件生成客戶端需要的一些Java類,如service的interface,參數類等等(如下面代碼中的SimpleService,People類).
Java調用代碼如下
- ApplicationContext ac = new ClassPathXmlApplicationContext("conf/wsAppcontext.xml");
- SimpleService simpleService = (SimpleService) ac.getBean("simpleService");
- People people = simpleService.queryPeopleByID("test");
- System.out.println(people.getAge() + people.getName() + people.getPid());
關於更多客戶端如何調用webservice,參照http://blog.csdn.net/kkdelta/article/details/3987591
對於服務器端,其本質也是接收符合SOAP規范的XML消息,解析XML,返回符合SOAP規范的XML,這里用一個servlet模擬webservice,代碼如下:
- public class WSSimulator extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
- System.out.println("doGet");
- BufferedReader in = new BufferedReader(new InputStreamReader( request.getInputStream()));
- String str;
- while ((str = in.readLine()) != null) {
- System.out.println(str); ##1
- }
- in.close();
- String soapHeader = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">"
- +"<SOAP-ENV:Header/><SOAP-ENV:Body>";
- String soapPayload = "<xxx>yyy</xxx>";
- String soapTail = "</SOAP-ENV:Body></SOAP-ENV:Envelope>";
- response.getWriter().write(soapHeader + soapPayload + soapTail); ##2
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
- System.out.println("doPost");
- doGet(request, response);
- }
- }
通過WebServiceTemplate將消息發送到這個servlet監聽的url,可以更深理解Webservice的本質.
##1 str就是從客戶端傳輸到服務器端的XML.##2將SOAP消息返回給客戶端.