本部分提供了支持 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
.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
<ref bean="marshallingConverter" />
<ref bean="atomConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter"
class="org.springframework.http.converter.json
.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
在配置中,注册了 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}",
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<Employee> 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 格式显示了所需的响应。
清单 3. getEmp() 和 getAllEmp() 的 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"}
]}
XML
Spring 的内置转换程序 MarshallingHttpMessageConverter 用于在对象和 XML (OXM) 之间进行映射。本示例使用 JAXB 2 作为转换程序的 marshaller/un-marshaller。清单 4 显示了配置。
清单 4. 配置 MarshallingHttpMessageConverter
<bean id="marshallingConverter"
class="org.springframework.http.converter.xml
.MarshallingHttpMessageConverter">
<constructor-arg ref="jaxbMarshaller" />
<property name="supportedMediaTypes" value="application/xml"/>
</bean>
<bean id="jaxbMarshaller"
class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>dw.spring3.rest.bean.Employee</value>
<value>dw.spring3.rest.bean.EmployeeList</value>
</list>
</property>
</bean>
了解 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
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
<email>huangyim@cn.ibm.com</email>
<id>1</id>
<name>Huang Yi Ming</name>
</employee>
Response for /rest/service/emps
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employees>
<count>2</count>
<employee>
<email>huangyim@cn.ibm.com</email>
<id>1</id>
<name>Huang Yi Ming</name>
</employee>
<employee>
<email>wudongf@cn.ibm.com</email>
<id>2</id><name>Wu Dong Fei</name>
</employee>
</employees>
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"
class="org.springframework.http.converter.feed
.AtomFeedHttpMessageConverter">
<property name="supportedMediaTypes" value="application/atom+xml" />
</bean>
清单 7 显示了处理 ATOM 请求和源生成的代码。
清单 7. EmployeeController & AtomUtil 类中的 getEmpFeed()
@RequestMapping(method=RequestMethod.GET, value="/emps",
headers="Accept=application/atom+xml")
public @ResponseBody Feed getEmpFeed() {
List<Employee> employees = employeeDS.getAll();
return AtomUtil.employeeFeed(employees, jaxb2Mashaller);
}
public static Feed employeeFeed(
List<Employee> employees, Jaxb2Marshaller marshaller) {
Feed feed = new Feed();
feed.setFeedType("atom_1.0");
feed.setTitle("Employee Atom Feed");
List<Entry> entries = new ArrayList<Entry>();
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<Content> contents = new ArrayList<Content>();
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 具象时的输出。
清单 8. 请求 application/atom+xml 时的 /rest/service/emps 输出
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Employee Atom Feed</title>
<entry>
<title>Huang Yi Ming</title>
<id>1</id>
<content type="xml">
<employee>
<email>huangyim@cn.ibm.com</email>
<id>1</id>
<name>Huang Yi Ming</name>
</employee>
</content>
</entry>
<entry>
<title>Wu Dong Fei</title>
<id>2</id>
<content type="xml">
<employee>
<email>wudongf@cn.ibm.com</email>
<id>2</id>
<name>Wu Dong Fei</name>
</employee>
</content>
</entry>
</feed>
实现 POST、PUT 和 DELETE
目前为止,示例已实现了几个处理 HTTP GET 方法的方法。清单 9 显示了 POST、PUT 和 DELETE 方法的实现。
清单 9. EmployeeController 中的 POST、PUT 和 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 与这些服务进行通信。
回页首
使用 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"
class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<ref bean="marshallingConverter" />
<ref bean="atomConverter" />
<ref bean="jsonConverter" />
</list>
</property>
</bean>
本文中的示例仅使用了一些可简化服务器之间通信的方法。RestTemplate支持其他方法,包括:
exchange:使用请求正文执行一些 HTTP 方法并获得响应。
getForObject:执行 HTTP GET 方法并将响应作为对象获得。
postForObject:使用特定请求正文执行 HTTP POST 方法。
put:使用特定请求正文执行 HTTP PUT 方法。
delete:执行 HTTP DELETE方法以获得特定 URI。
代码示例
下列代码示例帮助阐述如何使用 RestTemplate。参见 RestTemplate API(参见 参考资料)获得使用的 API 的详细说明。
清单 11 显示如何将头添加到请求中,然后调用请求。使用 MarshallingHttpMessageConverter 您可以获得响应并将其转换为类型类。可以使用不同的媒体类型测试其他具象。
清单 11. XML 具象请求
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<EmployeeList> 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 的数据。
清单 12. 发布新员工
Employee newEmp = new Employee(99, "guest", "guest@ibm.com");
HttpEntity<Employee> entity = new HttpEntity<Employee>(newEmp);
ResponseEntity<Employee> response = restTemplate.postForEntity(
"http://localhost:8080/rest/service/emp", entity, Employee.class);
Employee e = response.getBody();
// handle the employee
清单 13 显示了如何 PUT 修改的员工以更新旧员工。它还显示了可用作请求 URI 占位符({id})的功能。
清单 13. PUT 以更新员工
Employee newEmp = new Employee(99, "guest99", "guest99@ibm.com");
HttpEntity<Employee> entity = new HttpEntity<Employee>(newEmp);
restTemplate.put(
"http://localhost:8080/rest/service/emp/{id}", entity, "99");
清单 14 显示了如何 DELETE 现有员工。
清单 14. DELETE 现有员工
restTemplate.delete(
"http://localhost:8080/rest/service/emp/{id}", "99");
结束语
在本篇文章中,您学习了 Spring 3 中引入的 HttpMessageConverter。它提供了对多具象的客户端和服务器端支持。使用提供的 源代码,您可以探索本文中的 HttpMessageConverter 实现和使用 “使用 Spring 3 构建 RESTful web 服务” 中的 ContentNegotiatingViewResolver 实现之间的差异。
相关推荐
Spring MVC REST Demo
使用Spring MVC创建REST服务简单例子
使用Spring MVC 搭建Rest服务 文档
spring mvc 包括 实现各种结构url 和get post 方式 跳转传参 提交等实例,有注释 是初学springmvc 必备入门级 参考.只需5分钟,看了代码就能让你掌握 spring mvc rest 的各种实现
使用Spring MVC3基于注解的形式实现的REST小例子 部署运行: 1. 将工程导入eclipse 2. 添加tomcat属性 工程(右键)——> tomcat project——> update context 3. 启动tomcat 4. 在浏览器中输入...
spring mvc基础开发 最基础类 一目了然 适合初学者
该实例展示了 spring3 REST 的使用方法,以及同一种内容,多种不同方式展示的实现,例如同一 User 信息,可以展示为:xml,json,html三种不同的格式。可以参考这篇文章:http://badqiu.javaeye.com/blog/552806
运行好,调试好的spring3.0 mvc_rest_demo.war ****************************** * 运行说明 ****************************** 1. 直接部署dist/springmvc_rest_demo.war至tomcat并启动服务器 2. 访问...
使用Spring MVC 构建RESTFul 风格的开发DEMO,
通过spring 3.0 的mvc 实现rest功能,代码是myeclipse工程,包括依赖包
本书由浅入深地介绍了当今流行的Java Web框架Spring MVC的方方面面,从基础的环境搭建到微服务设计与架构,再到持久化、REST API构建、认证与测试……涵盖了Spring MVC诸多重要且常用的特性。值得一提的是,本书针对...
Spring3MVC-REST-HelloWorld 实例简单代码
NULL 博文链接:https://am-wj.iteye.com/blog/1774212
NULL 博文链接:https://leiwuluan.iteye.com/blog/1539767
《Spring MVC 3.0实战指南》,参考《Spring 3.x企业应用开发实战》。 内容简介: 1、Spring MVC框架简介 2、HTTP请求地址映射 3、HTTP请求数据的绑定 4、数据转换、格式化、校验 5、数据模型控制 6、视图及解析器 7...
SPRING-MVC-MQ-CXF-REST_Demo
Table of Contents Configuring a Spring Development Environment ...REST and AJAX Resolving and Implementing Views Testing Spring MVC Applications Spring Web Flow Building Applications with Spring Web...
NULL 博文链接:https://zhaoshijie.iteye.com/blog/1036041
◆全面的REST支持:在Spring MVC中天然支持REST,如REST式的请求映射,URI变量提取等。 ◆富Portlet 2.0支持:Spring MVC完全支持Portlet 2.0环境以及Portlet 2.0中新的事件与资源请求模型。 ◆对象/XML映射(OXM...
使用Rest Assured和Mockmvc进行Spring mvc集成测试.zip