在RequestMapping

时间:2015-11-06 17:41:03

标签: spring-mvc jackson

我在让RequestMapping PUT请求正常工作时遇到问题(注意:对于所有类,我为了简洁/清晰而简化了)。对于RequestMapping,我有这个:

@RequestMapping(value="/mobile/device", method = RequestMethod.PUT)
public ResponseEntity<Void> flagDevice (@RequestBody List<MobileDeviceData> deviceInfoList) String inAuthIdentity) {
// code here
}

MobileDeviceData类如下所示:

@Entity
@Table(name="ReportedDeviceData", schema="schemaName")
public class MobileDeviceData {
    @Id
    @Column(name="id")
    private String id;

    @Column(name="activityDetectedDate")
    private ZonedDateTime activityDetectedDate;

    ....
}

JSON有效负载看起来像这样:

[{
    "id": "123",
    "activityDetectedDate": "2015-11-06T08:32:05.994-08:00[America/Los_Angeles]"
}]

或者像这样:

[{
    "id": "123",
    "activityDetectedDate": 1446829632891
}]

第一种方式我收到此错误:

{"timestamp":1446829369320,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"Could not read document: Can not instantiate value of type [simple type, class java.time.ZonedDateTime] from String value ('2015-11-06T08:32:05.994-08:00[America/Los_Angeles]'); no single-String constructor/factory method\n at [Source: java.io.PushbackInputStream@6989f9; line: 2, column: 39] (through reference chain: java.util.ArrayList[0]->com.inauth.inex.entity.MobileDeviceData[\"activityDetectedDate\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.ZonedDateTime] from String value ('2015-11-06T08:32:05.994-08:00[America/Los_Angeles]'); no single-String constructor/factory method\n at [Source: java.io.PushbackInputStream@6989f9; line: 2, column: 39] (through reference chain: java.util.ArrayList[0]->com.inauth.inex.entity.MobileDeviceData[\"activityDetectedDate\"])","path":"/mobile/device/"}

对于第二种方式(以毫秒为单位的当前时间):

{"timestamp":1446829912863,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"Could not read document: Can not instantiate value of type [simple type, class java.time.ZonedDateTime] from Long integral number (1446829632891); no single-long-arg constructor/factory method\n at [Source: java.io.PushbackInputStream@550eb04; line: 2, column: 39] (through reference chain: java.util.ArrayList[0]->com.inauth.inex.entity.MobileDeviceData[\"activityDetectedDate\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.ZonedDateTime] from Long integral number (1446829632891); no single-long-arg constructor/factory method\n at [Source: java.io.PushbackInputStream@550eb04; line: 2, column: 39] (through reference chain: java.util.ArrayList[0]->com.inauth.inex.entity.MobileDeviceData[\"activityDetectedDate\"])","path":"/mobile/device/"}

所以我的问题是:

  1. 我怎样才能获得这些方法中的任何一种?或者是否有第三种方式被认为是我不知道的最佳实践?
  2. 什么是令人敬畏的是让两种方式都可以工作,然后客户可以选择。
  3. 提前致谢!

1 个答案:

答案 0 :(得分:2)

默认情况下,杰克逊不知道如何将值"2015-11-06T08:32:05.994-08:00[America/Los_Angeles]"1446829632891反序列化为ZonedDateTime个对象。

第一个选项是为JsonDeserializer编写一个自定义ZonedDateTime,知道如何对这两个值进行反序列化。

第二个选项,以及你应该使用的选项,因为它很简单,就是注册已经具有此行为的Module。现有Module存在,herejackson-datatype-jsr310。如文档所述,您可以隐式注册

ObjectMapper mapper = new ObjectMapper();
mapper.findAndRegisterModules();

或明确

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());

这意味着您必须创建自己的ObjectMapper并将其注入相应的MappingJackson2HttpMessageConverter。 (实际上,Spring Web 4.1.x似乎已经注册了这个众所周知的Module,因此您不需要做任何其他事情,只需将库添加到类路径中。)

还有jackson-datatype-jdk8