2017-07-24 2 views
0

Ich implementiere eine Spring @RestController mit einer @PostMapping annotierten Methode. Ich möchte einen HTTP-POST mit diesem Körper erlauben:Liste von ZoneDateTime als Anfragekörper mit Spring

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

ich ein Objekt als @RequestBody verwendet haben:

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; 
    } 
} 

Das ist mein Controller-Methode:

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

Allerdings, wenn ich versuchen Sie das, ich bekomme:

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

Wenn ich ZonedDateTime durch String ersetze, funktioniert es.

Ich benutze Spring Boot 1.5.3.

Hinweis: Die Verwendung von @DateTimeFormat für einen GET-Anfrageparameter funktioniert einwandfrei. Ich versuchte es mit:

@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); 
} 

Antwort

1

das Problem scheint, war, dass ich vergessen, die jackson-datatype-jsr310 Abhängigkeit enthalten als Feder-Boot wird es standardmäßig nicht hinzufügen:

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

Sie können @JsonDeserialize verwenden und Deserializer von Ihre eigene

wie die folgende

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; 
    } 
} 

Die Deserializer-Annotation wird wie folgt aussehen:

Verwandte Themen