發佈與調用 Web 服務還能再簡化嗎?

本文是《輕量級 Java Web 框架架構設計》的系列博文。 java

在 Java 6 之後,發佈與調用 Web 服務是一件很是簡單的事情,只需使用 JAX-WS(Java API for XML-based Web Services)便可,它也是 JSR-224 規範。你們知道規範都是接口,是沒有實現的,不過官方提供了一個參考實現,名爲 JAX-WS RI,其中的 RI 是 Reference Implement(參考實現)的意思。 架構

咱們能夠直接藉助 JAX-WS RI 來發布與調用 Web 服務,還等什麼?如今就開始! 框架

第一步:下載 JAX-WS RI 程序包 ide

這是一個壓縮包,大約 17 M 左右,下載後直接解壓便可,好比,解壓到 D:\SDK\JAX-WS 目錄下。 工具

由於要將服務從 Web 應用裏發佈出來,而 Web 應用是部署在 Tomcat 上的,但此時 Tomcat 殊不知道 JAX-WS RI 在哪裏。怎麼辦呢?不妨對 Tomcat 作一個簡單的配置吧。 測試

第二步:配置 Tomcat url

打開 TOMCAT\conf\catalina.properties 文件,作以下修改: spa

common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,D:/SDK/JAX-WS/lib/*.jar .net

注意:以上紅色文字即爲所修改的內容。 架構設計

第三步:配置 Web 服務接口

在 Java 6 中提供了一個 javax.jws 包,全部的 JAX-WS 註解都在該包中。可以使用 @WebService 註解配置在 Java 接口上:

import javax.jws.WebService;

@WebService
public interface GreetingService {

    void sayHello(String name);
}

第四步:配置 Web 服務實現

一樣適用 @WebService 註解配置 Web 服務實現,不一樣的是,須要定義兩個屬性:

import com.smart.sample.service.GreetingService;
import javax.jws.WebService;

@WebService(serviceName = "GreetingService", endpointInterface = "com.smart.sample.service.GreetingService")
public class GreetingServiceImpl implements GreetingService {

    @Override
    public void sayHello(String name) {
        System.out.println("Hello " + name);
    }
}

其中,serviceName 屬性表示 Web 服務的名稱,endpointInterface 屬性表示 Web 服務的接口。

爲何叫 endpoint(端點)?其實本質就是一個 Java 接口,只不過在 Web 服務中給它叫了一個高端大氣上檔次的名字罷了。

第五步:發佈 Web 服務

在 WEB-INF 目錄下新建一個名爲 sun-jaxws.xml 的文件,其內容以下:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">

    <endpoint name="GreetingService" url-pattern="/GreetingService" implementation="com.smart.sample.service.impl.GreetingServiceImpl"/>

</endpoints>

以上對 endpoint 起了一個名字(name 屬性),配置了 url 匹配地址是什麼(url-pattern 屬性),此外還指定了一個具體的 Web 服務實現(implementation 屬性)。

還要作什麼呢?直接啓動 Tomcat 吧!

第六步:啓動 Tomcat

可以使用如下地址查看 Web 服務的 WSDL:

http://localhost:8080/smart-sample/GreetingService?wsdl

WSDL 是 Web Services Description Language 的縮寫,說白了就是 Web 服務的描述文件,描述一下這個 Web 服務到底有什麼?

以上 XML 文檔中最重要的就 4 個東西:

  1. Web 服務的名稱(name = "GreetingService")
  2. Web 服務的命名空間(targetNamespace="http://impl.service.sample.smart.com/"
  3. Web 服務的地址(location="http://localhost:8080/smart-sample/GreetingService"
  4. Web 服務的方法(見 operation 元素

以上這 4 要素正是 Web 服務客戶端須要知道的信息,最後用一個客戶端來完成 Web 服務調用。

最後一步:調用 Web 服務

寫一個客戶端類,用它來調用以上發佈的 Web 服務。注意:在調用時可不要關閉 Tomcat 哦!

import com.smart.sample.service.GreetingService;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class GreetingServiceClient {

    public static void main(String[] args) throws Exception {
        URL url = new URL("http://localhost:8080/smart-sample/GreetingService?wsdl");
        QName qname = new QName("http://impl.service.sample.smart.com/", "GreetingService");

        Service service = Service.create(url, qname);
        GreetingService greetingService = service.getPort(GreetingService.class);

        greetingService.sayHello("Jack");
    }
}

客戶端代碼通常分爲三步:

  1. 定義相關數據,包括 WSDL 的 URL 地址、Web 服務的 QName(即 Qualified Name,限定名稱,可理解爲帶路徑的名稱,相似於 Java 中帶包名的類)
  2. 獲取 Service Port(可理解爲調用 Web 服務的代理對象,其實調用 Web 服務的本質上就是代理模式的一種實踐)
  3. 調用目標方法(這就是經過代理來調用目標對象的方法)

運行後,就能夠在 Tomcat 控制檯下看到 Hello Jack 的輸出文字了。

夠簡單吧!我不這麼認爲。

至少有兩個地方是能夠簡化一下的:

  1. 只需在接口上配置 @WebService,無需在實現上配置。
  2. 無需配置 sun-jaxws.xml,直接在接口上配置便可。

也就是說,發佈 Web 服務只須要在一個地方配置,那就是接口!

Smart 又是如何進行簡化,讓它變得更加優雅的呢?敬請關注。

同時也期待着您更加優秀的解決方案!


補充(2013-11-22)

除了經過 Web 容器(Tomcat)來發布 Web 服務之外,JAX-WS 還提供了另外一種發佈方式:

import com.smart.sample.service.impl.GreetingServiceImpl;
import javax.xml.ws.Endpoint;

public class GreetingServiceServer {

    public static void main(String[] args) throws Exception {
        Endpoint.publish("http://localhost:8080/smart-sample/GreetingService", new GreetingServiceImpl());
    }
}

JAX-WS 提供了一個 Endpoint 工具類,只需調用它的 publish 方法便可發佈 Web 服務。該方法包括 2 個參數:

  1. 第一個參數是 Web 服務的地址。
  2. 第二個參數是 Web 服務的實現。

此方法無需藉助 Tomcat,方便客戶端測試。

不過對於 Web 應用而言,最直接的方式仍是經過 Web 容器來部署比較恰當。

相關文章
相關標籤/搜索