关于 Java spring web 接收 Content-Type=application/json 请求参数的问题

118 天前
 coollight56

请问 spring web 只能用 @RequestBody 来接受 json 格式参数吗? 而且好像必须是用对象来接收

比如下面的情况就会报错 json 参数为

{
    "taskId":123
    ....
}

controller 为

    @PostMapping("/info")
    public void info(@RequestBody Long taskId) {
		System.out.println("taskId:" + taskId);
		// TODO
        
        
    }

错误提示

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.lang.Long` from Object value (token `JsonToken.START_OBJECT`)]

但是只要把 taskId 包装到一个对象中就可以正常接收,然而这样会不会太麻烦了,例如我又要接收一个 userId 那又得创建一个对象,spring web 不考虑自己封装的情况下(因为感觉这种场景应该很多才对,可能是我没掌握)有什么办法可以像 @RequestParam (只要定义需要接受的参数类型和名称就可以)来接收 json 参数

3386 次点击
所在节点    程序员
46 条回复
IFallowed
116 天前
我权且不论为啥一个查询接口使用 post ,估计这也不是 op 能决定的,而是 op 公司的传统。
根据 op 补充说明,请求发送方的数据格式不还是一个对象吗,为什么接收方要修改数据格式?我还没想到有什么场景需要这样做?
IFallowed
116 天前
另外,我看下来大家的回复也不是再说 json 传参符不符合规范啊? json 本就是现在主流的数据传输类型,和规范有什么关系?
IFallowed
116 天前
op 最后自定义了一个 @ComboParam ,你最终的处理不还是把请求参数封装在一个对象里面吗?
发送方以对象格式封装参数发给你,你在参数解析器里再把请求参数解析拆分后,最后又封装到了对象里,这样有什么意义?就为了把 schemeId 单独拿出来?又或者像你在 13 楼所表述的:请求发送方发送的参数包含你不需要的数据?
那解决思路不应该是再定义一个统一的前置的 Interceptor ,根据方法的入参去过滤掉请求体里不需要的数据吗?
当然,更推荐的应该是在你们的前后端交互规范里确立:前端应在不同的业务场景调用不同或者相同的接口仅传递必要的参数,而不能一窝打包交给服务端
IFallowed
116 天前
最后,如果 op 的公司没有说必须使用 post,这里只要换成 get 请求方式,都不需要 op 再自定义注解,就能达到 op 的要求:
@GetMapping("/schemeUserList")
public ApiResult<PageResult<?>> schemeUserList(@NotNull Long schemeId,
@Valid UserSearchParam userSearchParm,
@Valid PageParam pageParam)
// TODO
}
coollight56
116 天前
@IFallowed #41 并没有修改请求发送方的数据格式,而是从请求方的数据里( json 对象)提取我所需的参数,比如一个查询接口请求方发送的 json 对象为
{
"name": "",
"startTime": 1746892800000,
"endTime": 1746979200000,

"pageSize": 10,
"pageNumber": 1
}
可以看到里面有查询相关的参数,也有分页相关的参数,如果用 @RequestBody 需要定义一个完整的对象来接收全部参数,后端开发都知道分页这个功能是很独立的只需要页码和条数就可以,如果我能通过 @ComboParam PageParam 选择性接收分页相关的参数,那么就不需要在每个分页查询的对象上都定义页码和条数 封装出来的对象 PageParam 在整个系统共用
IFallowed
116 天前
@coollight56
1. 推荐你能改成 get 请求,就改成 get 请求,是你想要的效果的最优解。
2. 把分页参数使用父类或者泛型包装。
3.分页参数不要放在 body ,改用 param 。post 不仅能接受请求体的数据,也能接受请求的 url 上的参数,使用这方式也能将分页参数和业务参数隔离。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1131110

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX