使用WAS CE开发基于JAX-WS的RESTful服务

作者&投稿:强溥 (若有异议请与网页底部的电邮联系)
~

   一 什么是REST

  REST是REpresentational State Transfer的缩写 代表分布式超媒体系统(如World Wide Web)上的一种软件架构体系 并不仅仅是创建Web Service的一种方法 它最早由Roy Fielding于 年在其博士论文 Architectural Styles and the Design of Neork based Sofare Architectures 中提出 并定义了一些基本原则 简单的说 放到World Wide Web上 就是所有的应用程序对象和功能都可以抽象为一种资源(Resource) 并通过URI来定位并使用 因此 我们可以把符合REST原则的系统称为RESTful 也就是说 REST是一种架构风格 而不是一个标准 你永远不会看到W C发布一个叫REST的Specification

  RESTful Web Service与基于SOAP和WSDL的Web Service有着很多的不同 它有着以下特点

  ·将Web Service作为一种资源 并通过URI来定位

  ·使用HTTP中的POST GET PUT和DELETE方法来代表对资源的CREATE READ UPDATE DELETE(CRUD)操作

  ·使用无状态通信

  ·传输XML或者SON

  在JAX WS中提供了对开发和部署一个RESTful的Web Service的基本支持 即通过实现Provider接口使得Web Serivce可以对传输的XML消息进行完全的控制 因此我们可以在WAS CE中使用JAX WS开发一个RESTful的Web Service     对RESTful Web Service提供完整支持的JAX RS Specification将会加入Java EE 的大家庭中 当前的WAS CE V x是遵循Java EE 的企业级应用服务器 因此 若想使用JAX RS开发RESTful Web Service 请关注WAS CE的后续版本

   二 开发环境设置

  本文基于WAS CE的最新版本V 开发一个RESTful的Web Service 在开始编写代码之前 请确认如下的开发环境

  ·Sun JDK V

  ·Eclipse IDE for Java EE Developers Ganymede

  ·WASCE Eclipse Plug in (WEP) V

  此外 WAS CE使用Axis 作为JAX WS引擎 但是由于其存在一个已知的关于HTTP Content Type Header的问题(在Axis 中才解决) 所以我们需要将JAX WS引擎切换成Apache CXF (WAS CE使用版本为V ) 不用担心 WAS CE的模块化架构 使这个过程十分简单 过程如下

   启动WAS CE

   打开Web //localhost: /console

   进入Application > Plugins页面 点击Add Repository

  

   由于WAS CE V 是基于Geronimo V 开发 所以我们也可以使用Geronimo的Server plug ins 在New Repository中输入

   / 然后点击Add Repository

  

   选择刚刚添加的Repository 然后点击Show Plugins in selected repository

  

   勾选上以下plug ins并且点击install按钮

  

   在以上CXF相关的Plugin安装完成之后 我们需要更新WAS CE的配置文件 以使得WAS CE在启动时加载CXF以代替Axis (注意 在更改配置文件前先要停止WAS CE服务器)

   停止WAS CE后 打开<WASCE_HOME>/var/config/config xml

  去掉以下四个module的condition属性

  <module name= nfigs/axis deployer/ /car condition= … />

  <module name= nfigs/axis ejb deployer/ /car condition= … />

  <module name= nfigs/cxf deployer/ /car condition= … />

  <module name= nfigs/cxf ejb deployer/ /car condition= … />

  增加load属性 axis 相关的为false cxf相关的为true

  <module name= nfigs/axis deployer/ /car load= false />

  <module name= nfigs/axis ejb deployer/ /car load= false />

  <module name= nfigs/cxf deployer/ /car load= true />

  <module name= nfigs/cxf ejb deployer/ /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 其中package Name Interfaces如下设置

  

   加入如下代码

  

  package ibm wasce samples jaxws rest;import java io ByteArrayInputStream;import javax annotation Resource;import javax servlet ServletRequest;import javax xml parsers DocumentBuilder;import javax xml parsers DocumentBuilderFactory;import javax xml transform Source;import javax xml transform dom DOMSource;import javax xml transform stream StreamSource;import javax xml ws BindingType;import javax xml ws Provider;import javax xml ws WebServiceContext;import javax xml ws WebServiceProvider;import javax xml ws handler MessageContext;import javax xml ws HTTPBinding;import javax xml ws HTTPException;import w c dom Node;import w c dom NodeList;import xml sax InputSource;@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) mc get(MessageContext QUERY_STRING );               System out println( Query String = + query);               ServletRequest req = (ServletRequest) mc get(MessageContext SERVLET_REQUEST );               targetName = req getParameter( 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 = DocumentBuilderFactory newInstance() newDocumentBuilder();                   InputSource inputSource = null ;                   if (streamSource getInputStream() != null ) {                       inputSource = new InputSource(streamSource getInputStream());                   } else  if (streamSource getReader() != null ) {                       inputSource = new InputSource(streamSource getReader());                   }                   n = builder parse(inputSource);               } else {                   throw  new RuntimeException( Unsupported source: + source);               }               NodeList children = n getChildNodes();               for ( int i = ; i < children getLength(); i++) {                   Node child = em(i);                   if (child getNodeName() equals( people )) {                       targetName = child getAttributes() getNamedItem( target ) getNodeValue();                       break ;                   }               }           }

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

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

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

  让我们看一看代码中的几个关键点

  a) @WebServiceProvider 表明这个Web Service实现了Provider接口 可以对XML消息进行完全的处理

  b) Provider 是这类Web Service都要实现的接口 它只有一个方法需要实现 即

  public abstractjava lang Object invoke(java lang Object arg )

  c) Source 是交换信息的载体

  当Source对象为空时 表示是一个GET Request 因为这种情况下 所有信息是被拼成一个URI的参数 并传到这个URI对应的Web Service

  否则 是一个POST Request 其内容会包括在一个Source对象内

  另外 Response的内容也要放到一个Source对象内

   编写web xml

  为了使我们前面编写的Web Service能够成功部署到WAS CE中 我们需要将如下内容加入到web xml中  <servlet>    <servlet name>Hello</servlet name>    <servlet class> ibm wasce samples jaxws rest HelloWorld</servlet class></servlet><servlet mapping>    <servlet name>Hello</servlet name>    <url pattern>/Hello</url pattern></servlet mapping>

  注意 这里只是借用了<servlet>和<servlet mapping>标签来帮助暴露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

   新建一个testget jsp 加入如下内容  <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 = response getWriter();   String target = request getParameter( target );

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

  try {       DocumentBuilder builder= DocumentBuilderFactory newInstance() newDocumentBuilder();       Document queryResponse = builder parse(method getResponseBodyAsStream());       XPath xPath = XPathFactory newInstance() newXPath();       NodeList nodes = (NodeList) xPath evaluate( /return queryResponse XPathConstants NODESET );       for ( int i = ; i < nodes getLength(); i++) {           // Get eachxpathexpression as a string           String str = (String) xPath evaluate( HelloWorldResponse em(i) XPathConstants STRING );           out println( Service return: + str);       }   } catch (Exception e) {       e printStackTrace();   }}

  在这个Servlet中我们用到了mons codec jar和mons 两个包 因此我们需要将它们加入到Build Path中

  

  这两个包在WAS CE的如下目录中可以找到

  <WASCE_HOME>epository\mons codec\mons codec\ \mons codec jar

  <WASCE_HOME >epository\mons client\mons client\ \mons

  让我们看一看这段Servlet代码中的一些关键点

  a) 首先创建了一个HttpClient对象 并运行了GetMethod 即使用GET请求如下URI

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

  b) 如果成功返回 即statusCode为 则可以从method对象中得到返回的结果

  method getResponseBodyAsStream()

  c) 因为返回的结果为自定义的一段XML文档 所以我们可以使用XPath来处理并输出到页面上

   编写部署计划geronimo web xml

  为使这个Web Client能够成功部署到WAS CE中 我们还需要在geronimo web xml的<environment>中加入如下依赖  <dep:dependencies>    <dep:dependency>        <dep:groupId>mons codec</dep:groupId>        <dep:artifactId>mons codec</dep:artifactId>        <dep:version> </dep:version>        <dep:type>jar</dep:type>    </dep:dependency>    <dep:dependency>        <dep:groupId>mons client</dep:groupId>        <dep:artifactId>mons client</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 如增加testpost jsp和HelloPostMethodRequester Servlet两个文件

   testpost jsp包括一个文件上载框 用以上传一个XML文件

   HelloPostMethodRequester Servlet用于将XML文件以POST方式传送给HelloWorld这个Service

  事实上 我们的HelloWorld RESTful Web Service已经具备了处理接收一个XML文件的能力

   六 资源链接

  ·WAS CE及Samples下载

  

  ·WAS CE Eclipse Plug in (aka WEP WAS CE s WTP Server Adapter)下载

  

  ·WAS CE文档

  

  ·WAS CE主页

lishixinzhi/Article/program/Java/ky/201311/28821




非国家标准行政区划只宜作为统计汇总用地址代码19743684183: 设R施左下角为LB(2,2),右上角为RT(9,7)的矩形裁剪窗口,线段AB的端点为A(0,3),B(6,8).(1)根据Cohen - Sutherland算法的区域编码方式,写出线段AB端点... -
伏剑痔血:[答案] 因:a+b=7 ab=7 c=√(a2+b2) 所以:将 a+b=7两边同时平方得: a2+2ab+b2=49 a2+b2=49-2ab a2+b2=49-2x7 a2+b2=49-14 a2+b2=35 所以: c=√(a2+b2)=√35 斜边上AB(=c)中线长度等于斜边的一半:√35/2 即...

非国家标准行政区划只宜作为统计汇总用地址代码19743684183: 怎么样才能学好嵌入式系统开发?具体的学习路线,看书还是看视频好 -
伏剑痔血: 嵌入式学习的话比较难,因为嵌入式需要学习东西特别多而且杂,更重要的是很多知识点很难理解.嵌入式的学习路线是Linux系统、Shell编程、Linux开发...

非国家标准行政区划只宜作为统计汇总用地址代码19743684183: 手机有无操作系统的区别? -
伏剑痔血: 我也来补充,其实功能是一方面,所谓没有操作系统的手机,里面的系统可以理解为一个普通应用软件,而所说有操作系统的手机,这样的手机有CPU和内存的.和电脑差不多的存在.这种手机功能可...

非国家标准行政区划只宜作为统计汇总用地址代码19743684183: Web Service,用哪个框架最好 -
伏剑痔血: 现在流行webservice框架主要是Apache Axis2和Apache CXF.Apache CXF是Codehaus XFire 的第二代产品,目前在不同框架中性能最佳,应该是开发者不错的选择,这与它本身的架构设计不无关系.相比其他框架,CXF具有几个突出的特性...

非国家标准行政区划只宜作为统计汇总用地址代码19743684183: 数据库用oracle,语言用C#,用哪个开发工具比较好? -
伏剑痔血: NET集成开发环境 MonoDevelop MonoDevelop 是个Linux平台上的开放源代码集成开发环境,主要用来开发Mono与.NET Framework软件.MonoDevelop 整合了很多Eclipse与Microsoft Visual Studio的特性,像是 Intellisense、版本控制还有 GUI ...

非国家标准行政区划只宜作为统计汇总用地址代码19743684183: 全部手机操作系统简介? -
伏剑痔血: Symbian系统 iOS系统 Brew系统 Windows Phone系统 Linux系统Palm OS Palm WebOS Android 系统(是现在比较流行的手机系统)BlackBerry OS系统 MeeGo系统

非国家标准行政区划只宜作为统计汇总用地址代码19743684183: 平板电脑我的世界 - 平板电脑我的世界怎么操作
伏剑痔血: 1. 平板电脑我的世界怎么操作可以玩的,需要在应用软件中先下载安装,并登录玩游... Windows CE属于嵌入式操作系统,使用标准Win 32 API子集,很多Windows程序可...

非国家标准行政区划只宜作为统计汇总用地址代码19743684183: winpos(关于winpos的基本详情介绍)
伏剑痔血: 1、Windows Embedded Compact(即 Windows CE)是微软公司嵌入式、移动计算平台的基础,它是一个开放的、可升级的32位嵌入式操作系统,是基于掌上型电脑类的...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网