将@RequestBody 转换为对象
Posted
技术标签:
【中文标题】将@RequestBody 转换为对象【英文标题】:Converting @RequestBody to an object 【发布时间】:2011-08-18 21:34:30 【问题描述】:伙计们,我已经做了足够多的研究,但仍然找不到解决方案。
简而言之,我只是将 url 编码的表单数据传递给 Controller 方法,并尝试将其转换为具有日期和整数的域对象。
@RequestMapping(value = "/savePassport", method = RequestMethod.POST)
public @ResponseBody
AjaxResponse savePassport(@RequestBody StaffPassport passport, HttpServletResponse response)
// Some operations.
员工护照如下所示:
import java.sql.Date;
public class StaffPassport
private int staffId;
private String passportNumber;
private String placeOfIssue;
private Date issueDate;
private Date expiryDate;
private String spouseName;
private String oldPassportRef;
private String visaInfo;
private String description;
//gets/sets
当我调用 /savePassport 时,我得到不受支持的媒体异常。我猜这和选角有关。
我不能正常工作。当然,我可以使用 @RequestParam 捕获单个表单数据并手动进行转换,但这不是框架的重点,不是吗?
我哪里出错了?你是对的。我是 Spring 的初学者,但我喜欢它。
【问题讨论】:
问得好,ResponseBody 效果很好,但是没有人知道如何让RequestBody 自动绑定到一个bean 上?这很奇怪...... 【参考方案1】:您似乎使用了错误的注释。 @RequestBody
用于接受在其正文中具有任意内容的请求,例如 JSON、某些应用程序定义的 XML、逗号分隔的变量.. 等等。并使用您在调度程序 servlet 中配置的编组器将其转换为对象。
如果您只想让 Spring 为您绑定一个普通的旧表单帖子到支持对象上,则在方法参数上放置的正确注释是 @ModelAttribute
。
【讨论】:
我没有使用 完成这项工作的类是 WebDataBinder。手动完成会很痛苦,因为其中有很多配置。 是的,java.sql.Date 没有默认的属性编辑器。您需要注册自己的属性编辑器,以便使用 @InitBinder 将字符串转换为日期。 我的回复有点晚。你说的对。我使用了@ModelAttribute 和 WebDataBinder 的组合,我得到了解决方案。我使用了错误的注释。【参考方案2】:如果您使用 jQuery 发布 JSON 对象,并且希望 Spring 能够使用 @RequestBody 处理它,请在您的数据中使用 JSON.stringify(....)。举个例子:
var data = "id": 3, "name": "test"
$.post("processJsonData.html",JSON.stringify(data), function(data)
...
);
如果你不使用 JSON.stringify() 那么你会将数据作为表单数据提交,Spring 会告诉你你有一个不受支持的媒体类型。
【讨论】:
【参考方案3】:首先确定你有
<mvc:annotation-driven />
在你的 Spring 配置文件中。这是在 SPring MVC 中使用 JSOn 所必需的。
其次,我建议您测试对服务器的请求是否具有 application/json 内容类型。我相信 Fiddler2 会帮助你做到这一点。
第三,但我不确定,尝试将 POJO 中的 Date 项从 SQL 类型更改为常规 java 类型。
更新: 刚刚查看了表单,您的“接受”HTTP 标头似乎也应该是 application/json。请也使用 Fiddler2 测试此问题。
【讨论】:
【参考方案4】:我假设您发布 JSON 并希望 Spring 转换为 StaffPassport。如果您收到 Unsupported media 异常,那是因为 Spring 无法找到合适的方式来执行转换。
要让 Spring 转换 JSON,它需要 Jackson——确保您的项目中有 Jackson jar。如果这是一个基于 Maven 的项目,您可以将 jackson-mapper-asl 工件 ID 添加到您的 pom.xml。这应该会给你 jackson-mapper 和 jackson-core jars。
编辑:我应该提到这适用于 Spring 3(我最近遇到了这个问题)。我不确定以前版本的 Spring 还需要什么。
【讨论】:
【参考方案5】:检查 HttpMessageConverter 接口及其实现。您可以编写自己的实现来将其转换为您想要的域模型。当控件到达您的方法时,您可以像传递域模型对象一样访问它。
【讨论】:
【参考方案6】:好的,我想我应该完善我的答案。我没有在 spring-mvc 项目中使用它的直接经验,而是在 spring-integration 中使用它。我很确定适用的媒体类型(application/x-url-form-encoded)已经被 Spring 框架处理并转换为 MultiMap;因此,就像任何其他地图一样,从中检索值,键值是您的表单变量并填充您的业务模型。
HTH。
【讨论】:
请更新您的原始答案并进行任何澄清。以上是关于将@RequestBody 转换为对象的主要内容,如果未能解决你的问题,请参考以下文章
Spring注解@ResponseBody,@RequestBody
@RequestBody 没有将 JSON 映射到 Java 对象 - Spring Boot
如何在@RequestBody 中自定义将字符串转换为枚举?