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

來源:互聯網
上載者:User

標籤:

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

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

  

  我們使用JAX-WS開發WebService只需要很簡單的幾個步驟:寫介面和實現=>發布=>產生用戶端(測試或使用)。

  而在開發階段我們也不需要匯入外部jar包,因為這些api都是現成的。首先是介面的編寫(介面中只需要把類註明為@WebService,把 要暴露給用戶端的方法註明為@WebMethod即可,其餘如@WebResult、@WebParam等都不是必要的,而用戶端和服務端的通訊用RPC 和Message-Oriented兩種,區別和配置以後再說):

package service;import java.util.Date;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import javax.jws.soap.SOAPBinding;/** * 作為測試的WebService介面 *  * @author Johness *  */@WebService@SOAPBinding(style = SOAPBinding.Style.RPC)public interface SayHiService {    /**     * 執行測試的WebService方法     */    @WebMethod    void SayHiDefault();    /**     * 執行測試的WebService方法(有參)     *      * @param name     */    @WebMethod    void SayHi(@WebParam(name = "name") String name);    /**     * 執行測試的WebService方法(用於時間校正)     *      * @param clentTime 用戶端時間     * @return 0表示時間校正失敗 1表示校正成功     */    @WebMethod    @WebResult(name = "valid")    int CheckTime(@WebParam(name = "clientTime") Date clientTime);}

然後是實作類別(註解@WebService及其endpointInterface屬性是必要的):

package service.imp;import java.text.SimpleDateFormat;import java.util.Date;import javax.jws.WebService;import javax.jws.soap.SOAPBinding;import service.SayHiService;/** * 作為測試的WebService實作類別 *  * @author Johness *  */@WebService(endpointInterface = "service.SayHiService")@SOAPBinding(style = SOAPBinding.Style.RPC)public class SayHiServiceImp implements SayHiService {    @Override    public void SayHiDefault() {        System.out.println("Hi, Johness!");    }    @Override    public void SayHi(String name) {        System.out.println("Hi, " + name + "!");    }    @Override    public int CheckTime(Date clientTime) {        // 精確到秒        String dateServer = new java.sql.Date(System.currentTimeMillis())                .toString()                + " "                + new java.sql.Time(System.currentTimeMillis());        String dateClient = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")                .format(clientTime);        return dateServer.equals(dateClient) ? 1 : 0;    }}

然後是發布(一般有兩種方式):

  方式一(此方式只能作為調試,有以下bug:

    jdk1.6u17?以下編譯器不支援以Endpoint.publish方式發布document方式的soap,必須在service介面和實作類別添加“@SOAPBinding(style = SOAPBinding.Style.RPC)”註解;

    訪問受限,似乎只能本機訪問(應該會綁定到publish的URL上,如下使用localhost的話就只能本機訪問)……):

package mian;import javax.xml.ws.Endpoint;import service.imp.SayHiServiceImp;public class Main {    /**     * 發布WebService     * 簡單     */    public static void main(String[] args) {        Endpoint.publish("http://localhost:8080/testjws/service/sayHi", new SayHiServiceImp());    }}

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

  以Tomcat為例,首先編寫sun-jaxws.xml檔案並放到WEB-INF下:

<?xml version="1.0" encoding="UTF-8"?><endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"    version="2.0">    <endpoint name="SayHiService"        implementation="service.imp.SayHiServiceImpl"        url-pattern="/service/sayHi" /></endpoints>

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

<?xml version="1.0" encoding="UTF-8"?><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">        <listener>          <listener-class>            com.sun.xml.ws.transport.http.servlet.WSServletContextListener          </listener-class>    </listener>    <servlet>        <servlet-name>SayHiService</servlet-name>          <servlet-class>            com.sun.xml.ws.transport.http.servlet.WSServlet          </servlet-class>    </servlet>      <servlet-mapping>          <servlet-name>SayHiService</servlet-name>          <url-pattern>/service/sayHi</url-pattern>      </servlet-mapping>        <welcome-file-list>        <welcome-file>index.html</welcome-file>        <welcome-file>index.htm</welcome-file>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></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則被產生了一個代理類來調用服務,接下來我們看看使用方式:

package test;import java.util.Date;import java.util.GregorianCalendar;import javax.xml.datatype.DatatypeConfigurationException;import javax.xml.datatype.DatatypeFactory;import javax.xml.datatype.XMLGregorianCalendar;import testjws.client.SayHiService;import testjws.client.SayHiServiceImpService;public class Main {    public static void main(String[] args) throws DatatypeConfigurationException {        // 擷取service        SayHiService service = new SayHiServiceImpService().getSayHiServiceImpPort();                // sayhi        service.sayHiDefault();        service.sayHi("Ahe");                // checktime        // 這裡主要說一下時間日期的xml傳遞,方法還略顯複雜        GregorianCalendar calender = new GregorianCalendar();        calender.setTime(new Date(System.currentTimeMillis()));        XMLGregorianCalendar xmldate = DatatypeFactory.newInstance().newXMLGregorianCalendar(calender);        System.out.println(service.checkTime(xmldate));    }}

看看伺服器的輸出,我們是否調用成功:

  

    

    成功了!

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

        

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

        

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

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

 

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.