真正的輕量級WebService框架——使用JAX-WS(JWS)發佈WebService

真正的輕量級WebService框架——使用JAX-WS(JWS)發佈WebService

  WebService從來都很受重視,特別是Java陣營,WebService框架和技術層出不窮。知名的XFile(新的如CXF)、Axis一、Axis2等。html

  而Sun公司也不甘落後,從早期的JAX-RPC到如今成熟的、支持RPC調用與消息傳遞的JAX-WS都通過了市場的考驗,十分紅熟,並且使用JAX-WS開發WebService的收益是很大的,它是輕量級的。java

  

  咱們使用JAX-WS開發WebService只須要很簡單的幾個步驟:寫接口和實現=>發佈=>生成客戶端(測試或使用)。web

  而在開發階段咱們也不須要導入外部jar包,由於這些api都是現成的。首先是接口的編寫(接口中只須要把類註明爲@WebService,把要暴露給客戶端的方法註明爲@WebMethod便可,其他如@WebResult、@WebParam等都不是必要的,而客戶端和服務端的通訊用RPC和Message-Oriented兩種,區別和配置之後再說):sql

  

複製代碼
 1 package service;
 2 
 3 import java.util.Date;
 4 
 5 import javax.jws.WebMethod;
 6 import javax.jws.WebParam;
 7 import javax.jws.WebResult;
 8 import javax.jws.WebService;
 9 import javax.jws.soap.SOAPBinding;
10 
11 /**
12  * 做爲測試的WebService接口
13  * 
14  * @author Johness
15  * 
16  */
17 @WebService
18 @SOAPBinding(style = SOAPBinding.Style.RPC)
19 public interface SayHiService {
20 
21     /**
22      * 執行測試的WebService方法
23      */
24     @WebMethod
25     void SayHiDefault();
26 
27     /**
28      * 執行測試的WebService方法(有參)
29      * 
30      * @param name
31      */
32     @WebMethod
33     void SayHi(@WebParam(name = "name") String name);
34 
35     /**
36      * 執行測試的WebService方法(用於時間校驗)
37      * 
38      * @param clentTime 客戶端時間
39      * @return 0表示時間校驗失敗 1表示校驗成功
40      */
41     @WebMethod
42     @WebResult(name = "valid")
43     int CheckTime(@WebParam(name = "clientTime") Date clientTime);
44 }
複製代碼

  而後是實現類(註解@WebService及其endpointInterface屬性是必要的):api

  

複製代碼
 1 package service.imp;
 2 
 3 import java.text.SimpleDateFormat;
 4 import java.util.Date;
 5 
 6 import javax.jws.WebService;
 7 import javax.jws.soap.SOAPBinding;
 8 
 9 import service.SayHiService;
10 
11 /**
12  * 做爲測試的WebService實現類
13  * 
14  * @author Johness
15  * 
16  */
17 @WebService(endpointInterface = "service.SayHiService")
18 @SOAPBinding(style = SOAPBinding.Style.RPC)
19 public class SayHiServiceImp implements SayHiService {
20 
21     @Override
22     public void SayHiDefault() {
23         System.out.println("Hi, Johness!");
24     }
25 
26     @Override
27     public void SayHi(String name) {
28         System.out.println("Hi, " + name + "!");
29     }
30 
31     @Override
32     public int CheckTime(Date clientTime) {
33         // 精確到秒
34         String dateServer = new java.sql.Date(System.currentTimeMillis())
35                 .toString()
36                 + " "
37                 + new java.sql.Time(System.currentTimeMillis());
38         String dateClient = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
39                 .format(clientTime);
40         return dateServer.equals(dateClient) ? 1 : 0;
41     }
42 
43 }
複製代碼

  而後是發佈(通常有兩種方式):瀏覽器

  方式一(此方式只能做爲調試,有如下bug:服務器

    jdk1.6u17?如下編譯器不支持以Endpoint.publish方式發佈document方式的soap,必須在service接口和實現類添加「@SOAPBinding(style = SOAPBinding.Style.RPC)」註解;app

    訪問受限,彷佛只能本機訪問(應該會綁定到publish的URL上,以下使用localhost的話就只能本機訪問)……):框架

複製代碼
 1 package mian;
 2 
 3 import javax.xml.ws.Endpoint;
 4 
 5 import service.imp.SayHiServiceImp;
 6 
 7 public class Main {
 8 
 9     /**
10      * 發佈WebService
11      * 簡單
12      */
13     public static void main(String[] args) {
14         Endpoint.publish("http://localhost:8080/testjws/service/sayHi", new SayHiServiceImp());
15     }
16 
17 }
複製代碼

  方式二(基於web服務器Servlet方式):jsp

  以Tomcat爲例,首先編寫sun-jaxws.xml文件並放到WEB-INF下:

  

複製代碼
1 <?xml version="1.0" encoding="UTF-8"?>
2 <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
3     version="2.0">
4     <endpoint name="SayHiService"
5         implementation="service.imp.SayHiServiceImpl"
6         url-pattern="/service/sayHi" />
7 </endpoints>
複製代碼

  而後改動web.xml,添加listener和servlet(url-pattern要相同哦):

複製代碼
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
 3     
 4     <listener>  
 5         <listener-class>
 6             com.sun.xml.ws.transport.http.servlet.WSServletContextListener  
 7         </listener-class>
 8     </listener>
 9     <servlet>
10         <servlet-name>SayHiService</servlet-name>  
11         <servlet-class>
12             com.sun.xml.ws.transport.http.servlet.WSServlet  
13         </servlet-class>
14     </servlet>  
15     <servlet-mapping>  
16         <servlet-name>SayHiService</servlet-name>  
17         <url-pattern>/service/sayHi</url-pattern>  
18     </servlet-mapping>
19     
20     <welcome-file-list>
21         <welcome-file>index.html</welcome-file>
22         <welcome-file>index.htm</welcome-file>
23         <welcome-file>index.jsp</welcome-file>
24     </welcome-file-list>
25 </web-app>
複製代碼

  最後部署到Tomcat裏,值得一提的是您可能須要添加如下jar包(由於Tomcat沒有):

            

  啓動Tomcat。

  

  服務端工做就完成了,注意兩個事情。

  注意:項目須要使用UTF-8編碼(至少sun-jaxws.xml必須是UTF-8格式的);

    對於MyEclipse的內置Tomcat,可能會出現不須要手動添加上述jar包,但獨立部署時應該添加,由於它們使用的class-path不同;

    多個不一樣路徑的接口也要使用同一個WSServlet;

    最好加上@SOAPBinding(style = SOAPBinding.Style.RPC)註解。

  部署好了以後打開瀏覽器輸入網址:http://localhost:8080/testjws/service/sayHi?wsdl。能夠看到東西就證實發布成功了。

  附上項目樹狀圖:

  

  最後是客戶端使用,因爲WebService是平臺和語言無關的基於xml的,因此咱們徹底可使用不一樣語言來編寫或生成客戶端。

  通常有三種方式來使用(對於Java語言而言):

    一,使用jdk自帶工具wsimport生成客戶端:

  

  jdk自帶的wsimport工具生成,上圖我是把客戶端文件生成到了桌面src文件中(-d),並保留了源文件(-keep),指定了包名(-p)。

 

  而後咱們就可使用生成的文件來調用服務器暴露的方法了:

            

    值得一提的是你生成使用的jdk和你客戶端的jre須要配套!

  從上面的目錄結構咱們能夠發現:服務端的每一個webmethod都被單獨解析成爲了一個類(若是使用了實體,實體也會被解析到客戶端,而且是源碼,因此建議使用實體時慎重)。

  

  (上面的圖是舊圖,只是爲了表示一下jaxws是爲每一個webmethod生成類的狀況)

  而咱們的service則被生成了一個代理類來調用服務,接下來咱們看看使用狀況:

複製代碼
 1 package test;
 2 
 3 import java.util.Date;
 4 import java.util.GregorianCalendar;
 5 
 6 import javax.xml.datatype.DatatypeConfigurationException;
 7 import javax.xml.datatype.DatatypeFactory;
 8 import javax.xml.datatype.XMLGregorianCalendar;
 9 
10 import testjws.client.SayHiService;
11 import testjws.client.SayHiServiceImpService;
12 
13 public class Main {
14 
15     public static void main(String[] args) throws DatatypeConfigurationException {
16         // 獲取service
17         SayHiService service = new SayHiServiceImpService().getSayHiServiceImpPort();
18         
19         // sayhi
20         service.sayHiDefault();
21         service.sayHi("Ahe");
22         
23         // checktime
24         // 這裏主要說一下時間日期的xml傳遞,方法還略顯複雜
25         GregorianCalendar calender = new GregorianCalendar();
26         calender.setTime(new Date(System.currentTimeMillis()));
27         XMLGregorianCalendar xmldate = DatatypeFactory.newInstance().newXMLGregorianCalendar(calender);
28         System.out.println(service.checkTime(xmldate));
29 
30     }
31 
32 }
複製代碼

  看看服務器的輸出,咱們是否調用成功:

  

    

    成功了!

    對於校驗時間的方法客戶端也收到反饋了:

        

    二,使用諸如MyEclipse(Eclipse for Jave EE也能夠)建立一個Web Service Client的項目

        

    而後填入wsdl地址便可,後續步驟我就不貼出了。

    三,本身寫代碼-_-,其實這個方法不得不說是最好的。

 

 歡迎您移步咱們的交流羣,無聊的時候你們一塊兒打發時間:Programmer Union

 或者經過QQ與我聯繫:點擊這裏給我發消息

 (最後編輯時間2014-03-08 00:23:18)

 

認真你就輸了,一直認真你就贏了!
相關文章
相關標籤/搜索