熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

使用WAS CE開發基於JAX-WS的RESTful服務

2013-11-23 20:38:30  來源: Java開源技術 

  什麼是REST

  REST是REpresentational State Transfer的縮寫代表分布式超媒體系統(如World Wide Web)上的一種軟件架構體系並不僅僅是創建Web Service的一種方法它最早由Roy Fielding於年在其博士論文Architectural Styles and the Design of Networkbased Software Architectures中提出並定義了一些基本原則簡單的說放到World Wide Web上就是所有的應用程序對象和功能都可以抽象為一種資源(Resource)並通過URI來定位並使用因此我們可以把符合REST原則的系統稱為RESTful也就是說REST是一種架構風格而不是一個標准你永遠不會看到WC發布一個叫REST的Specification

  RESTful Web Service與基於SOAP和WSDL的Web Service有著很多的不同它有著以下特點

  ·將Web Service作為一種資源並通過URI來定位

  ·使用HTTP中的POSTGETPUT和DELETE方法來代表對資源的CREATEREADUPDATEDELETE(CRUD)操作

  ·使用無狀態通信

  ·傳輸XML或者SON

  在JAXWS中提供了對開發和部署一個RESTful的Web Service的基本支持即通過實現Provider接口使得Web Serivce可以對傳輸的XML消息進行完全的控制因此我們可以在WAS CE中使用JAXWS開發一個RESTful的Web Service
    對RESTful Web Service提供完整支持的JAXRS Specification將會加入Java EE 的大家庭中當前的WAS CE Vx是遵循Java EE 的企業級應用服務器因此若想使用JAXRS開發RESTful Web Service請關注WAS CE的後續版本

  開發環境設置

  本文基於WAS CE的最新版本V開發一個RESTful的Web Service在開始編寫代碼之前請確認如下的開發環境

  ·Sun JDK V

  ·Eclipse IDE for Java EE Developers Ganymede

  ·WASCE Eclipse Plugin (WEP) V

  此外WAS CE使用Axis作為JAXWS引擎但是由於其存在一個已知的關於HTTP ContentType Header的問題(在Axis中才解決)所以我們需要將JAXWS引擎切換成Apache CXF (WAS CE使用版本為V)不用擔心WAS CE的模塊化架構使這個過程十分簡單過程如下

   啟動WAS CE

   打開Web //localhost:/console

   進入Application > Plugins頁面點擊Add Repository

  

   由於WAS CE V是基於Geronimo V開發所以我們也可以使用Geronimo的Server plugins在New Repository中輸入

  / 然後點擊Add Repository

  

   選擇剛剛添加的Repository然後點擊Show Plugins in selected repository

  

   勾選上以下plugins並且點擊install按鈕

  

   在以上CXF相關的Plugin安裝完成之後 我們需要更新WAS CE的配置文件以使得WAS CE在啟動時加載CXF以代替Axis(注意在更改配置文件前先要停止WAS CE服務器)

   停止WAS CE後打開<WASCE_HOME>/var/config/configxml

  去掉以下四個module的condition屬性

  <module name=orgnfigs/axisdeployer//car condition=/>

  <module name=orgnfigs/axisejbdeployer//car condition=/>

  <module name=orgnfigs/cxfdeployer//car condition=/>

  <module name=orgnfigs/cxfejbdeployer//car condition=/>

  增加load屬性axis相關的為falsecxf相關的為true

  <module name=orgnfigs/axisdeployer//car load=false/>

  <module name=orgnfigs/axisejbdeployer//car load=false/>

  <module name=orgnfigs/cxfdeployer//car load=true/>

  <module name=orgnfigs/cxfejbdeployer//car load=true/>

   重新啟動WAS CE服務器

  開發一個簡單的RESTful Web Service

   在Eclipse中創建一個Dynamic Web Project作為Web Service的宿主

  選擇File>New>Dynamic Web Project

  輸入Project Name為HelloRestfulService

   右擊Java Resources src新建一個class其中packageNameInterfaces如下設置

  

   加入如下代碼

  

  package comibmwascesamplesjaxwsrest;
import javaioByteArrayInputStream;
import javaxannotationResource;
import javaxservletServletRequest;
import javaxxmlparsersDocumentBuilder;
import javaxxmlparsersDocumentBuilderFactory;
import javaxxmltransformSource;
import javaxxmltransformdomDOMSource;
import javaxxmltransformstreamStreamSource;
import javaxxmlwsBindingType;
import javaxxmlwsProvider;
import javaxxmlwsWebServiceContext;
import javaxxmlwsWebServiceProvider;
import javaxxmlwshandlerMessageContext;
import javaxxmlwshttpHTTPBinding;
import javaxxmlwshttpHTTPException;
import orgwcdomNode;
import orgwcdomNodeList;
import orgxmlsaxInputSource;
@WebServiceProvider
@BindingType (value = HTTPBinding HTTP_BINDING )
public  class HelloWorld  implements Provider<Source> {
   @Resource
   protected WebServiceContext wsContext ;
   public Source invoke(Source source) {
       try {
           String targetName = null ;
           if (source == null ) {
               //Get: Getting input from query string
               MessageContext mc = wsContext getMessageContext();
               String query = (String) mcget(MessageContext QUERY_STRING );
               System out println( Query String = + query);
               ServletRequest req = (ServletRequest) mcget(MessageContext SERVLET_REQUEST );
               targetName = reqgetParameter( target );
           } else {
               //POST: Getting input from input box
               Node n = null ;
               if (source instanceof DOMSource) {
                   n = ((DOMSource) source)getNode();
               } else  if (source instanceof StreamSource) {
                   StreamSource streamSource = (StreamSource) source;
                   DocumentBuilder builder = DocumentBuilderFactorynewInstance()newDocumentBuilder();
                   InputSource inputSource = null ;
                   if (streamSourcegetInputStream() != null ) {
                       inputSource = new InputSource(streamSourcegetInputStream());
                   } else  if (streamSourcegetReader() != null ) {
                       inputSource = new InputSource(streamSourcegetReader());
                   }
                   n = builderparse(inputSource);
               } else {
                   throw  new RuntimeException( Unsupported source: + source);
               }
               NodeList children = ngetChildNodes();
               for ( int i = ; i < childrengetLength(); i++) {
                   Node child = em(i);
                   if (childgetNodeName()equals( people )) {
                       targetName = childgetAttributes()getNamedItem( target )getNodeValue();
                       break ;
                   }
               }
           }

  String body = <ns:return xmlns:ns=\\>
                   + <ns:HelloWorldResponse> + this sayHello(targetName) + </ns:HelloWorldResponse>
                   + </ns:return> ;
           return  new StreamSource( new ByteArrayInputStream(bodygetBytes()));

  } catch (Exception e) {
           eprintStackTrace();
           throw  new HTTPException();
       }
   }

  private String sayHello(String target){
       return  Hello + target;
   }
}

  讓我們看一看代碼中的幾個關鍵點

  a) @WebServiceProvider 表明這個Web Service實現了Provider接口可以對XML消息進行完全的處理

  b) Provider 是這類Web Service都要實現的接口它只有一個方法需要實現

  public abstractjavalangObject invoke(javalangObject arg

  c) Source 是交換信息的載體

  當Source對象為空時表示是一個GET Request因為這種情況下所有信息是被拼成一個URI的參數並傳到這個URI對應的Web Service

  否則是一個POST Request其內容會包括在一個Source對象內

  另外Response的內容也要放到一個Source對象內

   編寫webxml

  為了使我們前面編寫的Web Service能夠成功部署到WAS CE中我們需要將如下內容加入到webxml中
 <servlet>
    <servletname>Hello</servletname>
    <servletclass>comibmwascesamplesjaxwsrestHelloWorld</servletclass>
</servlet>
<servletmapping>
    <servletname>Hello</servletname>
    <urlpattern>/Hello</urlpattern>
</servletmapping>

  注意這裡只是借用了<servlet>和<servletmapping>標簽來幫助暴露Web Service並不是真是要求這個Web Service必須要實現HttpServlet接口

   部署運行並測試這個Web Service

  右擊這個HelloRestfulService工程選擇Run As > Run on Server會將其部署到WAS CE中當Status欄變為Synchronized時在Console中會有類似如下信息顯示

  

  通過訪問如下地址測試使用GET方式調用RESTful Web Service返回的結果

  //localhost/HelloRestfulService/Hello?target=Rex

  

  開發一個簡單的RESTful Web Service Client

   創建一個Dynamic Web Project作為Client

  選擇File>New>Dynamic Web Project

  輸入Project Name為HelloRestfulClient

   新建一個testgetjsp加入如下內容
 <form method=POST action=HelloGetMethodRequester>
  Target Name: <input type=text name=target>
  <input type=submit value=Submit>
</form>

  這個JSP用來為HelloGetMethodRequester Servlet提供參數

   創建HelloGetMethodRequester Servlet加入如下內容

  protected void doPost(HttpServletRequest request HttpServletResponse response) throws ServletException IOException {
   PrintWriter ut = responsegetWriter();
   String target = requestgetParameter( target );

  String queryRequest = //localhost:/HelloRestfulService/Hello?target= + target;
   GetMethod method = new GetMethod(queryRequest);
   HttpClient client = new HttpClient();
   int statusCode = clientexecuteMethod(method);
   if (statusCode != ) { //HttpStatusSC_OK
       System err println( Method failed: + methodgetStatusLine());
   }

  try {
       DocumentBuilder builder= DocumentBuilderFactorynewInstance()newDocumentBuilder();
       Document queryResponse = builderparse(methodgetResponseBodyAsStream());
       XPath xPath = XPathFactorynewInstance()newXPath();
       NodeList nodes = (NodeList) xPathevaluate( /return queryResponse XPathConstants NODESET );
       for ( int i = ; i < nodesgetLength(); i++) {
           // Get eachxpathexpression as a string
           String str = (String) xPathevaluate( HelloWorldResponse em(i) XPathConstants STRING );
           outprintln( Service return: + str);
       }
   } catch (Exception e) {
       eprintStackTrace();
   }
}

  在這個Servlet中我們用到了commonscodecjar和commons兩個包因此我們需要將它們加入到Build Path中

  

  這兩個包在WAS CE的如下目錄中可以找到

  <WASCE_HOME>\repository\commonscodec\commonscodec\\commonscodecjar

  <WASCE_HOME >\repository\commonshttpclient\commonshttpclient\\commons

  讓我們看一看這段Servlet代碼中的一些關鍵點

  a) 首先創建了一個HttpClient對象並運行了GetMethod即使用GET請求如下URI

  //localhost/HelloRestfulService/Hello?target= + target

  b) 如果成功返回即statusCode為則可以從method對象中得到返回的結果

  methodgetResponseBodyAsStream()

  c) 因為返回的結果為自定義的一段XML文檔所以我們可以使用XPath來處理並輸出到頁面上

   編寫部署計劃geronimowebxml

  為使這個Web Client能夠成功部署到WAS CE中我們還需要在geronimowebxml的<environment>中加入如下依賴
 <dep:dependencies>
    <dep:dependency>
        <dep:groupId>commonscodec</dep:groupId>
        <dep:artifactId>commonscodec</dep:artifactId>
        <dep:version></dep:version>
        <dep:type>jar</dep:type>
    </dep:dependency>
    <dep:dependency>
        <dep:groupId>commonshttpclient</dep:groupId>
        <dep:artifactId>commonshttpclient</dep:artifactId>
        <dep:version></dep:version>
        <dep:type>jar</dep:type>
    </dep:dependency>
</dep:dependencies>

   部署和運行

  右擊這個HelloRestfulClient工程選擇Run As > Run on Server會將其部署到WAS CE中當Status欄變為Synchronized時表示部署成功

  在浏覽器中打開如下頁面

  

  輸入Rex並點擊Submit可得到如下結果

  

  總結

  本文介紹了REST的基本概念以及如何在WAS CE V下開發一個RESTful Web Service和一個使用GET方式的Client如果讀者朋友有興趣的話也可以嘗試擴展這個Client如增加testpostjsp和HelloPostMethodRequester Servlet兩個文件

   testpostjsp包括一個文件上載框用以上傳一個XML文件

   HelloPostMethodRequester Servlet用於將XML文件以POST方式傳送給HelloWorld這個Service

  事實上我們的HelloWorld RESTful Web Service已經具備了處理接收一個XML文件的能力

  資源鏈接

  ·WAS CE及Samples下載

  

  ·WAS CE Eclipse Plugin (aka WEP WAS CEs WTP Server Adapter)下載

  

  ·WAS CE文檔

  

  ·WAS CE主頁


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28821.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.