博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务(转载)
阅读量:4958 次
发布时间:2019-06-12

本文共 12265 字,大约阅读时间需要 40 分钟。

转载 http://www.ibm.com/developerworks/cn/web/wa-restful/index.html 

 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 与服务进行通信。

本部分提供了支持 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
method(HttpEntity
entity) {…}

参见 Spring 文档(参见 ) 获得可插入方法中的支持注释或对象的完整列表。

使用不同 MIME 类型表示同一资源是 RESTful web 服务的一个重要方面。通常,可以使用具有不同 "accept" HTTP 头的同一 URI 提取具有不同表示的资源。还可以使用不同的 URI 或具有不同请求参数的 URI。

“使用 Spring 3 构建 RESTful web 服务”(参见 )介绍了 ContentNegotiatingViewResolver,可以挑选不同的视图解析器处理同一 URI(具有不同的 accept 头)。因此,ContentNegotiatingViewResolver 可用于生成多个具象。

还有另一种方式可生成多具象 — 将 HttpMessageConverter 和 c@ResponseBody 注释结合起来使用。使用这种方法无需使用视图技术。

HTTP 请求和响应是基于文本的,意味着浏览器和服务器通过交换原始文本进行通信。但是,使用 Spring,controller 类中的方法返回纯 'String' 类型和域模型(或其他 Java 内建对象)。如何将对象序列化/反序列化为原始文本?这由 HttpMessageConverter 处理。Spring 具有捆绑实现,可满足常见需求。表 1 显示了一些示例。



使用...... 您可以......
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 服务。示例应用程序中使用的一些资源在 “使用 Spring 3 构建 RESTful web 服务”(参见 )中构建。还可以 示例代码。

首先,您必须配置 HttpMessageConverter。要生成多个具象,自定义几个 HttpMessageConverter 实例,以将对象转换为不同的媒体类型。此部分包括 JSON、ATOM 和 XML 媒体类型。

从最简单的示例开始。JSON 是一个轻量型的数据交换格式,人们可轻松地进行读取和编写。清单 1 显示了配置 JSON converter 的代码。




在配置中,注册了 3 个转换程序。MappingJacksonHttpMessageConverter 用于将对象转换为 JSON,反之亦然。此内置转换程序使用 Jackson 的 ObjectMapper 将 JSON 映射到 JavaBean,因此您必须将下列 Jackson JAR 文件添加到类路径。

  • org.codehaus.jackson.jar
  • org.codehaus.jackson.mapper.jar

下一步是编写一个方法,处理请求 JSON 具象的请求。清单 2 显示了详细信息。



@RequestMapping(method=RequestMethod.GET, value="/emp/{id}",  		headers="Accept=application/json") public @ResponseBody Employee getEmp(@PathVariable String id) { Employee e = employeeDS.get(Long.parseLong(id)); return e; } 	 @RequestMapping(method=RequestMethod.GET, value="/emps",  		headers="Accept=application/json") public @ResponseBody EmployeeListinggetAllEmp() { List
employees = employeeDS.getAll(); EmployeeListinglist = new EmployeeList(employees); return list; }

@ResponseBody 注释用于将返回对象(Employee 或 EmployeeList)变为响应的正文内容,将使用MappingJacksonHttpMessageConverter 将其映射到 JSON。

使用 HttpMessageConverter 和 @ResponseBody,您可以实现多个具象,而无需包含 Spring 的视图技术 — 这是使用ContentNegotiatingViewResolver 所不具有的一个优势。

现在您可以使用 CURL 或 REST Client Firefox 插件调用请求。记住添加一个 HTTP 头:Accept=application/json。清单 3 以 JSON 格式显示了所需的响应。



Response for /rest/service/emp/1 {"id":1,"name":"Huang Yi Ming","email":"huangyim@cn.ibm.com"}  Response for /rest/service/emps {"count":2, "employees":[ {"id":1,"name":"Huang Yi Ming","email":"huangyim@cn.ibm.com"}, {"id":2,"name":"Wu Dong Fei","email":"wudongf@cn.ibm.com"} ]}

Spring 的内置转换程序 MarshallingHttpMessageConverter 用于在对象和 XML (OXM) 之间进行映射。本示例使用 JAXB 2 作为转换程序的 marshaller/un-marshaller。清单 4 显示了配置。



dw.spring3.rest.bean.Employee
dw.spring3.rest.bean.EmployeeList

了解 JAXB 2 不能很好地支持 java.util.List<T> 到 XML 的映射很重要。常用实践是为对象集添加一个包装类。参见 “使用 Spring 3 构建 RESTful web 服务”(参见 )或  源代码,了解此 JAXB 注释类的详细信息。

在处理请求的控制器中的方法如何?回顾一下  中的代码。发现在此处不需要添加任何代码一点也不奇怪。您只需要在 Accept头中添加另一个支持的媒体类型,如下所示。

headers=”Accept=application/json, application/xml”

转换程序将对象正确地映射到请求的类型(JSON 或 XML)。清单 5 显示了请求 application/xml 具象的理想结果。



Response for /rest/service/emp/1 
huangyim@cn.ibm.com
1
Huang Yi Ming
Response for /rest/service/emps
2
huangyim@cn.ibm.com
1
Huang Yi Ming
wudongf@cn.ibm.com
2
Wu Dong Fei

ATOM 源是另一种在 RESTful web 服务中交换数据的常见格式。Atom 源文档是 Atom 源(包括有关源及与其相关的所有或部分项的元数据)的具象。其根是 atom:feed 元素。还有一个 ATOM Publish Protocol (APP) 定义交换格式和行为。(定义 ATOM 和 APP 格式不在本文的讨论范围内。参见  了解更多信息。)

本示例使用 AtomFeedHttpMessageConverter 转换 ATOM 源,利用 ROME ATOM API。因此,您必须在类路径中包含 JAR 文件 sun.syndication.jar。清单 6 显示了此转换程序的配置。




清单 7 显示了处理 ATOM 请求和源生成的代码。



@RequestMapping(method=RequestMethod.GET, value="/emps",  		headers="Accept=application/atom+xml") public @ResponseBody Feed getEmpFeed() { 	List
employees = employeeDS.getAll(); return AtomUtil.employeeFeed(employees, jaxb2Mashaller); } public static Feed employeeFeed( List
employees, Jaxb2Marshaller marshaller) { Feed feed = new Feed(); feed.setFeedType("atom_1.0"); feed.setTitle("Employee Atom Feed"); List
entries = new ArrayList
(); for(Employee e : employees) { StreamResult result = new StreamResult( new ByteArrayOutputStream()); marshaller.marshal(e, result); String xml = result.getOutputStream().toString(); Entry entry = new Entry(); entry.setId(Long.valueOf(e.getId()).toString()); entry.setTitle(e.getName()); Content content = new Content(); content.setType(Content.XML); content.setValue(xml); List
contents = new ArrayList
(); contents.add(content); entry.setContents(contents); entries.add(entry); } feed.setEntries(entries); return feed; }

在上述代码中,注意:

  • getEmpFeed() 方法将同一 URI 处理为 getAllEmp(),但具有不同的 Accept 头。
  • 使用 employeeFeed() 方法,您可以将 Employee 对象解析为 XML,然后将其添加到源项的 <content> 元素。

清单 8 显示了请求 URI /rest/service/emps 的 application/atom+xml 具象时的输出。



Employee Atom Feed
Huang Yi Ming
1
huangyim@cn.ibm.com
1
Huang Yi Ming
Wu Dong Fei
2
wudongf@cn.ibm.com
2
Wu Dong Fei

目前为止,示例已实现了几个处理 HTTP GET 方法的方法。清单 9 显示了 POSTPUT 和 DELETE 方法的实现。



@RequestMapping(method=RequestMethod.POST, value="/emp") public @ResponseBody Employee addEmp(@RequestBody Employee e) { employeeDS.add(e); return e; } 	 @RequestMapping(method=RequestMethod.PUT, value="/emp/{id}") public @ResponseBody Employee updateEmp( 	@RequestBody Employee e, @PathVariable String id) { employeeDS.update(e); return e; } 	 @RequestMapping(method=RequestMethod.DELETE, value="/emp/{id}") public @ResponseBody void removeEmp(@PathVariable String id) { employeeDS.remove(Long.parseLong(id)); }

@RequestBody 注释在 addEmp() 和 updateEmp() 方法中使用。它接收 HTTP 请求正文并试图使用注册的 HttpMessageConverter 将其转换为对象类。在下一部分中,您将使用 RestTemplate 与这些服务进行通信。

“使用 Spring 3 构建 RESTful web 服务”(参见 )介绍了如何使用 CURL 和 REST 客户端测试 REST 服务。从编程水平上讲,Jakarta Commons HttpClient 通常用于完成此测试(但这不在本文的讨论范围中)。您还可以使用名为 RestTemplate 的 Spring REST 客户端。从概念上讲,它与 Spring 中的其他模板类相似,比如 JdbcTemplate 和 JmsTemplate

RestTemplate 还使用 HttpMessageConverter。您可以将对象类传入请求并使转换程序处理映射。

清单 10 显示了 RestTemplate 的配置。它还使用之前介绍的 3 个转换程序。




本文中的示例仅使用了一些可简化服务器之间通信的方法。RestTemplate支持其他方法,包括:

  • exchange:使用请求正文执行一些 HTTP 方法并获得响应。
  • getForObject:执行 HTTP GET 方法并将响应作为对象获得。
  • postForObject:使用特定请求正文执行 HTTP POST 方法。
  • put:使用特定请求正文执行 HTTP PUT 方法。
  • delete:执行 HTTP DELETE方法以获得特定 URI。

下列代码示例帮助阐述如何使用 RestTemplate。参见 RestTemplate API(参见 )获得使用的 API 的详细说明。

清单 11 显示如何将头添加到请求中,然后调用请求。使用 MarshallingHttpMessageConverter 您可以获得响应并将其转换为类型类。可以使用不同的媒体类型测试其他具象。



HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_XML); HttpEntity
entity = new HttpEntity
(headers); ResponseEntity
response = restTemplate.exchange( "http://localhost:8080/rest/service/emps", HttpMethod.GET, entity, EmployeeList.class); EmployeeListingemployees = response.getBody(); // handle the employees

清单 12 显示了如何将新员工发布到服务器。服务器端服务 addEmp() 可接受媒体类型为 application/xml 和 application/json 的数据。



Employee newEmp = new Employee(99, "guest", "guest@ibm.com"); HttpEntity
entity = new HttpEntity
(newEmp); ResponseEntity
response = restTemplate.postForEntity( "http://localhost:8080/rest/service/emp", entity, Employee.class); Employee e = response.getBody(); // handle the employee

清单 13 显示了如何 PUT 修改的员工以更新旧员工。它还显示了可用作请求 URI 占位符({id})的功能。



Employee newEmp = new Employee(99, "guest99", "guest99@ibm.com"); HttpEntity
entity = new HttpEntity
(newEmp); restTemplate.put( "http://localhost:8080/rest/service/emp/{id}", entity, "99");

清单 14 显示了如何 DELETE 现有员工。



restTemplate.delete( 	"http://localhost:8080/rest/service/emp/{id}", "99");

在本篇文章中,您学习了 Spring 3 中引入的 HttpMessageConverter。它提供了对多具象的客户端和服务器端支持。使用提供的 ,您可以探索本文中的 HttpMessageConverter 实现和使用 “使用 Spring 3 构建 RESTful web 服务” 中的ContentNegotiatingViewResolver 实现之间的差异。


下载

描述 名字 大小 下载方法
文章源代码 src_code.zip 11KB


学习

  • 随附文章 “”(developerWorks,2010 年 7 月)介绍了构建 RESTful web 服务的 Spring 方式。
  • 在 Wikipedia 上了解  及其相关链接。
  • 浏览  以很好地了解技术的作用。它包括一个示例项目,以及支持的幻灯片演示和示范视频。
  • 全面了解 。
  • 了解有关  的更多信息。
  • 全面了解 。
  • 探索 ,一个 Atom/RSS Java 实用工具集,可与大多数联合格式一起在 Java 中使用。
  • 了解有关  的更多信息。
  • 阅读 developerWorks 系列 “”(2006 年 10 月)获得协议概述及其基本操作和功能。
  • 了解 ,快速开源 JSON 处理器。
  • :通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。
  • :这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
  • ,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过  栏目,迅速了解 Web 2.0 的相关概念。

获得产品和技术

  • 获取最新  发行版。
  • 下载  或  ,并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。

转载于:https://www.cnblogs.com/chenying99/archive/2012/06/07/2540613.html

你可能感兴趣的文章
保险购买方式
查看>>
SQL - 2.基础语法
查看>>
【CodeChef PREFIXOR】Prefix XOR
查看>>
浅谈CSRF攻击方式
查看>>
转: 利用RabbitMQ、MySQL实现超大用户级别的消息在/离线收发
查看>>
144. Binary Tree Preorder Traversal (Tree, Stack)
查看>>
使用cookie保存用户名和密码
查看>>
Java-Shiro(四):Shiro
查看>>
NOJ 1163 活动安排问题 [动态规划]
查看>>
CentOS7源码安装qbittorrent最新版本
查看>>
不用任何图片,只用简单的css写出唯美的钟表,就问你行吗?
查看>>
超时时间已到。在操作完成之前超时时间已过或服务器未响应
查看>>
kuangbin带你飞系列----poj3278 Catch That Cow
查看>>
centos6 php5.4 升級到php 5.6
查看>>
Dynamic SQL Using OPEN FOR in Oracle PL/SQL
查看>>
windows下的mysql迁移到linux下
查看>>
Exercise 3.4 A calculator that allows multiple calculations
查看>>
vs2010打开vs2012的sln文件
查看>>
yii2引入css和js文件
查看>>
POJ 1198 / HDU 1401 Solitaire (记忆化搜索+meet in middle)
查看>>