Content-Type: application/x-www-form-urlencoded 提交的数据无法自动装配成复杂对象
我所指的复杂对象是表单的值是一个对象或者数组,比如我新写了一篇博文(Post),博文中包含两个标签[{name: 'tag0'}, {name: 'tag1'}],注意这里将文章和标签的关系假设成一对多,而非多对多。要发表的文章:
{
title: 'title test',
content: 'content test',
tag: [{name: 'tag0'}, {name: 'tag1'}]
}
此时如果拼接url传值的方式,必定要把tag的value转换成字符串,如果直接拼接会得到结果
url?title="title test"&content="content test"&tag="[Object, Object]"
明显不对,聪明的你一定想得到可以将tag的值转化成JSON字符串呀:
url?title="title test"&content="content test"&tag="[{"name":"tag0"},{"name":"tag1"}]"
一切看起来十分完美,但是后台是没办法将一个String类型自动装配成一个Tag类型的!
如果你坚持这么做,可以再写一个参数单独接收Tag
@PostMapping
public Result add (Post post, @RequestParam String tags) {
Type type = new TypeToken<List<Tag>>(){}.getType();
Gson gson = new Gson();
if (!StringUtil.isEmpty(tags)) {
List<Tag> tagList = gson.fromJson(tags, type);
Set<Tag> tagSet = new HashSet<>();
for (Tag tag: tagList) {
tag.setPost(post);
tagSet.add(tag);
}
post.setTags(tagSet);
}
return ResultUtil.success(postService.save(post));
}
你也许注意到了,文章的其他属性是可以自动装配到Post类中的,前提是不要加 @RequestParam 或者 @RequestBody注解。
另外:如果是已经存在的对象,form方式提交还可将 主键 装配成 对象,比如文章的主键是 c5850c6e-b71e-4dfe-97d6-4a87179c1d92 ,前端提交时参数 post: 'c5850c6e-b71e-4dfe-97d6-4a87179c1d92',后端依然可以用Post直接接收。
Content-Type: application/json 的使用
前端直接在请求体中提交Post对象,注意属性要一一对应,关联关系也需要是对应的对象。比如这里一个比较复杂的文章对象,其中的author(作者)、category(分类)分别对应后台实体类User、Category,tags(标签)对应的是实体类Tag的集合,只要无差错都可以装配成功。
image.png后台注意使用 @RequestBody 注解来接受请求体中的参数
@PostMapping
public Result add (@RequestBody Post post) {
return ResultUtil.success(postService.save(post));
}
网友评论