Reputation: 26858
I'm implementing a Spring @RestController
with a @PostMapping
annotated method. I want to allow a HTTP POST using this body:
{"dateTimes":[
"2017-07-19T14:25+02:00",
"2017-08-19T14:25+02:00"
]
}
I have an object used as @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;
}
}
This is my controller method:
@PostMapping("/transaction-allowed")
public void isTransactionAllowed(@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody TransactionAllowedRequestBody requestBody) {
System.out.println("requestBody = " + requestBody);
}
However, when I try this, I get:
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')
If I replace ZonedDateTime
with String
, it works.
I am using Spring Boot 1.5.3.
Note: Using @DateTimeFormat
on a GET request parameter works fine. I tried it with:
@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);
}
Upvotes: 0
Views: 2296
Reputation: 2447
You can use @JsonDeserialize
and a Deserializer of your own
Like the following one
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;
}
}
To use the Deserializer annotation will be like
@JsonDeserialize(using = ZonedDateTimeDeserializer.class)
private List<ZonedDateTime> dateTimes;
Upvotes: 0
Reputation: 26858
Seems the issue was that I forget to include the jackson-datatype-jsr310
dependency as Spring Boot will not add it by default:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
Upvotes: 1