2010年10月12日 星期二

[JAX-WS]簡單實作 WebService

現在實作 WebService 真的比以前簡單多了,就連 Client 端要呼叫、傳遞資料等等也都很簡單
下面就來看看要怎麼實作一個 WebService 及 Client


(一)實作 WebService:

1. 準備環境:
(1)JDK 1.6 (我使用的版本是 1.6.0_20)
(2)在 WebAP 的 WEB-INF/lib 下放置以下 jar 檔
gmbal-api-only.jar
jaxb-impl.jar
jaxws-api.jar
jaxws-rt.jar
management-api.jar
policy.jar
stax-ex.jar
streambuffer.jar
這些 jar 檔可以從 https://jax-ws.dev.java.net/ 下載,我使用的版本是 JAXWS2.2.1-20100617.zip

2. 實作一個要成為 WebService 的 class,下面是簡單的範例
註:可以再寫一個 SEI (Service Endpoint Interface)
並且這個 class 去 implement 它,不過這個不是必要的,這裡就不介紹了
package com.blogspot.karrysu;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public class MyWS {
 @WebMethod
 public TestVO test(TestVO vo){
  if( vo==null ) return null;
  vo.setStrValue("Modified by Server side.");
  return vo;
 }
}
注意:class 必需標示 @WebService,而要提供服務的 method 要標示 @WebMethod
這是 JAX-WS 所定義的規格

3. 設定 WebAP
(1)修改 WEB-INF/web.xml ,加入下面設定
<listener>
 <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
 <servlet-name>WSServlet</servlet-name>
 <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
</servlet>
<servlet-mapping>
 <servlet-name>WSServlet</servlet-name>
 <url-pattern>/services/*</url-pattern>
</servlet-mapping> 
</listener>
4. 新增 WEB-INF/sun-jaxws.xml,內容如下
<endpoints version="2.0" xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">
 <endpoint implementation="com.blogspot.karrysu.MyWS" name="MyWS" url-pattern="/services/myws">
</endpoint></endpoints>
5. 啟動 Web Server,並用瀏覽器開啟下面網址
http://localhost:8080/WebAP名/services/myws
例如我的測試環境是
http://localhost:8080/WebServices/services/myws
如果有看到下面畫面,即表示 WebService 已可提供服務了

Web Services


Endpoint

Information

Service Name:{http://karrysu.blogspot.com/}MyWSService
Port Name:{http://karrysu.blogspot.com/}MyWSPort

Address:http://localhost:8080/WebServices/services/myws
WSDL:http://localhost:8080/WebServices/services/myws?wsdl
Implementation class:com.blogspot.karrysu.MyWS

(一)實作 Client:

1. 準備環境:
(1)JDK 1.6 (我使用的版本是 1.6.0_20)
(2)並不需要什麼額外的 jar 檔即可呼叫 WebService

2. 產生 WebService 的 Client 端檔案,在命令列中,切換到 project 所在路徑執行
$JAVA_HOME/bin/wsimport -d [classes path] -s [src path] -p [target package] [wsdl url]
參數說明:
-d:產生的 class 檔要放在哪裡(不含 package 路徑)
-s:產生的 java 檔要放在哪裡(不含 package 路徑)
-p:要產生到哪個 package,這裡的 package 不一定要跟 Server 端的一樣
例如
$JAVA_HOME/bin/wsimport -d ./build/classes -s ./src -p com.blogspot.karrysu.wsclient http://localhost:8080/WebServices/services/myws?wsdl
這裡的 wsdl url 只是為了做為依據來產生檔案,與實際上呼叫時的 wsdl url 不一定要相同

3. 呼叫的語法
XXXXService service = new XXXXService(
  new URL("wsdl url")
  ,new QName("targetNamespace", "Service name")
 );
XXXX port = service.getXXXXPort();
port.XXXX(); //這裡就可以直接使用 WebService 的 method 了

下面是簡單的範例
package com.blogspot.karrysu.wsclient;

import java.net.URL;
import javax.xml.namespace.QName;

public class TestRun {
 public static void main(String[] args) {
  try {
   MyWSService service = new MyWSService(
     new URL("http://localhost:8080/WebServices/services/myws?wsdl")
     ,new QName("http://karrysu.blogspot.com/", "MyWSService")
    );
   MyWS port = service.getMyWSPort();
   
   TestVO childVO = new TestVO();
   childVO.setStrValue("test childVO");
   TestVO vo = new TestVO();
   vo.setStrValue("Created by client side");
   vo.setChildVO(childVO);
   System.out.println(voToString("old vo = ",vo));
   
   TestVO rtnvo = port.test(vo); //呼叫 WebService 的 method
   
   System.out.println(voToString("old vo = ",rtnvo));
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 //下面這個 method 不是重點
 public static String voToString(String prefix,TestVO vo){
  StringBuilder sb = new StringBuilder();
  if( prefix!=null ){
   sb.append(prefix);
  }
  sb.append(vo.getStrValue());
  sb.append(",childVO=[");
  if( vo.getChildVO()!=null ){
   sb.append(voToString(null,vo.getChildVO()));
  }else{
   sb.append("null");
  }
  sb.append("]");
  return sb.toString();
 }
}

相關文章
[JAX-WS]解決 WebService 只會產生一個實體的問題

沒有留言:

張貼留言

廣告訊息會被我刪除