使用@RequestBody List<?>的Spring MVC REST返回HTTP 400语法不正确 [英] Spring MVC REST using @RequestBody List<?> returns HTTP 400 syntactically incorrect

查看:309
本文介绍了使用@RequestBody List<?>的Spring MVC REST返回HTTP 400语法不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring 4 + Jackson 2,并在自定义类上使用@RequestBody编写了一个功能齐全的POST方法。这种方法可以解组对象。

I am using Spring 4 + Jackson 2 and have written a fully functional POST method using @RequestBody on a custom class. This method has no trouble unmarshalling the object.

@ResponseBody
@RequestMapping(value="store", method = RequestMethod.POST)
public ServiceResponse store(@RequestBody CustomClass list) {
    ...
}

// Request: { code: "A", amount: 200 }

当我尝试添加另一种方法来处理同一个类的集合时,我的POST请求返回时出现以下错误。

When I attempted to add another method to handle a collection of the same class instead, my POST requests were returning with the following error.


HTTP状态400:客户端发送的请求在语法上不正确。

HTTP Status 400: The request sent by the client was syntactically incorrect.

我注意到,当提交的JSON与实体类不匹配时,通常会发生此错误。但是,我所做的只是提交一个相同对象的数组而不是对象本身,这已经证明有效。

I note that this error typically occurs when the JSON submitted does not match the entity class. However, all I am doing is submitting an array of the same object instead of the object itself, which has already proven to work.

@ResponseBody
@RequestMapping(value="store-bulk", method = RequestMethod.POST)
public ServiceResponse storeBulk(@RequestBody List<CustomClass> list) {
    ...
}

// Request: [{ code: "A", amount: 200 }, { code: "B", amount: 400 }]

我在这里遗漏了什么吗?

Am I missing something here?

推荐答案

答案是Spring 4实际上并没有摆脱类型擦除,这与其他一些解决方案所暗示的相反。在通过手动解组进行调试的同时,我决定自己处理这个步骤,而不是我无法控制的隐式转换。我确实希望有人出现并证明我是错的,尽管展示了更直观的解决方案。

The answer is that Spring 4 doesn't actually get rid of type erasure, contrary to what some other solutions suggest. While experimenting on debugging via manual unmarshalling, I decided to just handle that step myself instead of an implicit cast that I have no control over. I do hope someone comes along and proves me wrong, demonstrating a more intuitive solution though.

@ResponseBody
@RequestMapping(value="store-bulk", method = RequestMethod.POST)
public ServiceResponse storeBulk(@RequestBody String json) {
    try {
        List<CustomClass> list = new ObjectMapper().readValue(json, new TypeReference<List<CustomClass>>() { });
        ...
    } catch (Exception e) {
        ...
    }
}

奖励:在我开始工作之后,我遇到了这个例外:

Bonus: Right after I got this working, I bumped into this exception:


IllegalStateException:已经有id的POJO

IllegalStateException: Already had POJO for id

如果有人得到这个,那是因为列表中的对象恰好引用了另一个对象列表中的项目已经引用。我可以解决这个问题,因为该对象对于我的整个集合来说都是相同的,所以我只是从JSON端删除了除第一个对象以外的所有引用。然后我在JSON被编组到List对象后添加了缺少的引用。

If anyone gets this, it's because the objects in the list happen to reference some object that another item in the list already references. I could work around this since that object was identical for my entire collection, so I just removed the reference from the JSON side from all but the first object. I then added the missing references back after the JSON was unmarshalled into the List object.

Java 8用户的双线程(用户对象引用是我的问题) case):

Two-liner for the Java 8 users (the User object reference was the issue in my case):

User user = list.get(0).getUser();
list.stream().filter(c -> c.getUser() == null).forEach(t -> t.setUser(user));

这篇关于使用@RequestBody List&lt;?&gt;的Spring MVC REST返回HTTP 400语法不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆