基于Jersey框架的RESTful Web Service的研究与实现

来源 :中国科技博览 | 被引量 : 0次 | 上传用户:yichunjekiyi
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  [摘 要]日益复杂的异构环境对Web 服务提出了更高的要求。相比于RPC和SOAP,更为简洁的、轻量级的RESTful Web Service获得了越来越广泛的关注。文章简要阐述了REST风格及其规范JAX-RS,提出一种利用Jersey框架对其实现的方式。研究利用JQuery AJAX技术处理GET、POST、PUT、DELETE请求,采用CORS方案解决跨域访问问题,使用JSON封装数据以提高异构平台间数据的一致性及处理效率。实践证明,该方法具有其有效性和先进性。
  [关键词]Jersey RESTful Web Service JSON Android JAX-RS
  中图分类号:TP393.09 文献标识码:A 文章编号:1009-914X(2016)02-0361-03
  1 REST、JAX-RS与Jersey简介
  REST最初是2000年Roy Thomas Fielding在他的博士论文Architectural Styles and the Design of Network——based Software Arehitectures[2]中提出的,是针对分布式系统的软件架构风格。然而事实上,REST并不是一个全新的概念,它其实也是HTTP1.1协议的设计原则[3]。它是使用HTTP协议的语法和语义将其功能完全作为一组URI可寻址资源来向服务消费者提供的Web Services架构方式[4]。在REST风格中,资源是最关键的概念,任何可以被访问或被远程操纵的东西都可能是一个资源。REST充分利用HTTP的自身功能,使用其标准的?GET、POST、PUT、DELETE?四种请求完成资源的CRUD操作,即新增(Create)、读取(Read)、修改(Update)和删除(Delete)。它使得Web服务的开发回归到HTTP本质,从而降低开发的复杂性,使得开发更加简洁而高效。而满足REST风格的设计就称之为RESTful。
  REST虽然十多年前就已被提出,但其相关规范直到2008年才被正式批准,这就是JAX-RS (Java API for RESTful Web Services , JSR 311)。JAX-RS规范是Sun公司(现为Oracle公司)Java企业版(JEE)开源实现的规范的一部分。JAX-RS通过提供一个带有注释机制的API把普通Java类和接口联系起来,采用一种特殊的资源描述方式为RESTful Web服务建立一个资源类[5]。它集成了JAXB,通过其注释机制大大简化了RESTful Web Service的开发,有效缩短了其开发周期。
  目前,遵从JAX-RS规范实现RESTful Web Service的框架很多,例如Jersey、Apache CXF、RESTEasy、RESTlet、Apache Wink等。然而,这并不是必须的。事实上,Spring MVC 3.0就是按照其自定义的方式来实现RESTful Web Service的。在众多实现框架中,Jersey是Sun公司伴随着JAX-RS规范同步发布的一个参考实现项目,能对JAX-RS规范提供良好支持,更加直观,具有代表性。然而截止目前,相比于rails等其他框架,国内外关于Jersey框架的文献参考少之又少。文章对于弥补该方面的空白具有一定价值。
  2 总体设计
  系统由应用层、资源层、服务层和数据访问层这四层自上而下组成,结构如图1所示。
  应用层(Application Layer)位于客户端,可以是Web浏览器或Android手机等终端。该层负责接收用户的输入数据,并向服务端的资源层发送资源请求,同时能向用户展示结果视图。
  资源层(Resource Layer)处理应用层发送的HTTP请求,根据请求类型调用服务层的不同方法,并向应用层返回JSON等格式数据。用户便是通过该层提供的URI来请求资源的。
  服务层(Service Layer)则是系统功能的核心,执行各种业务逻辑以完成系统各项功能。它通过与数据层的通信获取需要的数据,然后通过加工处理,向资源层提供具体服务。
  数据层(Data Layer)利用DAO封装与具体业务逻辑无关的CRUD操作,从底层数据库获取相应数据并返回给服务层。
  REST风格的核心概念是资源,而URI则是访问资源的关键,设计良好的、统一规范的URI十分必要。下表1是对应四类资源的部分URI举例。限于篇幅,URI的设计原则此处不做介绍。
  3 RESTful Web Service服务端实现
  服务端代码由5个包组成,dao、service和resource包分别用于实现数据层、服务层和资源层。除此之外,pojo包专用于存放POJO,filter包则用于存放过滤器。
  3.1 POJO类
  在com.rest.pojo包中建立POJO类:Customer。POJO类使用 @XmlRootElement 注释,以便将bean以xml或json格式返回。具体如下:
  @XmlRootElement
  public class Customer {
  private String id;
  private String name;
  private String addr;
  getters and setters
  }
  3.2 DAO类
  在com.rest.dao包中建立CustomerDAO类,该包位于数据层,实现与业务逻辑无关的数据库CRUD操作。研究使用MySql数据库,利用JDBC实现数据库连接与访问。例如下述代码便是利用JDBC提供的Connection等对象实现了数据的增删改操作。   //该方法与业务逻辑无关,只要是关于数据库的增删改操作均能适用
  static public int noQueryDB(String sql){
  Connection conn=dbConnection(); //用自定义方法实现数据库连接
  Statement stmt=createStatement(conn); //用自定义方法实例化Statement对象
  int count=stmt.executeUpdate(sql);
  return count; //返回实际影响的行数
  }
  3.3 Service类
  在com.rest.service包中建立CustomerService类,该包位于服务层。CustomerService类对应用层传递的数据进行逻辑加工,然后通过与数据层的通信获取需要的结果,再对结果进行处理返回给应用层。下述为更新一个customer的服务代码。为集中介绍Jersey框架实现,此处省略与之无关的业务处理。
  //从应用层获取customer对象,并返回影响的行数
  public int updateCustomer(Customer customer) {
  String sql="update customer set name='" + customer.getName() + "',addr='" + customer.getAddr() + "' where id='" + customer.getId() + "'";
  int count=CustomerDAO.noQueryDB(sql);
  return count;
  }
  3.4 Resource类
  在com.rest.resource包中建立Customers类,该类位于资源层。Jersey框架支持JAX-RS规范,采用一系列@符号开头的注释描述资源。限于篇幅,仅介绍更新某id的customer资源,无关操作省略,代码如下。
  public class Customers {
  private CustomerService customerService = new CustomerService ();
  getter and setter
  @PUT //用于更新操作的PUT请求,对于同样的URI,可
  //根据该注释进行路由选择,调用不同的方法
  @Path("customers /{id}") //定义资源的URI路径
  @Produces("application/json;charset=UTF-8") //定义请求的MIME格式为JSON
  @Consumes("application/json;charset=UTF-8") //定义响应的MIME格式为JSON
  //注释@PathParam表示路径参数,可以将请求的URI中的一部分作为参数传入方法
  public Customer updateCustomer(@PathParam("id") String id, Customer customer) {
  Customer cust = (Customer) getCustomerService().getCustomerById(id);
  if (cust == null) {
  throw new WebApplicationException(Response.status(Status.NOT_FOUND).build());
  } else {
  getCustomerService().updateCustomer(customer);
  return customer;
  }
  }
  }
  客户端与服务器的数据交换可以采取多种MIME格式,但在web应用中,人们常采用XML或JSON。因为两者都能较好地实现跨平台、跨系统交换数据。为统一数据格式,简化接口设计,XML和JSON成为数据交换的首选格式。然而,XML格式文件存储了大量的冗余信息,相对于JSON格式的文件需要占用更多的带宽。其次,对其进行解析相比JSON格式的文件更复杂[6]。因此,研究采用更为轻量级的JSON数据格式。在上述资源类中通过注释@Produces和@Consumes进行了声明。
  另外,在上述updateCustomer方法中可以看出,资源层能直接使用customer对象接收应用层传递来的JSON数据。这便是JAXB的@XmlRootElement注释的作用。JAX-RS集成了JAXB,能自动实现JSON数据与bean的相互转换,为数据传递提供了便捷手段。
  4 Web客户端实现
  虽然HTTP支持GET、POST、PUT、DELETE、OPTIONS、HEAD、TRACE、CONNECT八种请求方式,但目前流行的Web浏览器大多只支持其中的GET和POST方法。所以Rails采用一个虚拟的:method参数来模拟HTTP中的PUT和DELETE方法[7]。事实上,REST只是一种风格,怎样实现并没有统一规范。甚至直接将方法写在资源的URI中以区别四种请求也是允许的。不过这样的设计将简单的问题复杂化了,有违REST风格的设计初衷。文章则利用JQuery AJAX技术来提交GET、POST、PUT、DELETE请求。
  下面代码用于提交PUT请求,以访问更新某id的customer资源。   $.ajax({
  url: 'http://127.0.0.1:8080/RestDemo/customers/'+$("#id").val(),
  type: 'put', //指明数据提交方式为PUT,对应的操作是更新
  data: JSON.stringify(GetJsonData()), //自定义方法GetJsonData用于从Web页面获取需提交的数据,
  //并整理为JSON格式
  dataType: 'json', //服务器返回的数据类型
  contentType:'application/json',
  ……
  });
  然而此时请求资源还涉及跨域访问问题。解决跨域访问的方法也很多,研究采用非常简单的且被众多浏览器良好支持的CORS方法。为使代码分离,研究创建过滤器CorsFilter,在过滤器中进行访问权限的控制。具体做法是重写CorsFilter的父类Filter中的方法doFilter,在其中加入如下代码即可:
  resp.setHeader("Access-Control-Allow-Origin", "*");
  resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
  “Access-Control-Allow-Origin”表示允许访问的外部资源,“*”表示所有允许任何域进行访问。“Access-Control-Allow-Methods”则表示允许访问的方法类型。
  如此,以PUT方式访问URI:http://127.0.0.1:8080/RestDemo/customers/1,可实现id为1的customer的更新。
  由于研究涉及了跨域访问,因此在向服务器发送PUT请求前,客户端会首先发起OPTIONS请求。当服务端验证通过后,然后再正式发送PUT请求。节录PUT标头信息如下所示。
  (1)PUT请求头:
  PUT /RESTDemo/customers/1 HTTP/1.1
  Host: 127.0.0.1:8080
  Connection: keep-alive
  Accept: application/json, text/javascript, */*; q=0.01
  Origin: http://127.0.0.1:81
  Content-Type: application/json
  Referer: http://127.0.0.1:81/webclient/updatecustomer.html
  ……
  (2)PUT返回头:
  HTTP/1.1 200 OK
  Server: Apache-Coyote/1.1
  Access-Control-Allow-Origin: *
  Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
  Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With
  Content-Type: application/json;charset=UTF-8
  ……
  5 Android客户端实现
  Android利用HTTP访问网络资源的方式主要有两种,一种是使用HttpURLConnection,另一种是使用Apache HttpClient。然而Android从4.3开始取消了对HttpClient对象的支持。研究使用HttpURLConnection向服务端发送请求。限于篇幅,在Android客户端,文章也仅介绍如何发送PUT请求。
  首先创建一个线程,用于更新客户信息,然后重写run方法,代码如下。
  URL url = new URL("http://192.168.1.108:8080/RestDemo/customers/"+etId.getText());
  HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  String content=getContentToJson(etId.getText(),etName.getText(),etAddr.getText());
  connection.setDoOutput(true); //设置容许输出
  connection.setDoInput(true); //设置容许输入
  connection.setRequestMethod("PUT"); //设置请求方法为PUT
  connection.setUseCaches(false); //设置不使用缓存
  connection.setRequestProperty("Connection", "Keep-Alive"); //设置维持长连接
  connection.setRequestProperty("Content-Type", "application/json"); //设置文件类型
  connection.setRequestProperty("Content-Length", String.valueOf(content.getBytes().length));   OutputStream os = connection.getOutputStream();
  os.write(content.getBytes("utf-8"));
  os.flush();
  os.close();
  if (connection.getResponseCode() == 200) {
  //请求成功后的相关逻辑
  }
  connection.disconnect();
  如此,Android客户端亦可以PUT方式访问URI:http://127.0.0.1:8080/RestDemo/customers/1。
  6 总结与展望
  RESTful Web Service可以避免基于SOAP协议的Web Service复杂的协议集解析,更易于实现,更符合Web的本源,具有简单性、可寻址性以及缓存性等特性,服务器的开销和维护成本更低,同时方便更多的服务无缝地在桌面和手持式平台进行大规模部署。文章从理论上提出了解决基于Jersey框架创建RESTful Web Service时可能遇到的各种问题,并通过实践证明了解决方法的可行性。然而并不是所有web服务都适合采用REST风格,REST至今在成熟度和安全性等方面尚存在不足,还值得改进。这也是将来的课题应进一步研究的方向。
  参考文献
  [1] 吴昌雨,贾瑞玉.基于Grails框架的Web服务构建[J].滁州职业技术学院学报,2012,11(4):61.
  [2] Roy Thomas Fielding. Architectural Styles and the Design of Network——based Software Arehitectures[D/OL]. Irvine: UNIVERSITY OF CALIFORNIA, 2000. www.ics.uci.edu/~fielding/pubs/dissertation/top.htm.
  [3] SUBBU ALLAMARAJU.RESTful web services cookbook[M]. 丁雪丰,译.北京:电子工业出版社,011.
  [4] 王非,蔡勇,贺志军.RESTful Web Services 在信息系统中的应用[J].计算机系统应用,2013,22(2):221.
  [5] 谢玉开.基于JAX-RS的面向资源架构应用研究[D].杭州:浙江理工大学,2010.
  [6] 王晓禹,石丽.基于JSON实现Android智能终端与Web服务器“面向对象”的信息交换[J].数字技术与应用,2012,4:224-225.
  [7] 潘冰.面向资源的RESTfulWeb应用研究[J].微计算机应用,2010,31(7):39-40.
其他文献
[摘 要]公交站点是公共汽车交通系统的重要组成部分, 由于市民出行主要还是依赖公交车,因此,公交系统是否完善不仅与乘客息息相关,而且直接影响城市的发展。采用模糊综合评价法对米东区4号线公交乘客各站点上下客流量进行综合评价,在问卷调查的基础上进行数据分析。通过常规公交各站点上下客流分析体系的建立,在探讨公交沿线问题的基础上,对常规公共交通沿线的合理性起到良好的导向作用。  [关键词]公交系统 乌鲁木
期刊
[摘 要]火灾的发生不仅会在一定程度上破坏生态平衡,同时也会给人们的财产生命安全带来严重威胁。因此,不断加强消防安全管理工作是具有重要现实意义与社会意义的。作为一种在消防安全管理中新兴的消防管理模式,网格化管理模式能够为消防安全管理带来极大的便利,其优势是传统管理模式无法比拟的。也正因为如此,我们更应该加强对网格化消防安全管理模式的研究,以此来促进我国消防安全管理的持续发展。本文基于“网格化”的原
期刊
[摘 要]本文论述了专用铁路运输管理如何适应国铁大运输思想,提出内抓管理,外树形象,树立“安全发展、和谐服务、运输畅通”管理理念,构建和谐的内、外部运输环境,为确保企业主体运输畅通更好的服务。  [关键词]和谐 服务 运输管理 畅通  中图分类号:F532 文献标识码:A 文章编号:1009-914X(2016)02-0399-01  1、引言  随着我国国民经济建设的不断加快,铁路运输的瓶颈现象
期刊
[摘 要]新中国成立以来,我国科技事业与经济发展取得了辉煌的成就,不仅有多项科技成果问世,并且经济持续高速发展达三十年之久,万众瞩目。随着经济与科技的飞速发展,我国人民的生活水平日益改善,特别是改革开放以后,中国政府逐步开放了对人口流动的控制,大量农民工流向城市,加快了城市化的脚步,城市人口剧增,人们生活水平提高,但是同时也产生了一系列的问题,其中城市生活垃圾对环境的危害以及社会的危害日益加剧,对
期刊
[摘 要]蓄电池直流系统使用过程中,需要进行运行维护,以此保证系统能够征程使用。研究表明,如果蓄电池直流系统日常运行期间,时常测试与维护,使用寿命大大增加。蓄电池直流系统运行方式确定的介绍,分析了定值确定,在此基础上,提出了蓄电池直流系统运行维护方法,仅供参考借鉴。  [关键词]蓄电池直流系统 运行维护  中图分类号:TM 文献标识码:A 文章编号:1009-914X(2016)05-0002-0
期刊
中图分类号:TN949.292 文献标识码:A 文章编号:1009-914X(2016)02-0373-02  近几年来,用手机的人越来越多,而用座机(有线)的人却越来越少,特别是数以亿计的家庭废弃了座机,几乎人人用上了手机,为什么呢?在学习之余,我经常思索这一问题。今年暑期,在翻阅一些书籍和浏览大量网页的基础上,我先后走访了移动公司、电信公司和一些党政机关、企事业单位及30多名电话用户,对这一简
期刊
[摘 要]近年来,随着煤矿采深的不断加大,地应力大幅增加,因此很多煤矿都采取了留宽煤柱护巷的布置方式,但这种布置方式有很多明显缺点。本文根据枣泉煤矿地质现状,对140201大采高综采工作面小煤柱沿空掘巷进行了研究,现场试验效果良好,以供类似矿井参考。  [关键词]小煤柱 沿空掘巷 综采工作面 大采高  中图分类号:TD 文献标识码:A 文章编号:1009-914X(2016)05-0009-01 
期刊
[摘 要]一支优秀的运动队,不仅应该具有超人的运动技术水平,更应该具备过硬的思想作风,才能保证这支队伍在任何困难、复杂的局面下都能取得骄人的成绩,不辜负党和人民的培养和重托。做好新时期优秀运动队思想政治工作,是提高广大教练员、运动员思想道德素质,建设社会主义和谐社会的内在要求,因此任何时候都不能忽视运动队思想政治工作的重要作用。  [关键词]思想政治工作 运动队 竞技体育  中图分类号:G807.
期刊
中图分类号:TSl02.51 文献标识码:A 文章编号:1009-914X(2016)05-0008-01  腈纶,学名又称聚丙烯腈纤维,在我国还称为“人造羊毛”,在国外则称为“奥纶”、“开司米纶”。腈纶通常是指用85%以上的丙烯腈与第二和第三单体的共聚物,经湿法纺丝或干法纺丝制得的合成纤维。聚丙烯腈纤维可以用来制作套衫、毛毯、地毯、童装以及诸如旗布、遮阳篷等户外产品,在纺织上有很大的用处。腈纶在
期刊
[摘 要]建筑工程项目施工进行中,起重机械设备是必不可少的。但在实际使用过程中,建筑起重机械设备在各种因素影响下经常出现安全问题,这些问题对项目施工产生极大的影响。基于此,笔者结合实际工作经验,分析了建筑起重机械设备产生故障的原因,并针对性的给出了相应预防控制措施。希望可以为同行提供一定的借鉴,为推进行业发展贡献自己的一份力量。  [关键词]事故分析 故障原因 预控措施  中图分类号:TH 文献标
期刊