首页 > 其他分享 >使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务(转)

使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务(转)

时间:2023-08-04 17:06:04浏览次数:49  
标签:web HttpMessageConverter Spring Employee 使用 清单 id


Spring,构建 Java™ 平台和 Enterprise Edition (Java EE) 应用程序的著名框架,现在在其模型-视图-控制器(Model-View-Controller ,MVC)层支持具象状态传输 (REST)。RESTful web 服务根据客户端请求生成多个具象(representations)很重要。在本篇文章中,学习使用HttpMessageConverter 生成多个具象。代码示例展示如何使用 RestTemplate 和HttpMessageConverter

 



Yi Ming Huang, 软件工程师, IBM  

2011 年 8 月 01 日



  • 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务(转)_JSON

    内容



简介

随附文章,“使用 Spring 3 构建 RESTful web 服务”(参见 参考资料),介绍了使用 Spring 构建 RESTful web 服务的方式。还解释了如何使用ContentNegotiatingViewResolver 生成多个具象,这是 RESTful web 服务的一个重要功能。本文还阐述了使用 HttpMessageConverter 生成多个具象的另一种方式,并且本文中的示例展示了如何使用 RestTemplate 和 HttpMessageConverter


 



回页首

Spring MVC 中的 REST 支持

本部分提供了支持 RESTful web 服务的主要 Spring 功能(或注释)的概述。



@Controller

@Controller

@RequestMapping

@RequestMapping 注释对函数进行注释,该函数处理某些 HTTP 方法、URI 或 HTTP 头。此注释是 Spring REST 支持的关键。可以更改

method 参数以处理其他 HTTP 方法。

例如:


@RequestMapping(method=RequestMethod.GET, value="/emps", 
headers="Accept=application/xml, application/json")


@PathVariable

使用 @PathVariable

例如:



@RequestMapping(method=RequestMethod.GET, value="/emp/{id}") public ModelAndView getEmployee(@PathVariable String id) { … }


其他有用的注释

使用 @RequestParam使用 @RequestHeader使用 @RequestBody使用 @ResponseBody使用 HttpEntity<T>使用 ResponseEntity<T>

例如:



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

表 1. HttpMessageConverter 示例

使用......

您可以......

StringHttpMessageConverter

从请求和响应读取/编写字符串。默认情况下,它支持媒体类型 text/* 并使用文本/无格式内容类型编写。

FormHttpMessageConverter

从请求和响应读取/编写表单数据。默认情况下,它读取媒体类型 application/x-www-form-urlencoded 并将数据写入 MultiValueMap<String,String>。

MarshallingHttpMessageConverter

使用 Spring 的 marshaller/un-marshaller 读取/编写 XML 数据。它转换媒体类型为 application/xml 的数据。

MappingJacksonHttpMessageConverter

使用 Jackson 的 ObjectMapper

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

从最简单的示例开始。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 的 ObjectMapperorg.codehaus.jackson.jarorg.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":"[email protected]"}

Response for /rest/service/emps
{"count":2,
"employees":[
{"id":1,"name":"Huang Yi Ming","email":"[email protected]"},
{"id":2,"name":"Wu Dong Fei","email":"[email protected]"}
]}



XML

Spring 的内置转换程序 MarshallingHttpMessageConverter

清单 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>[email protected]</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>[email protected]</email>
      <id>1</id>
      <name>Huang Yi Ming</name>
    </employee>
    <employee>
      <email>[email protected]</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

清单 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>[email protected]</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>[email protected]</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

清单 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 GETpostForObject:使用特定请求正文执行 HTTP POSTput:使用特定请求正文执行 HTTP PUTdelete:执行 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()

清单 12. 发布新员工



Employee newEmp = new Employee(99, "guest", "[email protected]");
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", "[email protected]");
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

http://www.ibm.com/developerworks/cn/web/wa-restful/

 

标签:web,HttpMessageConverter,Spring,Employee,使用,清单,id
From: https://blog.51cto.com/u_2650279/6964755

相关文章

  • 视频监控汇聚平台EasyCVR视频页面WebRTC流地址播放不了是什么原因?
    开源EasyDarwin视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放,可同时播放多路视频流,也能支持视频定时轮播。视频监控汇聚平台EasyCV......
  • 小狐狸GPT付费源码-WEB版前端的监控代码
    今天搭建了下小狐狸的WEB版,里面有个隐藏的js代码调用外部接口可以看到下面的代码 会把当前的域名调用外部接口传递过去  ......
  • Spring Boot 之自定义Starter
    没有调查就没有发言权!做JavaEE开发的小伙伴们肯定听说过“约定大于配置”这样一句话,就是说系统,类库,框架应该假定合理的默认值,而非要求提供不必要的配置springboot中也为我们提供了丰富的starterspring-boot-starter-web:快速构建基于SpringMVC的Web项目,使用Tomcat做默认嵌......
  • Spring-1-透彻理解Spring XML的Bean创建--IOC
    学习目标上一篇文章我们介绍了什么是Spring,以及Spring的一些核心概念,并且快速快发一个Spring项目,实现IOC和DI,今天具体来讲解IOC能够说出IOC的基础配置和Bean作用域了解Bean的生命周期能够说出Bean的实例化方式一、Bean的基础配置问题导入问题1:在<bean>标签上如何配置别名......
  • springboot+mysql简单的登录系统
    springboot+mysql简单的登录系统pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation=&q......
  • Spring源码分析(五) MappingJackson2HttpMessageConverter
    大家用过springmvc的肯定都用过@RequestBody和@ResponseBody注解吧,你了解这个的原理吗?这篇文章我们就来说下它是怎么实现json转换的。首先来看一个类RequestResponseBodyMethodProcessor,这个类继承了AbstractMessageConverterMethodProcessor,我们来看看这个类的构造方法protec......
  • SpringBoot中Filter bean是怎么被添加到Servlet容器中的
    参考资料对于SpringBoot的IOC容器——ServletWebServerApplicationContext,其中的Filterbean,每个Filterbean都会被独立的注册成为Servlet的Filter。大概的注册过程分成2步:IOC容器——ServletWebServerApplicationContext将Filter接口的实现类封装成FilterRegistrationBean,放......
  • 对于Spring中的@Scheduled注解,cron表达式的格式与传统的cron表达式有所不同。
    @Scheduled(cron="00*/1**?")对于Spring中的@Scheduled注解,cron表达式的格式与传统的cron表达式有所不同。Spring的cron表达式包含6个字段,分别是秒分时日月星期。其中,秒是可选的。根据您提供的@Scheduled(cron="00*/1**?"),这表示任务会在每个小时的0分0秒执......
  • Java17与相关框架支持版本SpringBoot、IDEA、Tomcat等
    相关框架需要的最低版本NameVersionJava17+SpringFramework6.0SpringBoot3.0Tomcat10.1Maven3.6.3+Gradle7.x(7.5orlater)and8.xUndertow2.3IntelliJIDEA2021.2+SpringFrameworkSpringFrameworkOverview::SpringFrame......
  • Java 大神整理的 Spring 笔记,强得起飞 !
    强烈推荐大家阅读:阿里大佬的spring学习笔记,基本涵盖了Spring所有核心知识点及原理,建议大家至少看3遍,便可成为一个Spring高手,超越99%的人,学完之后再去学Spring的其他框架,比如SpringBoot,简直就是小意思,文末获取高清pdfJava程序员加餐福利:小咖最近整理一份BAT面试资料,覆盖了Java核心......