使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务
原文地址:http://www.ibm.com/developerworks/cn/web/wa-restful/
简介: Spring,构建 Java™ 平台和 Enterprise Edition (Java EE) 应用程序的著名框架,现在在其模型-视图-控制器(Model-View-Controller ,MVC)层支持具象状态传输 (REST)。RESTful web 服务根据客户端请求生成多个具象(representations)很重要。在本篇文章中,学习使用 HttpMessageConverter
生成多个具象。代码示例展示如何使用RestTemplate
和 HttpMessageConverter
与服务进行通信。此外,还将学习如何使用 Spring API 和注释构建 RESTful web 服务,生成常见具象,比如 ATOM Feed、XML 和 JavaScript Object Notation (JSON)。
简介
随附文章,“使用 Spring 3 构建 RESTful web 服务”(参见 参考资料),介绍了使用 Spring 构建 RESTful web 服务的方式。还解释了如何使用 ContentNegotiatingViewResolver
生成多个具象,这是 RESTful web 服务的一个重要功能。本文还阐述了使用HttpMessageConverter
生成多个具象的另一种方式,并且本文中的示例展示了如何使用 RestTemplate
和HttpMessageConverter
与服务进行通信。
Spring MVC 中的 REST 支持
本部分提供了支持 RESTful web 服务的主要 Spring 功能(或注释)的概述。
@Controller
- 使用
@Controller
注释对将成为 MVC 中控制器的类进行注释并处理 HTTP 请求。 @RequestMapping
- 使用
@RequestMapping
注释对函数进行注释,该函数处理某些 HTTP 方法、URI 或 HTTP 头。此注释是 Spring REST 支持的关键。可以更改method
参数以处理其他 HTTP 方法。例如:
@RequestMapping(method=RequestMethod.GET, value="/emps",
headers="Accept=application/xml, application/json") @PathVariable
- 使用
@PathVariable
注释可将 URI 中的路径变量作为参数插入。例如:
@RequestMapping(method=RequestMethod.GET, value="/emp/{id}")
public ModelAndView getEmployee(@PathVariable String id) { … } - 其他有用的注释
- 使用
@RequestParam
将 URL 参数插入方法中。使用
@RequestHeader
将某一 HTTP 头插入方法中。使用
@RequestBody
将 HTTP 请求正文插入方法中。使用
@ResponseBody
将内容或对象作为 HTTP 响应正文返回。使用
HttpEntity<T>
将它自动插入方法中,如果将它作为参数提供。使用
ResponseEntity<T>
返回具有自定义状态或头的 HTTP 响应。例如:
public @ResponseBody Employee getEmployeeBy(@RequestParam("name")
String name, @RequestHeader("Accept") String accept, @RequestBody String body) {…}
public ResponseEntity<String> method(HttpEntity<String> entity) {…}参见 Spring 文档(参见 参考资料) 获得可插入方法中的支持注释或对象的完整列表。
多具象支持
使用不同 MIME 类型表示同一资源是 RESTful web 服务的一个重要方面。通常,可以使用具有不同 "accept" HTTP 头的同一 URI 提取具有不同表示的资源。还可以使用不同的 URI 或具有不同请求参数的 URI。
“使用 Spring 3 构建 RESTful web 服务”(参见 参考资料)介绍了 ContentNegotiatingViewResolver
,可以挑选不同的视图解析器处理同一 URI(具有不同的 accept 头)。因此,ContentNegotiatingViewResolver
可用于生成多个具象。
还有另一种方式可生成多具象 — 将 HttpMessageConverter
和 c@ResponseBody
注释结合起来使用。使用这种方法无需使用视图技术。
HttpMessageConverter
HTTP 请求和响应是基于文本的,意味着浏览器和服务器通过交换原始文本进行通信。但是,使用 Spring,controller 类中的方法返回纯 'String' 类型和域模型(或其他 Java 内建对象)。如何将对象序列化/反序列化为原始文本?这由HttpMessageConverter
处理。Spring 具有捆绑实现,可满足常见需求。表 1 显示了一些示例。
表 1. HttpMessageConverter 示例
使用...... | 您可以...... |
---|---|
StringHttpMessageConverter | 从请求和响应读取/编写字符串。默认情况下,它支持媒体类型 text/* 并使用文本/无格式内容类型编写。 |
FormHttpMessageConverter | 从请求和响应读取/编写表单数据。默认情况下,它读取媒体类型 application/x-www-form-urlencoded 并将数据写入 MultiValueMap<String,String>。 |
MarshallingHttpMessageConverter | 使用 Spring 的 marshaller/un-marshaller 读取/编写 XML 数据。它转换媒体类型为 application/xml 的数据。 |
MappingJacksonHttpMessageConverter | 使用 Jackson 的 ObjectMapper 读取/编写 JSON 数据。它转换媒体类型为 application/json 的数据。 |
AtomFeedHttpMessageConverter | 使用 ROME 的 Feed API 读取/编写 ATOM 源。它转换媒体类型为 application/atom+xml 的数据。 |
RssChannelHttpMessageConverter | 使用 ROME 的 feed API 读取/编写 RSS 源。它转换媒体类型为 application/rss+xml 的数据。 |
构建 RESTful web 服务
在此部分中,学习构建可生成多个具象的简单 RESTful web 服务。示例应用程序中使用的一些资源在 “使用 Spring 3 构建 RESTful web 服务”(参见 参考资料)中构建。还可以 下载示例代码。
首先,您必须配置 HttpMessageConverter
。要生成多个具象,自定义几个 HttpMessageConverter
实例,以将对象转换为不同的媒体类型。此部分包括 JSON、ATOM 和 XML 媒体类型。
JSON
从最简单的示例开始。JSON 是一个轻量型的数据交换格式,人们可轻松地进行读取和编写。清单 1 显示了配置 JSON converter 的代码。
清单 1. 配置 rest-servlet.xml 中的 HttpMessageConverter
<bean class="org.springframework.web.servlet.mvc.annotation |
在配置中,注册了 3 个转换程序。MappingJacksonHttpMessageConverter
用于将对象转换为 JSON,反之亦然。此内置转换程序使用 Jackson 的 ObjectMapper
将 JSON 映射到 JavaBean,因此您必须将下列 Jackson JAR 文件添加到类路径。
- org.codehaus.jackson.jar
- org.codehaus.jackson.mapper.jar
下一步是编写一个方法,处理请求 JSON 具象的请求。清单 2 显示了详细信息。
清单 2. 处理在 EmployeeController 中定义的 JSON 请求
@RequestMapping(method=RequestMethod.GET, value="/emp/{id}", |
@ResponseBody
注释用于将返回对象(Employee
或 EmployeeList
)变为响应的正文内容,将使用MappingJacksonHttpMessageConverter
将其映射到 JSON。
使用 HttpMessageConverter
和 @ResponseBody
,您可以实现多个具象,而无需包含 Spring 的视图技术 — 这是使用ContentNegotiatingViewResolver
所不具有的一个优势。
现在您可以使用 CURL 或 REST Client Firefox 插件调用请求。记住添加一个 HTTP 头:Accept=application/json
。清单 3 以 JSON 格式显示了所需的响应。
清单 3. getEmp() 和 getAllEmp() 的 JSON 结果
Response for /rest/service/emp/1 |
XML
Spring 的内置转换程序 MarshallingHttpMessageConverter
用于在对象和 XML (OXM) 之间进行映射。本示例使用 JAXB 2 作为转换程序的 marshaller/un-marshaller。清单 4 显示了配置。
清单 4. 配置 MarshallingHttpMessageConverter
<bean id="marshallingConverter" |
了解 JAXB 2 不能很好地支持 java.util.List<T> 到 XML 的映射很重要。常用实践是为对象集添加一个包装类。参见 “使用 Spring 3 构建 RESTful web 服务”(参见 参考资料)或 下载 源代码,了解此 JAXB 注释类的详细信息。
在处理请求的控制器中的方法如何?回顾一下 清单 2 中的代码。发现在此处不需要添加任何代码一点也不奇怪。您只需要在Accept
头中添加另一个支持的媒体类型,如下所示。
headers=”Accept=application/json, application/xml” |
转换程序将对象正确地映射到请求的类型(JSON 或 XML)。清单 5 显示了请求 application/xml 具象的理想结果。
清单 5. getEmp() 和 getAllEmp() 的 XML 结果
Response for /rest/service/emp/1 |
ATOM 源
ATOM 源是另一种在 RESTful web 服务中交换数据的常见格式。Atom 源文档是 Atom 源(包括有关源及与其相关的所有或部分项的元数据)的具象。其根是 atom:feed
元素。还有一个 ATOM Publish Protocol (APP) 定义交换格式和行为。(定义 ATOM 和 APP 格式不在本文的讨论范围内。参见 参考资料 了解更多信息。)
本示例使用 AtomFeedHttpMessageConverter
转换 ATOM 源,利用 ROME ATOM API。因此,您必须在类路径中包含 JAR 文件 sun.syndication.jar。清单 6 显示了此转换程序的配置。
清单 6. 配置 AtomFeedHttpMessageConverter
<bean id="atomConverter" |
清单 7 显示了处理 ATOM 请求和源生成的代码。
清单 7. EmployeeController & AtomUtil 类中的 getEmpFeed()
@RequestMapping(method=RequestMethod.GET, value="/emps", |
在上述代码中,注意:
getEmpFeed()
方法将同一 URI 处理为getAllEmp()
,但具有不同的Accept
头。- 使用
employeeFeed()
方法,您可以将Employee
对象解析为 XML,然后将其添加到源项的<content>
元素。
清单 8 显示了请求 URI /rest/service/emps 的 application/atom+xml 具象时的输出。
清单 8. 请求 application/atom+xml 时的 /rest/service/emps 输出
<?xml version="1.0" encoding="UTF-8"?> |
实现 POST、PUT 和 DELETE
目前为止,示例已实现了几个处理 HTTP GET
方法的方法。清单 9 显示了 POST
、PUT
和 DELETE
方法的实现。
清单 9. EmployeeController 中的 POST、PUT 和 DELETE 方法
@RequestMapping(method=RequestMethod.POST, value="/emp") |
@RequestBody
注释在 addEmp()
和 updateEmp()
方法中使用。它接收 HTTP 请求正文并试图使用注册的HttpMessageConverter
将其转换为对象类。在下一部分中,您将使用 RestTemplate
与这些服务进行通信。
使用 RestTemplate 与 REST 服务进行通信
“使用 Spring 3 构建 RESTful web 服务”(参见 参考资料)介绍了如何使用 CURL 和 REST 客户端测试 REST 服务。从编程水平上讲,Jakarta Commons HttpClient 通常用于完成此测试(但这不在本文的讨论范围中)。您还可以使用名为 RestTemplate
的 Spring REST 客户端。从概念上讲,它与 Spring 中的其他模板类相似,比如 JdbcTemplate
和 JmsTemplate
。
RestTemplate
还使用 HttpMessageConverter
。您可以将对象类传入请求并使转换程序处理映射。
配置 RestTemplate
清单 10 显示了 RestTemplate
的配置。它还使用之前介绍的 3 个转换程序。
清单 10. 配置 RestTemplate
<bean id="restTemplate" |
本文中的示例仅使用了一些可简化服务器之间通信的方法。RestTemplate
支持其他方法,包括:
exchange
:使用请求正文执行一些 HTTP 方法并获得响应。getForObject
:执行 HTTPGET
方法并将响应作为对象获得。postForObject
:使用特定请求正文执行 HTTPPOST
方法。put
:使用特定请求正文执行 HTTPPUT
方法。delete
:执行 HTTPDELETE
方法以获得特定 URI。
代码示例
下列代码示例帮助阐述如何使用 RestTemplate
。参见 RestTemplate API(参见 参考资料)获得使用的 API 的详细说明。
清单 11 显示如何将头添加到请求中,然后调用请求。使用 MarshallingHttpMessageConverter
您可以获得响应并将其转换为类型类。可以使用不同的媒体类型测试其他具象。
清单 11. XML 具象请求
HttpHeaders headers = new HttpHeaders(); |
清单 12 显示了如何将新员工发布到服务器。服务器端服务 addEmp()
可接受媒体类型为 application/xml 和 application/json 的数据。
清单 12. 发布新员工
Employee newEmp = new Employee(99, "guest", "guest@ibm.com"); |
清单 13 显示了如何 PUT 修改的员工以更新旧员工。它还显示了可用作请求 URI 占位符({id}
)的功能。
清单 13. PUT 以更新员工
Employee newEmp = new Employee(99, "guest99", "guest99@ibm.com"); |
清单 14 显示了如何 DELETE 现有员工。
清单 14. DELETE 现有员工
restTemplate.delete( |
结束语
在本篇文章中,您学习了 Spring 3 中引入的 HttpMessageConverter
。它提供了对多具象的客户端和服务器端支持。使用提供的 源代码,您可以探索本文中的 HttpMessageConverter
实现和使用 “使用 Spring 3 构建 RESTful web 服务” 中的ContentNegotiatingViewResolver
实现之间的差异。
下载
描述 | 名字 | 大小 | 下载方法 |
---|---|---|---|
文章源代码 | src_code.zip | 11KB | HTTP |
参考资料
学习
- 随附文章 “使用 Spring 3 来创建 RESTful Web Services”(developerWorks,2010 年 7 月)介绍了构建 RESTful web 服务的 Spring 方式。
- 在 Wikipedia 上了解 REST 及其相关链接。
- 浏览 Spring MVC showcase 以很好地了解技术的作用。它包括一个示例项目,以及支持的幻灯片演示和示范视频。
- 全面了解 Spring 3。
- 了解有关 RestTemplate API 的更多信息。
- 全面了解 JAXB Reference Implementation Project。
- 探索 ROME,一个 Atom/RSS Java 实用工具集,可与大多数联合格式一起在 Java 中使用。
- 了解有关 ATOM 的更多信息。
- 阅读 developerWorks 系列 “认识 Atom 发布协议,第 1 部分: 使用 Atom 发布协议创建和编辑 Web 资源”(2006 年 10 月)获得协议概述及其基本操作和功能。
- 了解 Jackson,快速开源 JSON 处理器。
- developerWorks Web development 专区:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。
- developerWorks Ajax 资源中心:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
- developerWorks Web 2.0 资源中心,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过 Web 2.0 新手入门 栏目,迅速了解 Web 2.0 的相关概念。
获得产品和技术
- 获取最新 Spring 发行版。
- 下载 Jackson。
- 下载 IBM 产品评估试用版软件 或 IBM SOA 人员沙箱 ,并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
讨论
- 现在就创建您的 developerWorks 社区 个人档案 并设置一个关于 OSGi 的 关注清单。连接到 developerWorks 社区 并保持连接。
- 找到 对 web 开发感兴趣的其他 developerWorks 成员。
- Web 开发人员,请在 web 开发群组中分享您的经验和知识。
- 分享您的知识:加入一个关注 web 主题的 developerWorks 群组。
- Roland Barcia 撰写的关于 Web 2.0 和中间件 的博客。
- 关注 developerWorks 成员 关于 web 主题的共享书签。
- 快速解答:访问 Web 2.0 Apps 论坛。
使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务的更多相关文章
- SpringBoot实战(十)之使用Spring Boot Actuator构建RESTful Web服务
一.导入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http ...
- 用于构建 RESTful Web 服务的多层架构
作者:Bruce Sun, Java 架构师, IBM 出处:http://www.ibm.com/developerworks/cn/web/wa-aj-multitier/ 用于构建 RESTfu ...
- Guzzle – 构建 RESTful Web 服务的 PHP HTTP 框架
Guzzle 减轻了发送 HTTP 请求和创建 Web 服务客户端的痛苦.它包含建立一个强大的网络服务客户端的工具,包括:服务描述定义的输入和输出的 API,资源迭代器遍历分页资源,尽可能有效地发送大 ...
- 基于jersey和Apache Tomcat构建Restful Web服务(一)
基于jersey和Apache Tomcat构建Restful Web服务(一) 现如今,RESTful架构已然成为了最流行的一种互联网软件架构,它结构清晰.符合标准.易于理解.扩展方便,所以得到越来 ...
- 使用 Jersey 和 Apache Tomcat 构建 RESTful Web 服务
作者: Yi Ming Huang, 软件工程师, IBM Dong Fei Wu, 软件工程师, IBM Qing Guo, 软件工程师, IBM 出处: http://www.ibm.com/de ...
- 基于jersey和Apache Tomcat构建Restful Web服务(二)
基于jersey和Apache Tomcat构建Restful Web服务(二) 上篇博客介绍了REST以及Jersey并使用其搭建了一个简单的“Hello World”,那么本次呢,再来点有趣的东西 ...
- 使用 RestEasy 和 Apache Tomcat 构建 RESTful Web 服务
第一次,用这个RestEasy框架,用的时候,总是提示,404的错误,郁闷,呵呵,不过经过努力,终于解决问题,特别留个标记. 关于404的错误,上网找了一大堆,也还不行. 我感觉应该是lib下面架包的 ...
- Yii2高速构建RESTful Web服务功能简单介绍
Yii2相比Yii1而言,一个重大的改进是内置了功能完备的RESTful支持. 其内置RESTful支持提供了例如以下功能: 使用ActiveRecord的通用接口来高速构建原型: 应答格式协商(缺省 ...
- [译]Spring Boot 构建一个RESTful Web服务
翻译地址:https://spring.io/guides/gs/rest-service/ 构建一个RESTful Web服务 本指南将指导您完成使用spring创建一个“hello world”R ...
随机推荐
- ubuntu装机
备份: .bashrc profile .vimrc exports defults/ 各种workspace中的源码 goagent/ 重转后安装: apt-get install openjdk- ...
- Jquery attr()方法 属性赋值和属性获取
jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式. 1. attr(属性名 ...
- How to change data dir of mysql?
# 1 copy orgin data dir of mysql to new one cp -R /var/lib/mysql /mysqldata chown mysql:mysql -R /my ...
- hdu4638Group
http://acm.hdu.edu.cn/showproblem.php?pid=4638 求某一区间所包含的连续的段 对于乱序的数 到了i这个数所包含的段数 首先把这个数看作单独的段 再看一下前面 ...
- Is there a way for me to run Adb shell as root without typing in 'su'?
Orginal artical :http://android.stackexchange.com/questions/5884/is-there-a-way-for-me-to-run-adb-sh ...
- CodeForces Round #286 Div.2
A. Mr. Kitayuta's Gift (枚举) 题意: 给一个长度不超过10的串,问能否通过插入一个字符使得新串成为回文串. 分析: 因为所给的串很多,所以可以枚举 “在哪插入” 和 “插入什 ...
- 三个流行MySQL分支的对比
MySQL是历史上最受欢迎的免费开源程序之一.它是成千上万个网站的数据库骨干,并且可以将它(和Linux)作为过去10年里Internet呈指数级增长的一个有力证明. 那么,如果MySQL真的这么重要 ...
- 【转】Cocos2d-x 弹出对话框的设计与实现
转自:http://www.tairan.com/archives/4854 我们时常需要这么些功能,弹出一个层,给与用户一些提示,这也是一种模态窗口,在没有对当前对话框进行确认的时候,不能继续往下操 ...
- 学习面试题Day09
一.Java基础部分 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相 ...
- Hibernate4.x之Session--常用方法
接上篇文章继续学习Hibernate的Session(http://www.cnblogs.com/dreamfree/p/4111777.html) 持久化对象的状态; 站在持久化的角度,Hiber ...