Spring MVC –揭秘了@RequestBody和@ResponseBody

在这篇文章中,我想对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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367103.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python大作业外星人入侵_【python3小白上路系列】外星人入侵——开始

早起的周日&#xff0c;今日阴天&#xff0c;老爸生日快乐~开始项目首先创建一个空的Pygame窗口&#xff0c;供后面用来绘制游戏元素&#xff0c;如飞船和外星人。我们还将让这个游戏响应用户输入、设置背景色以及加载飞船图像。1.1.1 创建Pygame窗口以及相应用户输入首先&…

Codeforces 975D Ghosts 【math】

打了两次cf里的比赛&#xff0c;发现cf比较喜欢考数学题。一开始看到这道题没有思路&#xff0c;因为总想dp&#xff0c;图论&#xff0c;贪心这些东西。如果下次再没有思路&#xff0c;可以从数学的角度入手。 题解说的比较清楚&#xff1a; 2018.9.4又看了遍这题&#xff0c;…

前后台分离之数据模拟

在前后端分离的项目中&#xff0c;前后端约定好接口以后&#xff0c;就开始进入各自的开发阶段了&#xff0c;这时候我们前端不可避免的就需要进行数据模拟&#xff0c;那么怎么进行数据模拟呢&#xff1f;我觉得有两种&#xff1a; 在 客户端 模拟数据&#xff0c;也就是在我…

碎玻璃:诊断生产Cassandra问题

我刚刚在健康市场科学&#xff08;HMS&#xff09;成立二周年之际&#xff0c;我们几乎一直在这里与Cassandra一起工作。 那时&#xff0c;我们遇到的问题很少。 就像我曾经使用过的其他几种技术一样&#xff0c;Cassandra“行之有效”。 但是&#xff0c;就像我曾经使用过的*…

java 一维数组_java基础 ---- 一维数组

为什么要使用数组&#xff1a; 因为不使用数组计算多个变量的时候太繁琐&#xff0c;不利于数据的处理。-------- 数组也是一个变量&#xff0c;是存储一组相同类型的变量声明一个变量就是在内存中划出一块合适的空间声明一个数组就是在内存中划出一块连续的空间数组长度就是…

四则运算2

作业描述&#xff1a; 悲催的二柱子接到了老师要求给软件增加一些小小的功能&#xff0c;具体要求如下&#xff1a; 1、除了整数以外&#xff0c;还要支持真分数的四则运算&#xff08;需要验证结果的正确性&#xff09;&#xff1b; 2、一次出的题目避免相互重复&#xff1b; …

Java中的策略设计模式-示例教程

策略模式是行为设计模式之一 。 当我们对一个特定任务有多种算法&#xff0c;并且客户端决定在运行时使用的实际实现时&#xff0c;将使用策略模式。 策略模式也称为策略模式 。 我们定义了多种算法&#xff0c;并让客户端应用程序将算法用作参数。 此模式的最佳示例之一是采用…

MySQL数据库主从复制

使用gtid &#xff08;也需要开启binlog日志&#xff09; CHANGE MASTER TO MASTER_HOST’192.168.95.11’, MASTER_USER’mysql12’, MASTER_PASSWORD’mysql12’,MASTER_AUTO_POSITION 1; 使用binlog CHANGE MASTER TO MASTER_HOST’192.168.95.12’, MASTER_USER’mysql…

vue-cli 3.0 使用全过程讲解

2018年8月13日更新&#xff1a; 恭祝vue-cli 3.0.0 官方正式版发布&#xff0c;此后我们可以正式在3.0环境下进行项目开发了。 此文发布以来受到了很多朋友的阅读&#xff0c;但我深知这篇文章还是很浅显的&#xff0c;因此&#xff0c;我会在后续的 3.0 使用过程中分享我遇到…

java反射机制在spring_Java反射机制在Spring IOC中的应用

IOC&#xff1a;即“控制反转”&#xff0c;不是什么技术&#xff0c;而是一种思想。使用IOC意味着将你设计好的对象交给容器控制&#xff0c;而不是传统的在你的对象内部直接控制。本篇文章主要讲解一下IOC底层实现的原理(反射)&#xff0c;Bean容器的实现&#xff0c;就不对I…

【图像处理】Haar-like特征

特征提取的原理、代码等&#xff1b; 如果是白黑白&#xff0c;是减去一个黑的还是2个黑的&#xff0c;网上有不同的说法&#xff1b;应该需要看原论文了。 论文原文 The sum of the pixels which lie within the white rectangles are subtracted from the sum of pixels in t…

mysql获取某个表的所有字段名

转载&#xff1a;mym43210 mysql安装成功后可以看到已经存在mysql、information_schema和test这个几个数据库。 information_schema库中有一个名为COLUMNS的表&#xff0c;这个表中记录了数据库中所有表的字段信息。 知道这个表后&#xff0c;获取任意表的字段就只需要一条sele…

neo4j / cypher:悬挂查询参数

一直以来&#xff0c;我一直在使用neo4j的密码查询语言&#xff0c; 迈克尔一直在告诉我在查询中使用参数&#xff0c;但是查询的性能始终可以接受&#xff0c;因此我没有必要。 但是&#xff0c;最近我正在研究一个数据集&#xff0c;并使用类似于以下的代码创建了约500个节点…

java调用浏览器组件来_Java 网页浏览器组件介绍

在使用 Java 开发客户端程序时&#xff0c;有时会需要在界面中使用网页浏览器组件&#xff0c;用来显示一段 HTML 或者一个特定的网址。本文将介绍在界面中使用浏览器组件的四种方法&#xff0c;给出示例的代码&#xff0c;并且分析每种方法的优点与不足&#xff0c;便于 Java …

前端入行两年--教会了我这些道理

1.前言 光阴似箭&#xff0c;日月如梭。不得不感慨时间过得很快&#xff0c;2017差不多结束了&#xff0c;一下子我从事前端开发的时间已经两年了。这两年可以说是一波三折&#xff0c;回想这两年的经历&#xff0c;让我忍不住了写下了这篇文章&#xff0c;记录自己在这两年经历…

解决Nginx: [error] open() Nginx.pid

使用nginx -c的参数指定nginx.conf文件的位置 sudo /usr/sbin/nginx -c /etc/nginx/nginx.conf 转载于:https://www.cnblogs.com/vannn/p/9756132.html

巴霍巴利王

巴霍巴利王 惊心动魄的宫廷政变&#xff0c;必然铸就新的王朝更迭。时代的婉转&#xff0c;终究选上得民心的君主。我们的故事就这样悄无声息的将你带入幽深的宫廷内院。 夜幕之中&#xff0c;面对寒冷与杀戮&#xff0c;一位身负重伤王室女人&#xff0c;抱着一个新生儿&#…

Java中的观察者设计模式-示例教程

观察者模式是行为设计模式之一 。 当您对对象的状态感兴趣并希望在发生任何更改时得到通知时&#xff0c;观察者设计模式很有用。 在观察者模式中&#xff0c;监视另一个对象状态的对象称为Observer &#xff0c;而正在监视的对象称为Subject 。 根据GoF&#xff0c;观察者模式…

华为大数求和 java_大数乘积java

{"data":{"id":"8000-000000437045-0","name":"SEO专题页栏目分发组","type":"1","position":"8000-000000004003-0","status":1,"linkList":[{"id"…

IdnentiyServer-使用客户端凭据访问API

情景如下&#xff1a;一个客户端要访问一个api&#xff0c;不需要用户登录&#xff0c;但是又不想直接暴露api给外部使用&#xff0c;这时可以使用identityserver添加访问权限。 客户端通过clientid和secrect访问identitserver的Token Endpoint,获取accesstoken&#xff1b; 接…