用JAX-WS+Spring實現簡單soap規範的webservice

 

轉載請註明出處:http://www.cnblogs.com/Starshot/p/7050084.htmlhtml

 

Soap即簡單對象訪問協議,也可理解爲一種用於程序之間通信的規範,它主要基於XML和http,也正由於基於XML和http,因此這個協議具備很強的通用性,可以很好地實現不一樣語言平臺之間的交流通信。缺點是相對比較重量級。java

Java的Soap框架有不少,例如xfire,CXF。說到soap不得不提一下rest,由於這些概念很容易弄混。web

rest是一種結構風格,而實現了rest風格的程序設計就叫作restful。它提倡更加輕量級、無狀態、自描述,更充分地利用http自己的特性,例如get,post,put,delete,以得到更加高效的性能,使交互更加簡潔易懂。例如要獲取圖書集合中的某本書AAA,能夠直接經過uri:/books/AAA來表示。spring

而soap則都是經過post來請求的,沒有充分利用http的其它方法,僅將http做爲傳輸協議來使用,而具體須要獲取的資源信息則包含在post的xml報文中。express

須要注意的是,rest是一種風格,它不限制於某個程序某個框架。例如CXF框架,它既能夠實現rest風格的webService,也能夠實現SOAP規範的webService。例如在我另外一篇博文中的CXF簡單例子(http://www.cnblogs.com/Starshot/p/6889751.html),就能夠看作是rest風格的webService。api

 

如今就先以JAX-WS這個輕量級的框架 (後面再和Spring合在一塊兒) 來實現一個soap規範的超簡單的webService。瀏覽器

首先建一個WebService的web工程,這個做爲服務的提供方。而後建一個HelloService類,以下所示:tomcat

而後類的代碼以下:restful

package com.webService;

import javax.jws.WebService;
import javax.xml.ws.Endpoint;

@WebService
public class HelloService {

    public String sayIt(String str){
        return "say it:"+str;
    }
    
    public static void main(String[] args) {
        Endpoint.publish("http://localhost:9009/hello/HelloService", new HelloService());
        System.out.println("publish done!");
    }
}

是否是很簡單,是否是很驚喜,而後直接執行,出現publish done!而後打開瀏覽器,輸入http://localhost:9009/hello/HelloService?wsdl,出現wsdl文件信息的話,就算是成功了。app

接下來再建一個客戶端工程,以下所示:

這個時候須要生成wsdl的客戶端,對這工程點擊右鍵,而後新建WebService client:

點下一步,輸入剛剛在瀏覽器輸入的地址:

而後再點擊下一步設置了代碼的路徑以後按肯定就能夠了,成功以後以下圖所示:

其中com.webService裏面的就是客戶端程序了。而後再如上圖新建一個測試類test1,內容以下:

package com.test;

import java.rmi.RemoteException;

import javax.xml.rpc.ServiceException;

import com.webService.HelloService;
import com.webService.HelloServiceProxy;
import com.webService.HelloServiceServiceLocator;

public class test1 {

    public static void main(String[] args) throws ServiceException, RemoteException {
        HelloService hs=new HelloServiceProxy();
         System.out.println(hs.sayIt("Yohoo!!"));
    }
}

執行,該程序,控制檯輸出:Yohoo!!,這就表示成功了。

經過查看客戶端代碼能夠知道,HelloServiceProxy,HelloServiceServiceLocator,HelloServicePortBindingStub三個類其實均可以用來調用服務。而全部類最終都是經過HelloServicePortBindingStub類中的sayIt方法來實現的,HelloServiceProxy和HelloServiceServiceLocator實際上是對HelloServicePortBindingStub進行了進一步的加工,這也是代理模式的一種體現。

再而後,上面這種方式發佈服務雖然簡單,但在實際應用中確定不是這樣子發佈服務的,實際確定是要發佈在web中的。JAX-WS和Spring結合起來發佈一個WebService服務:

 首先在原來的WebServiec工程加入如下jar包:

commons-logging-1.0.4.jar
gmbal-api-only.jar
ha-api.jar
jaxb-impl.jar
jaxws-api.jar
jaxws-rt.jar
jaxws-spring-1.8.jar
management-api.jar
policy.jar
spring-beans-3.2.14.RELEASE.jar
spring-context-3.2.14.RELEASE.jar
spring-core-3.2.14.RELEASE.jar
spring-expression-3.2.14.RELEASE.jar
spring-web-3.2.14.RELEASE.jar
stax-ex.jar
streambuffer.jar
xbean-spring-3.0.jar

由於涉及jar包比較多,若是有須要的話,能夠留下郵箱,我發過去。

而後建一個SpeakingService類,Component註解是表示這個類將被spring容器管理,以下所示,

package com.webService;

import javax.jws.WebService;

import org.springframework.stereotype.Component;



@Component
@WebService
public class SpeakingService  {
    
    public String speak(String content) {
        return "speaking:"+content;
    }

}

而後在WEB-INF下建web.xml文件,內容以下:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

   <servlet>
  <servlet-name>jwsService</servlet-name>
  <servlet-class>
   com.sun.xml.ws.transport.http.servlet.WSSpringServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>jwsService</servlet-name>
  <url-pattern>/SpeakingService</url-pattern>
 </servlet-mapping>
</web-app>

而後在src路徑下創建applicationContext.xml文件,內容以下:

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ws="http://jax-ws.dev.java.net/spring/core"
 xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://jax-ws.dev.java.net/spring/core
http://jax-ws.dev.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet
http://jax-ws.dev.java.net/spring/servlet.xsd
http://www.springframework.org/schema/context  
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">

  <context:component-scan base-package="*"/> 

 <wss:binding url="/SpeakingService">
  <wss:service>
   <ws:service bean="#speakingService" />
  </wss:service>
 </wss:binding>

</beans> 

這裏有個細節要注意的是<ws:service bean="#speakingService" />這裏的speakingService首字母記得要小寫,雖然原來的類名是大寫開頭,可是默認加載進spring容器以後,bean的id就是一小寫開頭了。

最後就是用tomcat將這個工程啓動就能夠了,訪問的ip和端口以及資源名稱就以tomcat容器的設定爲準了。生成客戶端的方法和剛開始說的同樣。

若是有問題,歡迎指出交流。

轉載請註明出處:http://www.cnblogs.com/Starshot/p/7050084.html

相關文章
相關標籤/搜索