JsonMappingException:无法反序列化 java.lang.Integer 的实例出 START_OBJECT 令牌

Posted

技术标签:

【中文标题】JsonMappingException:无法反序列化 java.lang.Integer 的实例出 START_OBJECT 令牌【英文标题】:JsonMappingException: Can not deserialize instance of java.lang.Integer out of START_OBJECT token 【发布时间】:2016-09-25 01:22:13 【问题描述】:

我想使用 Spring Boot 编写一个小而简单的 REST 服务。 下面是 REST 服务代码:

@Async
@RequestMapping(value = "/getuser", method = POST, consumes = "application/json", produces = "application/json")
public @ResponseBody Record getRecord(@RequestBody Integer userId) 
    Record result = null;
    // Omitted logic

    return result;

我发送的 JSON 对象如下:


    "userId": 3

这是我得到的例外:

警告 964 --- [XNIO-2 任务 7] .w.s.m.s.DefaultHandlerExceptionResolver : 无法读取 HTTP 信息: org.springframework.http.converter.HttpMessageNotReadableException: 无法读取文档:无法反序列化 java.lang.Integer out of START_OBJECT token at [Source: java.io.PushbackInputStream@12e7333c;行:1,列:1];嵌套的 例外是 com.fasterxml.jackson.databind.JsonMappingException: Can 不在 START_OBJECT 中反序列化 java.lang.Integer 的实例 [来源:java.io.PushbackInputStream@12e7333c;线:1, 列:1]

【问题讨论】:

【参考方案1】:

也许您正尝试从 Postman 客户端或类似的东西发送正文中包含 JSON 文本的请求:


 "userId": 3

这不能被 Jackson 反序列化,因为这不是一个整数(它似乎是,但它不是)。 java.lang Integer 中的 Integer 对象稍微复杂一些。

为了使您的 Postman 请求正常工作,只需输入(不带花括号 ):

3

【讨论】:

我知道这已经晚了,但我怎样才能让我的控制器方法发送像 "userId": 3 这样的请求 @Gimnath 发送 "userId": "userIdVariable" ,用引号括起来,变量名和大括号之间有 no 空格。【参考方案2】:

显然,Jackson 无法将传递的 JSON 反序列化为 Integer。如果您坚持通过请求正文发送 User 的 JSON 表示,则应将 userId 封装在另一个 bean 中,如下所示:

public class User 
    private Integer userId;
    // getters and setters

然后将该 bean 用作您的处理程序方法参数:

@RequestMapping(...)
public @ResponseBody Record getRecord(@RequestBody User user)  ... 

如果您不喜欢创建另一个 bean 的开销,您可以将 userId 作为 Path Variable 的一部分传递,例如/getuser/15。为此:

@RequestMapping(value = "/getuser/userId", method = POST, produces = "application/json")
public @ResponseBody Record getRecord(@PathVariable Integer userId)  ... 

由于您不再在请求正文中发送 JSON,您应该删除该 consumes 属性。

【讨论】:

我知道问题出在 Jackson 对象映射器上,但我并不真正了解通过 HTTP 发送的 JSON 对象。我最初的提示是问题出在我的 JSON 对象上。感谢您的回答 Ali Dehghani! 不使用 PathVariable 注解,有没有其他方法可以在 POST 方法中发送一个简单的 Integer?除了 Jackson 之外,还有其他反序列化技术可以反序列化请求正文中的简单 Integer 吗? 代替application/json,您可以发送一个键值对,例如userId=15 在请求正文中使用 application/x-www-form-urlencoded 如果不是@PathVariable,您可以使用@RequestParam("userId") 作为URI 中的查询参数,并将被视为“?userId=15”作为服务URI 的结尾.

以上是关于JsonMappingException:无法反序列化 java.lang.Integer 的实例出 START_OBJECT 令牌的主要内容,如果未能解决你的问题,请参考以下文章

Jackson JsonMappingException:无法识别的列'C':已知列“A”,“B”

org.codehaus.jackson.map.JsonMappingException:无法从 JSON 字符串实例化类型 [简单类型,类 models.Job] 的值

使用 Jackson 和消息解析 JSON 文件中的内容时出现问题 - JsonMappingException - 无法反序列化为超出 START_ARRAY 令牌

JsonMappingException:不是地图,不是数组或不是枚举

Spring cloud netflix 和 HystrixObservable --> JsonMappingException

使用 Pageable 字段测试端点时出现 JsonMappingException