在这篇文章中,我想对Spring MVC进行一些深入的探讨,以揭示将请求转换为参数对象后在幕后发生的情况,反之亦然。 在开始之前,我想解释这些注释的目的。

@RequestBody和@ResponseBody是做什么用的?

它们是spring mvc框架的注释,可用于控制器中以实现智能对象序列化和反序列化。 通过提取消息转换的逻辑并将其作为一个方面,它们可帮助您避免样板代码。 除此之外,它们还帮助您为单个REST资源支持多种格式,而无需重复代码。 如果您使用@ResponseBody注释方法,spring将尝试转换其返回值并将其自动写入http响应。 如果使用@RequestBody注释方法参数,spring会尝试将传入请求主体的内容即时转换为参数对象。

这是一个例子

@Controller
@RequestMapping(value = "/bookcase")
public class BookCaseController {private BookCase bookCase;@RequestMapping(method = RequestMethod.GET)@ResponseBodypublic BookCase getBookCase() {return this.bookCase;}@RequestMapping(method = RequestMethod.PUT)@ResponseStatus(HttpStatus.NO_CONTENT)public void setBookCase(@RequestBody BookCase bookCase) {this.bookCase = bookCase;}}

那么,当我们使用这些注释时,Spring在后台做了什么?

根据您的配置,spring在后台注册了HttpMessageConverters列表。 HttpMessageConverters的职责是根据预定义的mime类型将请求正文转换为特定类,然后再次转换为响应正文。 每当发出的请求命中@RequestBody或@ResponseBody批注时,spring都会循环遍历所有已注册的HttpMessageConverters,以寻找适合给定mime类型和类的第一个,然后将其用于实际转换。

如何添加自定义HttpMessageConverter?

通过分别添加@EnableWebMvc <mvc:annotation-driven />,spring为JSON / XML注册了一堆预定义的消息转换器,等等。 您可以添加如下的自定义转换器

@Configuration
@EnableWebMvc
@ComponentScan
public class WebConfiguration extends WebMvcConfigurerAdapter {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> httpMessageConverters) {httpMessageConverters.add(new BookCaseMessageConverter(new MediaType("text", "csv")));}
}

在此示例中,我编写了一个转换器,用于处理BookCase的转换,而BookCase基本上是一本Books List。 转换器能够将csv内容转换为BookCase,反之亦然。 我使用opencsv解析文本。

这是模型

public class Book {private String isbn;private String title;public Book(String isbn, String title) {this.isbn = isbn;this.title = title;}// ...
}public class BookCase extends ArrayList<Book> {public BookCase() {}public BookCase(Collection<? extends Book> c) {super(c);}
}

和实际的转换器

public class BookCaseMessageConverter extends AbstractHttpMessageConverter<BookCase> {public BookCaseMessageConverter() {}public BookCaseMessageConverter(MediaType supportedMediaType) {super(supportedMediaType);}public BookCaseMessageConverter(MediaType... supportedMediaTypes) {super(supportedMediaTypes);}@Overrideprotected boolean supports(Class<?> clazz) {return BookCase.class.equals(clazz);}@Overrideprotected BookCase readInternal(Class<? extends BookCase> clazz, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {CSVReader reader = new CSVReader(new InputStreamReader(httpInputMessage.getBody()));List<String[]> rows = reader.readAll();BookCase bookCase = new BookCase();for (String[] row : rows) {bookCase.add(new Book(row[0], row[1]));}return bookCase;}@Overrideprotected void writeInternal(BookCase books, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {CSVWriter writer = new CSVWriter(new OutputStreamWriter(httpOutputMessage.getBody()));for (Book book : books) {writer.writeNext(new String[]{book.getIsbn(), book.getTitle()});}writer.close();}
}

结果

现在,我们可以将text / csv请求以及application / json和xml发出给我们的资源,而这些请求基本上是开箱即用的。

  1. PUT /bookcase
    Content-Type: text/csv
    "123","Spring in Action"
    "456","Clean Code"Response
    204 No Content
  2. GET /bookcase
    Accept: text/csvResponse
    200 OK
    "123","Spring in Action"
    "456","Clean Code"

得益于遵循单责任原则的spring mvc设计,我们的控制器保持纤薄。 如果我们要支持新的媒体类型,则不必添加一行。

完整的示例可以在我的github上找到

参考: Spring MVC –在Be Be a Better Developer博客上, JCG合作伙伴 Gregor Riegler 揭露了@RequestBody和@ResponseBody的神秘面纱 。

翻译自: https://www.javacodegeeks.com/2013/07/spring-mvc-requestbody-and-responsebody-demystified.html

Spring MVC –揭秘了@RequestBody和@ResponseBody相关推荐

  1. Spring MVC源码 ----- @RequestBody和@ResponseBody原理解析

    来源:https://www.cnblogs.com/java-chen-hao/p/11187914.html 1. 概述 在SpringMVC的使用时,往往会用到@RequestBody和@Res ...

  2. Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解

    引言: 接上一篇文章,对@RequestMapping进行地址映射讲解之后,该篇主要讲解request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用: 简介: han ...

  3. spring mvc注解之@RequestBody和@RequestParm

    @RequestBody http://localhost:8080/user/login {"username":"jack","passward& ...

  4. Spring MVC 解决日期类型动态绑定问题

    出处:http://www.cnblogs.com/crazy-fox/archive/2012/02/18/2357699.html ean 名为User,则在相同的包中存在UserEditor类可 ...

  5. spring mvc接收数组

    (一)前言 对于springmvc接收数组的问题啊,我试验过几次,但是了有时候成功了,有时候失败了,也不知道为啥的,然后现在又要用到了,所以打算具体看看到底怎么回事,但是了我实验成功了顺便找了好多资料 ...

  6. Spring MVC常用注解--“姐妹花”@RequestBody和@ResponseBody

    1. 引言 在这篇短文中,我们简要地介绍了Spring MVC中常用的注解 @RequestBody和@ResponseBody. 2. @RequestBody 简单地说,在@RequestBody ...

  7. Spring MVC之@RequestBody, @ResponseBody 详解

    引言: 接上一篇文章讲述处理@RequestMapping的方法参数绑定之后,详细介绍下@RequestBody.@ResponseBody的具体用法和使用时机: 简介: @RequestBody 作 ...

  8. spring mvc @RequestBody @ResponseBody 解析流程

    一.此接口测试用例 @RequestMapping(value = "/save_user",produces = "application/xml;charset=ut ...

  9. 如何在返回String的Spring MVC @ResponseBody方法中响应HTTP 400错误?

    本文翻译自:How to respond with HTTP 400 error in a Spring MVC @ResponseBody method returning String? I'm ...

最新文章

  1. 【LeetCode】230#二叉搜索树中第K小的元素
  2. 王者争雄服务器维护,王者争雄_王者争雄官网_攻略-第一手游网
  3. [小技巧]在NTFS分区中复制文件的同时如何复制权限
  4. windows下python3关于机器学习的环境配置,Anaconda的安装和使用方法以及安装后无法打开的解决方法
  5. Polymorphic form--多态表单
  6. Blockchain-Based Flexible Double-Chain Architecture and Performance Optimization for Better Sustaina
  7. oracle条件批量更新表数据
  8. 《中国大学--博弈论》
  9. uefi能重置系统吗_无惧UEFI, Win10也能玩转一键自动还原
  10. cmd静默运行_exe、msi、dos、bat等静默运行,后台运行,不弹窗的解决办法
  11. postsql将MULTIPOLYGON转POLYGON
  12. html 怎么转换,html怎么转换成word?
  13. 达梦数据库备份还原使用
  14. BP神经网络综合评价法
  15. 构筑“数据连接器”,腾讯云大数据推出“开源开放”战略
  16. asin、acos、atan 和 atan2 函数用法简介
  17. bat 批处理 启动微信 QQ等应用软件可以多开微信
  18. 可能是东半球最好看的vue3日历组件vue-baidu-calendar
  19. php imap函数,Imap是什么意思,php imap 函数详解(2)
  20. 什么是服务器集群?海外服务器集群的优势?

热门文章

  1. tomcat中配置jndi数据源以便spring获取
  2. 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)
  3. JVM内存结构分析:为什么需要S0和S1?
  4. 带Quarkus的Qute模板
  5. stream分组计数_Java Stream:第2部分,计数始终是计数吗?
  6. 文档 修订 非修订区别_修订和不变性
  7. 算法正义_正义联盟的Sprint Boot
  8. hibernate删除记录_Hibernate记录:常见问题的提示和解决方案
  9. dynamodb容器使用_使用DynamoDB映射器将DynamoDB项目映射到对象
  10. 谷歌guava_Google Guava:您永远不会知道的5件事