利用JDK自帶工具構建一個簡單的Java SOAP Web Service

 


這兩天由於工作的某些原因,需要了解一些關於Web Service的知識,然後在網上看到了這麼一篇簡單的有點略微過時但是對於初次接觸Web Service的同學來說又很有必要了解的文章,於是自己嘗試着將文章翻譯過來。


A. 構造Web服務

1. 構造一個簡單的hello

假設你構造了這樣一個類,接受一個字符串輸入並且返回另外一個字符串

package waserver;

public class Hello{
    public String sayHello(String name){
        return "Hello " + name;
    }
}

2. 將hello類轉變成Web Service

我們可以簡單的利用幾個註解將這個hello類轉換成一個對應的Web Service: 
@WebService— 用來將一個類標記爲一個Web服務 
@SOAPBinding(style=SOAPBinding.Style.RPC)—用來標註通信類型,在這裏是採用RPC通信

package wsserver

import javax.jwx.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService
@SOAPBinding(style=SOAPBinding.Style.RPC)
public class Hello {
    public String sayHello(String name) {
        return "Hello " + name;
    }
}

3. 發佈Hello服務

我們可以利用JDK自帶的Endpoint類來發布服務。我們將向該類的public方法提供一個URL以及一個服務類的實例。

package wsserver;

import javax.xml.ws.Endpoint;

public class ServiceStarter {
    public static void main(String[] args) {
        String url = "http://localhost:1212/hello";

4. 編譯代碼

我們可以利用簡單的Javac命令來編譯上面的兩個類(即Hello類和ServiceStarter類)

javac -d . *.java
  •  

5. 啓動服務

我們可以利用下面的Java命令來運行ServiceStarter類,從而啓動我們的服務 
java wsserver/ServiceStarter

6. 檢查服務

現在服務已經成功運行起來了,你可以通過步驟3中的url地址獲取到服務的WSDL文件來檢查服務是否正確運行。服務的WSDL文件是通過在URL最後添加?wsdl得到的:http://localhost:1212/hello?wsdl
你得到的WSDL文件與下面所展示的XML文件類似。

<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. -->
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://wsserver/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://wsserver/" name="HelloService">
    <types></types>
    <message name="sayHello">
        <part name="arg0" type="xsd:string"></part>
    </message>
    <message name="sayHelloResponse">
        <part name="return" type="xsd:string"></part>
    </message>
    <portType name="Hello">
        <operation name="sayHello">
            <input message="tns:sayHello"></input>
            <output message="tns:sayHelloResponse"></output>
        </operation>
    </portType>
    <binding name="HelloPortBinding" type="tns:Hello">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding>
        <operation name="sayHello">
            <soap:operation soapAction=""></soap:operation>
            <input>
                <soap:body use="literal" namespace="http://wsserver/"></soap:body>
            </input>
            <output>
                <soap:body use="literal" namespace="http://wsserver/"></soap:body>
            </output>
        </operation>
    </binding>
    <service name="HelloService">
        <port name="HelloPort" binding="tns:HelloPortBinding">
            <soap:address location="http://localhost:1212/hello"></soap:address>
        </port>
    </service>
</definitions>

B. 創建客戶端

首先我們需要擁有一個服務類的接口,這樣我們才能夠通過java代碼調用服務類的方法。然後我們需要寫一些代碼來連接服務。非常幸運的是,如果我們能夠提供一個有效的WSDL URLJDK裏面的wsimport命令可以幫助我們完成所有的工作。

1. 導入服務接口和服務客戶端構造類

我們可以利用wsimport命令來完成這個目標 
wsimport -d . -p wsclient -keep http://localhost:1212/hello?wsdl 
-p參數指定生成類所在的目錄。執行上面這條命令可以生成兩個類文件:第一個文件爲Hello.java,這個接口包含了我們的sayHello方法。代碼如下所示:

package wsclient;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.1.6 in JDK 6
 * Generated source version: 2.1
 *
 */
@WebService(name = "Hello", targetNamespace = "http://wsserver/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface Hello {
    /**
     *
     * @param arg0
     * @return
     * returns java.lang.String
     */
    @WebMethod
    @WebResult(partName = "return")
    public String sayHello(
        @WebParam(name = "arg0", partName = "arg0")
        String arg0);
}

第二個文件爲HelloService.java,它包含幫助我們連接我們關注的含有無參構造器的服務以及getHelloPort()方法:

package wsclient;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceFeature;
/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.1.6 in JDK 6
 * Generated source version: 2.1
 *
 */
@WebServiceClient(name = "HelloService", targetNamespace = "http://wsserver/", wsdlLocation = "http://localhost:1212/hello?wsdl")
public class HelloService extends Service
{
    private final static URL HELLOSERVICE_WSDL_LOCATION;
    private final static Logger logger = Logger.getLogger(wsclient.HelloService.class.getName());
    static {
        URL url = null;
        try {
            URL baseUrl;
            baseUrl = wsclient.HelloService.class.getResource(".");
            url = new URL(baseUrl, "http://localhost:1212/hello?wsdl");
        } catch (MalformedURLException e) {
            logger.warning("Failed to create URL for the wsdl Location: 
            'http://localhost:1212/hello?wsdl', retrying as a local file");
            logger.warning(e.getMessage());
        }
        HELLOSERVICE_WSDL_LOCATION = url;
    }
    public HelloService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }
    public HelloService() {
        super(HELLOSERVICE_WSDL_LOCATION, new QName("http://wsserver/", "HelloService"));
    }
    /**
     *
     * @return
     * returns Hello
     */
    @WebEndpoint(name = "HelloPort")
    public Hello getHelloPort() {
        return super.getPort(new QName("http://wsserver/", "HelloPort"), Hello.class);
    }
    /**
     *
     * @param features
     * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported 
     * features not in the <code>features</code> parameter will have their default values.
     * @return
     * returns Hello
     */
    @WebEndpoint(name = "HelloPort")
    public Hello getHelloPort(WebServiceFeature... features) {
        return super.getPort(new QName("http://wsserver/", "HelloPort"), Hello.class, features);
    }
}

2. 調用Web服務

現在我們可以通過構造一個HelloService類的實例來調用Web服務了,我們可以通過調用HelloService實例的getHelloPort()方法來獲取Hello接口。然後我們可以像調用Java方法一樣調用它的方法並獲取相應的結果反饋:

package wsclient

public class HelloClient {
    public static void main(String[] args) {
        HelloService service = new HelloService();
        Hello hello = service.getHelloPort();
        String text = hello.sayHello("hany");
        System.out.println(text);
    }
}

3. 編譯和運行

javac -d . *.java 
java wsclient/HelloClient

點擊我查看原文

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章