1. 程式人生 > >整合XFire與Spring, 釋出 Webservice 以及客戶端的訪問方式

整合XFire與Spring, 釋出 Webservice 以及客戶端的訪問方式

  1. 首先第一步當然是先下載好服務端的依賴了; 服務端依賴包
  2. 新建Web工程,為了後續的客戶端的測試,還需加入commons- httpclient.jar包到WEB-INF/lib下哦;
  3. 在web.xml中配置 XFireSpringServlet,將Spring容器中定義的Web Service在某個URI下發布:
  4. <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>
  5. 在WEB-INF下建立兩個配置Spring配置檔案,一個為applicationContext.xml,該檔案用來定義本工程的bean,一個為xfire-servlet.xml,用來配置XFire的相關bean;
  6. 那麼,現在來建介面HelloWorld、實現類HelloWorldImpl
  7. 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;
        }
    }
  8. 在applicationContext.xml檔案中配置對應的bean:HelloWorldBean
  9. <beans>
        <bean id="HelloWorldBean" class="webservice.HelloWorldImpl"/>
    </beans>
  10. 在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的配置。