Parameterize JsonProperty value of Jackson Java Library

Viewed 309

I want to Serialize this body with Jackson.

but the "requestName" part will be different in many API Calls.

so I have some different objects for this part.

The problem is I want to parameterize the name of this JsonProperty but the Annotation doesnt accept the variable.

I get this error when I compile it :

/home/duma/IdeaProjects/API Testing/src/test/java/SingleRequest.java:16:19
java: element value must be a constant expression

Any Idea about this ?

body :

"singleRequest": {
        "requestName": {
            "canReplaceSpellCheckerQuery": false,
            "language": "fa",
            "query": "test",
            "scope": "app",
            "entities": ""
        }
    }

code :

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

public class SingleRequest {
   
    private Object object;
    @JsonIgnore
    private String requestName;

    SingleRequest(Object request, String requestName){
        this.object = request;
        this.requestName = requestName;
    }

    @JsonProperty(value = requestName)
    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }
    
    public String getRequestName() {
        return requestName;
    }
    public void setRequestName(String requestName) {
        this.requestName = requestName;
    }
}

1 Answers

Considering the JSON document you wish to generate:

"singleRequest": {
        "requestName": {
            "canReplaceSpellCheckerQuery": false,
            "language": "fa",
            "query": "test",
            "scope": "app",
            "entities": ""
        }
    }

and that you wish to parameterize the key corresponding to the field "requestName", then you may try the following code:

public class RequestDocument implements Serializable {
    Map<String, RequestOptions> singleRequest;

    public RequestDocument(Map<String, RequestOptions> singleRequest) {
        this.singleRequest = singleRequest;
    }

    public RequestDocument(String requestName, RequestOptions options) {
        this.singleRequest = new HashMap<String, RequestOptions>() {{
                put(requestName, options);
            }
        };
    }

    public static RequestDocument makeSample() {
        return new RequestDocument("requestName", RequestOptions.makeSample());
    }

    public String toJsonString() throws IOException {
        return new ObjectMapper()
                .setVisibility(PropertyAccessor.FIELD, Visibility.ANY) // just because I have no setter/getter
                .writerWithDefaultPrettyPrinter()
                .writeValueAsString(this);
    }
}

with RequestOptions being:

public class RequestOptions implements Serializable {
    Boolean canReplaceSpellCheckerQuery;
    String language;
    String query;
    String scope;
    String entities;

    public RequestOptions(Boolean canReplaceSpellCheckerQuery, String lang, String query, String scope, String entities) {
        this.canReplaceSpellCheckerQuery = canReplaceSpellCheckerQuery;
        this.language = lang;
        this.query = query;
        this.scope = scope;
        this.entities = entities;
    }        
    
    public static RequestOptions makeSample() {
        return new RequestOptions(false, "fa", "test", "app", "");
    }
}

By running the following code:

 public static void main(String[] args) throws IOException {
        RequestDocument example = RequestDocument.makeSample();
        logger.info(example.toJsonString());
    }

The output is exactly this:

{
  "singleRequest" : {
    "requestName" : {
      "canReplaceSpellCheckerQuery" : false,
      "language" : "fa",
      "query" : "test",
      "scope" : "app",
      "entities" : ""
    }
  }
}

I believe this is the simplest way to achieve your goals, but alternatives exist. You may start by reading this article and related: https://www.baeldung.com/jackson-map.

Please note that the provided code is just an example, not particularly polished.

Related