整合XFire與Spring, 釋出 Webservice 以及客戶端的訪問方式
阿新 • • 發佈:2018-12-11
- 首先第一步當然是先下載好服務端的依賴了; 服務端依賴包
- 新建Web工程,為了後續的客戶端的測試,還需加入commons- httpclient.jar包到WEB-INF/lib下哦;
- 在web.xml中配置 XFireSpringServlet,將Spring容器中定義的Web Service在某個URI下發布:
-
<xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>XFireService</display-name> <!-- begin Spring配置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml,/WEB-INF/xfire-servlet.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <listener> <listener-class> org.springframework.web.util.IntrospectorCleanupListener </listener-class> </listener> <!-- end Spring配置 --> <!-- begin XFire 配置 --> <servlet> <servlet-name>xfire</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>xfire</servlet-name> <url-pattern>*.ws</url-pattern> </servlet-mapping> <servlet> <!-- 配合Spring容器中XFire一起工作的Servlet--> <servlet-name>xfireServlet</servlet-name> <servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>xfireServlet</servlet-name> <!-- 在這個URI下開放Web Service服務 --> <url-pattern>/service/*</url-pattern> </servlet-mapping> <!-- end XFire 配置 --> </web-app>
- 在WEB-INF下建立兩個配置Spring配置檔案,一個為applicationContext.xml,該檔案用來定義本工程的bean,一個為xfire-servlet.xml,用來配置XFire的相關bean;
- 那麼,現在來建介面HelloWorld、實現類HelloWorldImpl:
-
package webservice; public interface HelloWorld { String sayHelloWorld(String name); }
package webservice; public class HelloWorldImpl implements HelloWorld { public String sayHelloWorld(String name) { String helloWorld = "hello," + name; return helloWorld; } }
- 在applicationContext.xml檔案中配置對應的bean:HelloWorldBean
-
<beans> <bean id="HelloWorldBean" class="webservice.HelloWorldImpl"/> </beans>
- 在xfire-servlet.xml檔案中匯出器的設定:
<beans> <!-- 引入XFire預配置資訊 --> <import resource="classpath:org/codehaus/xfire/spring/xfire.xml" /> <!—定義訪問的url--> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="urlMap"> <map> <entry key="/HelloWorldService.ws"> <ref bean="HelloWorldService" /> </entry> </map> </property> </bean> <!-- 使用XFire匯出器 --> <bean id="baseWebService" class="org.codehaus.xfire.spring.remoting.XFireExporter" lazy-init="false" abstract="true"> <!-- 引用xfire.xml中定義的工廠 --> <property name="serviceFactory" ref="xfire.serviceFactory" /> <!-- 引用xfire.xml中的xfire例項 --> <property name="xfire" ref="xfire" /> </bean> <bean id="HelloWorldService" parent="baseWebService"> <!-- 業務服務bean --> <property name="serviceBean" ref="HelloWorldBean" /> <!-- 業務服務bean的窄介面類 --> <property name="serviceClass" value="webservice.HelloWorld" /> </bean> </beans>
以上,簡單的Web Service已經編寫ok,瀏覽器輸入:http://localhost:8080/webservice_helloworld/HelloWorldService.ws?wsdl。可以看到HelloWorldService對應的WSDL資訊,閱讀這個WSDL文件,我們可以知道HelloWorld的sayHelloWorld方法已經被成功地釋出為Web Service了。
那麼接下來,就是客戶端的訪問了。
有幾種訪問方式:
- 獲得WSDL檔案HelloWorldService.wsdl,將其放在src目錄下面,接著我們通過程式訪問該WSDL檔案,並呼叫需測試的方法;
-
import org.codehaus.xfire.client.Client; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import webservice.HelloWorld; public class WebServiceClientTest { HelloWorld helloWorld = null; publicstaticvoid main(String[] args) throws Exception { WebServiceClientTest test = new WebServiceClientTest(); test.testClient(); } publicvoid testClient() throws Exception { String wsdl = "HelloWorldService.wsdl"; //對應的WSDL檔案 Resource resource = new ClassPathResource(wsdl); Client client = new Client(resource.getInputStream(), null); //根據WSDL建立客戶例項 Object[] objArray = new Object[1]; objArray[0] = "美食"; Object[] results = client.invoke("sayHelloWorld", objArray); System.out.println("result: " + results[0]); } }
- 根據服務地址建立客戶端呼叫程式。在src目錄下建立客戶端呼叫的Spring配置檔案client.xml;
-
<beans> <bean id="testWebService" class="org.codehaus.xfire.spring.remoting.XFireClientFactoryBean"> <property name="serviceClass"> <value>webservice.HelloWorld</value> </property> <property name="wsdlDocumentUrl"> <value>http://localhost:8080/webservice_helloworld/HelloWorldService.ws?wsdl</value> </property> </bean> </beans>
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import webservice.HelloWorld; publi cclass WebServiceClientTest { HelloWorld helloWorld = null; publicstaticvoid main(String[] args) { WebServiceClientTest test = new WebServiceClientTest(); test.testClient(); } publicvoid testClient() { ApplicationContext ctx = new ClassPathXmlApplicationContext( "client.xml"); helloWorld = (HelloWorld) ctx.getBean("testWebService"); System.out.println(helloWorld.sayHelloWorld("美食")); } }
- 通過HttpClient訪問(推薦)
-
public void test() throws IOException, Exception{ Client client = new Client(new URL("http://localhost:8080/Webservice/wsdl/queryService.ws?wsdl")); Object[] objArray = new Object[7]; Map<String, Object> params = new HashMap<>(); params.put("Condition", ""); params.put("RequiredItems", "xm"); String json = JSONObject.toJSONString(params); // System.out.println("json = " + json); objArray[0] = json; Object[] results = client.invoke("Query", objArray); System.out.println(" result: " + results[0]); }
使用小結:
-
service裡面的方法過載的話會導致wsdl檔案裡面的介面名稱自動更改為‘名稱’+數字;
-
service的引數不能包含字元陣列,不然會空指標;
-
儘可能的只發布少的服務介面,將要呼叫的介面名稱傳給這個公共介面,然後就可以統一管理在一個公共介面了,以後增加介面也不需要每次都修改xml的配置。