We are using Spring Boot to expose a REST endpoint which is called by a dumb client which delivers us the following:
{
"timestamp": "2016-08-16T14:30.000Z",
"data": "{\"amount\":1,\"product\":\"BASIC PRODUCT\"}"
}
We've created the following objects:
@JsonDeserialize(builder = Message.Builder.class)
public final class Message {
private final String timestamp;
private final Data data;
public String getTimestamp() {...}
public Data getData() {...}
@JsonPOJOBuilder
public static final class Builder {
private String timestamp;
private Data data;
public Builder withTimestamp(final String timestamp) {...}
public Builder withData(final Data data) {...}
}
}
and
@JsonDeserialize(builder = Data.Builder.class)
public final class Data {
private final String product;
private final int amount;
public String getProduct() {...}
public int getAmount() {...}
@JsonPOJOBuilder
public static final class Builder {
private String product;
private int amount;
public Builder withProduct(final String product) {...}
public Builder withAmount(final int amount) {...}
}
}
and exposed the endpoint as
@RequestMapping(consumes = "application/json", method = POST)
public ResponseEntity<?> receive(@RequestBody Message message) {
/// ...
}
but control doesn't even reach the receive
method and fails with 400 BAD REQUEST
. I believe this has to do with the fact that data
is a JSON-valued string. Does Jackson provide any annotation that I can use to force the JSON-valued string to be deserialized as an instance of Data
?
The key is in public Builder withData()
method of Message.Builder.class
to explicitly parse JSON-valued string to Data
type. Change the method parameter to String instead of Data
and call ObjectMapper().readValue(JSON-valued string, Data.class)
to deserialize it into Data
.
For example like this:
public Builder withData(final String jsonValue) throws JsonParseException, JsonMappingException, IOException {
Data data = new ObjectMapper().readValue(jsonValue, Data.class);
this.data = data;
return this;
}
For the clarity sake here you are my whole POJOs:
Message:
public final class Message {
private final String timestamp;
private final Data data;
private Message(Builder builder){
this.timestamp = builder.timestamp;
this.data = builder.data;
}
public String getTimestamp() {...}
public Data getData() {...}
@JsonPOJOBuilder
public static final class Builder {
private String timestamp;
private Data data;
private static ObjectMapper mapper = new ObjectMapper();
public Builder withTimestamp(final String timestamp) {
this.timestamp = timestamp;
return this;
}
public Builder withData(final String jsonValue) throws JsonParseException, JsonMappingException, IOException {
Data data = mapper.readValue(jsonValue, Data.class);
this.data = data;
return this;
}
public Message build() {
return new Message(this);
}
} // Builder
}
Data:
public final class Data {
private final String product;
private final int amount;
private Data(Builder builder){
this.product = builder.product;
this.amount = builder.amount;
}
public String getProduct() {...}
public int getAmount() {...}
@JsonPOJOBuilder
public static final class Builder {
private String product;
private int amount;
public Builder withProduct(final String product) {
this.product = product;
return this;
}
public Builder withAmount(final int amount) {
this.amount = amount;
return this;
}
public Data build() {
return new Data(this);
}
} // Builder
}
Hope it helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.