天天看點

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

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兩種,差別和配置以後再說):

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService
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架構——使用JAX-WS(JWS)釋出WebService

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

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService
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;
    }

}      
轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

然後是釋出(一般有兩種方式):

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

    jdk1.6u17?以下編譯器不支援以Endpoint.publish方式釋出document方式的soap,必須在service接口和實作類添加“@SOAPBinding(style = SOAPBinding.Style.RPC)”注解;

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

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService
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());
    }

}      
轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

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

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

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService
<?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>      
轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

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

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService
<?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>      
轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

最後部署到Tomcat裡,值得一提的是您可能需要添加以下jar包(因為Tomcat沒有):

            

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

  啟動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架構——使用JAX-WS(JWS)釋出WebService

  最後是用戶端使用,由于WebService是平台和語言無關的基于xml的,是以我們完全可以使用不同語言來編寫或生成用戶端。

  一般有三種方式來使用(對于Java語言而言):

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

  

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

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

  然後我們就可以使用生成的檔案來調用伺服器暴露的方法了:

            

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

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

  從上面的目錄結構我們可以發現:服務端的每個webmethod都被單獨解析成為了一個類(如果使用了實體,實體也會被解析到用戶端,并且是源碼,是以建議使用實體時慎重)。

  

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

  (上面的圖是舊圖,隻是為了表示一下jaxws是為每個webmethod生成類的情況)

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

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService
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));

    }

}      
轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

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

  

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

    

    成功了!

    對于校驗時間的方法用戶端也收到回報了:

        

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

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

        

轉 真正的輕量級WebService架構——使用JAX-WS(JWS)釋出WebService

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

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

轉字 https://www.cnblogs.com/coprince/p/5732822.html

繼續閱讀