The response of a WS is a json with first capitalize letters. I'm trying to encapsulate the response in a new MyResponse obj having lowercase first letters.
I'm using Jackson.
At first I have my models:
public class Telephone {
private String country;
private String prefix;
//getters and setters
}
public class Position {
private String x;
private String y;
//getters and setters
}
public class Root {
@JsonProperty("Telephone")
private List<Telephone> telephone;
@JsonProperty("Position")
private List<Position> position;
//getters and setters
}
public class MyResponse {
private final Root root;
private final String now;
public MyResponse(Root root, String now) {
this.root = root;
this.now = now;
}
//getters
}
As you can see above, I used @JsonProperty in my Root
class because I want to map my response using a first lowercase letter.
Now I have my RestController:
@Controller
public class RestController {
@GetMapping("/my-controller")
ResponseEntity<String> myController() {
//Simulating the request to my ws to get my json string
String jsonString = "{\n" +
" \"Telephone\":[\n" +
" {\n" +
" \"country\":\"ES\",\n" +
" \"prefix\":\"+34\"\n" +
" },\n" +
" {\n" +
" \"country\":\"FR\",\n" +
" \"prefix\":\"+33\"\n" +
" },\n" +
" {\n" +
" \"country\":\"EN\",\n" +
" \"prefix\":\"+44\"\n" +
" }\n" +
" ],\n" +
" \"Position\":[\n" +
" {\n" +
" \"x\":\"123.23\",\n" +
" \"y\":\"98.93\"\n" +
" },\n" +
" {\n" +
" \"x\":\"250.99\",\n" +
" \"y\":\"43.89\"\n" +
" }\n" +
" ]\n" +
"}";
ObjectMapper om = new ObjectMapper();
Root root = null;
try {
root = om.readValue(jsonString, Root.class);
MyResponse myResponse = new MyResponse(root, LocalDateTime.now().toString());
String responseAsString = om.writeValueAsString(myResponse);
return new ResponseEntity<>(responseAsString, HttpStatus.OK);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
As you can see in the snippet of code above, at the beginning I got the json string (in my real code calling the WS) and I deserialized it into a Java POJO using the readValue
method:
root = om.readValue(jsonString, Root.class);
Then I created my MyResponse obj using the deserialized POJO:
MyResponse myResponse = new MyResponse(root, LocalDateTime.now().toString());
And at the end, I serialized myResponse obj to String using om.writeValueAsString
and I returned it to my frontend:
String responseAsString = om.writeValueAsString(myResponse);
return new ResponseEntity<>(responseAsString, HttpStatus.OK);
Since MyResponse obj is serialized and deserialized both using my Root @JsonProperty (s) I get:
{
"root":{
"Telephone":[
{
"country":"ES",
"prefix":"+34"
},
{
"country":"FR",
"prefix":"+33"
},
{
"country":"EN",
"prefix":"+44"
}
],
"Position":[
{
"x":"123.23",
"y":"98.93"
},
{
"x":"250.99",
"y":"43.89"
}
]
},
"now":"2021-06-24T11:18:04.077612"
}
That is not what I am trying to do: I have capitalize letters in my response. How can I solve this problem? Should I use two different classes for serialization and deserialization?
I've tried what suggested by Felix. But it didn't work, I got the following error:
Conflicting/ambiguous property name definitions found multiple explicit names: but also implicit accessor
After a while I was able to solve my problem in this way:
public class Root {
private List<Telephone> telephone;
private List<Position> position;
@JsonCreator
public Root(@JsonProperty("Telephone") List<Telephone> telephon, @JsonProperty("Position") List<Position> position) {
this.telephon = telephon;
this.position = position;
}
//getters and setters
}
The annotation @JsonCreator
is used in deserialization phase only.
When one deserializes Jackson uses the constructor annotated with @JsonCreator
. In serialization phase Jackson uses the fields name to convert the obj into String.