2017-07-24 33 views
0

我正在實施彈簧@RestController以及@PostMapping帶註釋的方法。我想允許HTTP POST使用此體:將ZonedDateTime列表作爲請求主體與彈簧

{"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') 

如果我用String代替ZonedDateTime,它就可以工作。

我正在使用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); 
} 

回答

1

看來問題是我忘了包括jackson-datatype-jsr310依賴性,春天開機默認不會添加它:

<dependency> 
     <groupId>com.fasterxml.jackson.datatype</groupId> 
     <artifactId>jackson-datatype-jsr310</artifactId> 
     <version>${jackson.version}</version> 
    </dependency> 
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;