使用Spring作为请求主体的ZonedDateTime列表

时间:2017-07-24 06:45:35

标签: java spring spring-boot jackson

我正在使用@RestController带注释的方法实现Spring @PostMapping。我想允许使用此主体的HTTP POST:

{"dateTimes":[
  "2017-07-19T14:25+02:00",
  "2017-08-19T14:25+02:00"
]
}

我有一个用作@RequestBody的对象:

public class TransactionAllowedRequestBody {
  @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
  private List<ZonedDateTime> dateTimes;

  public List<ZonedDateTime> getDateTimes() {
    return dateTimes;
  }


  public void setDateTimes(List<ZonedDateTime> dateTimes) {
    this.dateTimes = dateTimes;
  }
}

这是我的控制器方法:

@PostMapping("/transaction-allowed")
public void isTransactionAllowed(@AuthenticationPrincipal CustomUserDetails userDetails,
                                 @RequestBody TransactionAllowedRequestBody requestBody) {
    System.out.println("requestBody = " + requestBody);
}

然而,当我尝试这个时,我得到:

Could not read JSON document: Can not construct instance of java.time.ZonedDateTime: 
no String-argument constructor/factory method to deserialize from String value ('2017-07-19T14:25+02:00')

如果我将ZonedDateTime替换为String,则可行。

我正在使用Spring Boot 1.5.3。

注意:在GET请求参数上使用@DateTimeFormat可以正常工作。我尝试过:

@GetMapping("/transaction-allowed")
public void isTransactionAllowed(@AuthenticationPrincipal CustomUserDetails userDetails,
                                 @RequestParam("datetime") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime dateTime) {
    System.out.println("userDetails = " + userDetails);
    System.out.println("dateTime = " + dateTime);
}

2 个答案:

答案 0 :(得分:1)

似乎问题是我忘了包含jackson-datatype-jsr310依赖项,因为Spring Boot默认不会添加它:

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>${jackson.version}</version>
    </dependency>

答案 1 :(得分:0)

您可以使用@JsonDeserialize和您自己的反序列化

喜欢以下

public class ZonedDateTimeDeserializer extends JsonDeserializer<List<ZonedDateTime>> {
    @Override
    public List<ZonedDateTime> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        ObjectCodec oc = jp.getCodec();
        JsonNode array = oc.readTree(jp);
        List<ZonedDateTime> dates = new ArrayList<>();
        if(array.isArray()) {
            for (JsonNode node: array) {
                dates.add(ZonedDateTime.parse(node.asText()));
            }
        }
        return dates;
    }
}

使用反序列化器注释将类似于

@JsonDeserialize(using = ZonedDateTimeDeserializer.class)
private List<ZonedDateTime> dateTimes;