Spring boot jackson java.time.Duration

时间:2018-05-05 23:03:13

标签: java spring java-8

我已经创建了一个安静的网络服务,我尝试发送上述课程的帖子请求

public class A {
    Duration availTime;
}

public class MyRest {
    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public Response<?> test(@RequestBody A ta) {
        return new ResponseEntity<>(HttpStatus.OK);`
    }
}

原始请求正文

{
  "availTime": {
    "seconds": 5400,
    "nano": 0,
    "units": [
      "SECONDS",
      "NANOS"
    ]
  }
}

预期的json结果

 {"availTime": "PT1H30M"}

我收到了上述错误:无法读取HTTP消息:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected token (START_OBJECT),
expected one of [VALUE_STRING, VALUE_NUMBER_INT, VALUE_NUMBER_FLOAT] for java.time.Duration value; nested exception is
com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected one of [VALUE_STRING, VALUE_NUMBER_INT, VALUE_NUMBER_FLOAT] for java.time.Duration value

1 个答案:

答案 0 :(得分:3)

例外情况说java.time.Duration只能从intfloatstring创建,但您提供的是Json对象。

将您的Duration类定义为

public class Duration {

    private long seconds;
    private long nano;
    private List<String> units;

    // setters / getters
}

现在,您的请求将从课程A

进行映射

编辑1
如果您仍想要映射到java.time.Duration,则需要更改您的请求正文 案例1(int)

  • 请求正文

    {   “availTime”:5400 }

  • 输出

    { “availTime”: “PT1H30M”}

案例2(浮动)

  • 请求正文

    {   “availTime”:5400.00 }

  • 输出

    { “availTime”: “PT1H30M”}

案例3(字符串)

  • 请求正文

    {   “availTime”:“PT5400S” }

  • 输出

    { “availTime”: “PT1H30M”}

对于以上三种情况,要添加依赖

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jsr310</artifactId>
  <version>2.8.8</version>
</dependency>

A类应修改为

public class A {

    private Duration availTime;

    // for json output of duration as string 
    @JsonFormat(shape = Shape.STRING)
    public Duration getAvailTime() {
        return availTime;
    }

    public void setAvailTime(Duration availTime) {
        this.availTime = availTime;
    }
}

将请求正文打印为json

ObjectMapper mapper = new ObjectMapper();
mapper.findAndRegisterModules();
System.out.println(mapper.writeValueAsString(ta));

如果您仍想映射现有的请求正文,则需要为Duration类编写自定义反序列化程序。

希望它有所帮助。