Search code examples
javajsonjacksonjackson-databind

Response with lowercase letters in serialization and deserialization Jackson


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?


Solution

  • 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.