简体   繁体   中英

@jsonanygetter doesn't work

Assume, I have the following class:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ObjectOfMonitoring {
  private BigInteger id;
  private Map<String, Object> properties = new HashMap<>();

  @JsonAnySetter
  public void add(String key, Object value) {
    properties.put(key, value);
  }

  @JsonAnyGetter
  public Map<String, Object> getProperties() {
    return properties;
  }

I test it in the following code:

ObjectOfMonitoring objectOfMonitoring = new ObjectOfMonitoring();
objectOfMonitoring.setId(BigInteger.ONE);
objectOfMonitoring.add("key1", "value1");
String jsonInString = mapper.writeValueAsString(objectOfMonitoring);
System.out.println(jsonInString);

I want to get result:

{"id":1,"key2":"value2","key1":"value1"}

But actual result is:

{"id":1,"properties":{"key2":"value2","key1":"value1"}}

What do I do incorrectly? And how to get the expected result?

Make sure that ObjectMapper and @JsonAnySetter / @JsonAnyGetter annotations are from the same packages.

All should be:

  • either from org.codehaus.jackson - which is the older version of jackson
  • or from com.fasterxml.jackson - which is newer (Jackson has moved from Codehaus when releasing Jackson 2 - see here )

If you have both dependencies in your project and you are using them interchangeably you may have such hard to notice problems.

The best would be to just get rid of org.codehaus.jackson from your project dependencies.

Might be late to the party but thought of posting the answer as it can be helpful to someone in the future.

This is the sample code which you can configure accordingly for your class.

The main class which will read the JSON and associates with the class:

public class Main {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("test.json").getAbsoluteFile();
        final ObjectMapper mapper = new ObjectMapper();
        MyObject myObject = mapper.readValue(jsonFile, MyPojo.class);
    }
}

Your custom POJO:

class MyObject {

    private int id;
    private Map<String,String> customField;
    
    //Getter and Setter for POJO fields ommited

    @JsonAnySetter
    public void setCustomField(String key, Object value) {
        System.out.println(" Key : " + key + " Value : " + value);
        if(customField == null){
            customField = new HashMap<String,Object>();
        }
        
        customField.put(key,value);
    }
    
    @JsonAnyGetter
    public Map<String,String> getCustomField(){
        return customField;
    }
}

This will work if even for duplicate keys within the JSON if you are using the readValue from ObjectMapper but if you are using the treeToValue method from ObjectMapper then this would fail for the duplicate keys and you will have only the last value for the duplicated field. I am still figuring out a way to access the duplicate field while using the treeToValue method

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM