使用@RequestBody List的Spring MVC REST在语法上返回HTTP 400错误
问题内容:
我正在使用Spring 4 + Jackson 2,并在自定义类上使用@RequestBody编写了功能齐全的POST方法。此方法可以轻松解组对象。
@ResponseBody
@RequestMapping(value="store", method = RequestMethod.POST)
public ServiceResponse store(@RequestBody CustomClass list) {
...
}
// Request: { code: "A", amount: 200 }
当我尝试添加另一个方法来处理同一类的集合时,我的POST请求返回并出现以下错误。
HTTP状态400:客户端发送的请求在语法上不正确。
我注意到,当提交的JSON与实体类不匹配时,通常会发生此错误。但是,我正在做的只是提交同一对象的数组,而不是提交对象本身,这已经证明可以工作。
@ResponseBody
@RequestMapping(value="store-bulk", method = RequestMethod.POST)
public ServiceResponse storeBulk(@RequestBody List<CustomClass> list) {
...
}
// Request: [{ code: "A", amount: 200 }, { code: "B", amount: 400 }]
我在这里想念什么吗?
问题答案:
答案是,Spring
4实际上并没有摆脱类型擦除,这与其他解决方案所建议的相反。在尝试通过手动解组进行调试时,我决定自己处理该步骤,而不是自己无法控制的隐式强制转换。我确实希望有人能证明我是错的,但还是展示了一个更直观的解决方案。
@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) {
...
}
}
奖励:在我开始工作后,我碰到了这个例外:
IllegalStateException:已经有ID的POJO
如果有人得到它,那是因为列表中的对象碰巧引用了列表中另一项已经引用的某个对象。我可以解决此问题,因为该对象对于我的整个集合而言都是相同的,因此我只从第一个对象之外的所有对象中删除了JSON端的引用。然后,在将JSON解组到List对象后,我又添加了缺少的引用。
Java 8用户的两种语言(在我的情况下,用户对象引用是问题):
User user = list.get(0).getUser();
list.stream().filter(c -> c.getUser() == null).forEach(t -> t.setUser(user));