Search code examples
jsonspring-bootjacksontype-conversionpojo

Eliminate duplicate Json elements and retrieve element names starting with capital letters spring boot/java


I'm developing a Rest Client using Spring Boot and Spring Framework (spring-boot-starter-parent 2.1.6.RELEASE) I have a class representing a response object as shown below:

public class ValidateResponse {
    private String ResponseCode;
    private String ResponseDesc;

    //getters and setters
    //constructors using fields
    //empty constructor
}

I'm creating a web-hook for an external api and I need to return a JSON object to for a specific endpoint (the JSON object properties must start with uppercase(s)). I'm calling returning the object from a PostMapping method nested in a RequestMapping root path:

@PostMapping("hooks/validate")
public ValidateResponse responseObj(@RequestHeader Map<String, String> headersObj) {
    ValidateResponse response = new ValidateResponse("000000", "Success");

    logger.info("Endpoint = hooks/validate | Request Headers = {}", headersObj);

    return response;

} 

However, when I hit the endpoint from postman I'm getting duplicate varialbes

{
    "ResponseCode": "000000",
    "ResponseDesc": "Success",
    "responseCode": "000000",
    "responseDesc": "Success"
}

I understand that the pojo-json conversion is handled by spring but I don't understand why the conversion is yielding duplicate variables.

Note: I know the ResponseDesc and the ResponseCode are not declared using the best standards for naming variables (camelCasing).

I've done some digging and according to the Java Language Specification

An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.

and

The "Java letters" include uppercase and lowercase ASCII Latin letters A-Z (\u0041-\u005a), and a-z (\u0061-\u007a), and, for historical reasons, the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $ character should be used only in mechanically generated source code or, rarely, to access pre-existing names on legacy systems.

So, I'm assuming its syntactically correct to define a variable using the Camelcase format [Need clarification on this].

I'm considering having to create the JSON object manually but I'd like to know the cause of this behaviour first. Any pointers are appreciated.


Solution

  • public class ValidateResponse {
    
        @JsonProperty("ResponseDesc")
        public String responseCode;
    
        @JsonProperty("ResponseDesc")
        public String responseDesc;
    
        //getters and setters
        //constructors using fields
        //empty constructor
    }
    

    This must fix your problem, however I do not know the reason as it requires deep Jackson investigation.

    EDIT

    I found out the reason. The field got duplicated because in you case you had:

    • 2 public fields named in upper case -> they are to be processed by jackson
    • 2 getters getResponseCode and getResponseDesc -> they are to be resolved as accessors for properties responseCode and responseDesc accordingly.

    Summing this up - you have 4 properties resolved by Jackson. Simply making your fields private will resolve your issue, however I still advise using JsonProperty approach.