jackson-databind
jackson-databind copied to clipboard
@JsonAnySetter and @JsonUnwrapped deserialize property twice
I did such test.
First define a pojo:
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class ESModel {
private Long id;
@JsonUnwrapped
private Result result;
private Map<String, Object> extra = new HashMap<>();
@JsonAnyGetter
public Map<String, Object> getExtra() {
return extra;
}
@JsonAnySetter
public void set(String key, Object value) {
extra.put(key, value);
}
@Data
public static class Result {
private String name;
}
}
Then test serialization:
@Test
public void test001() {
ESModel esModel = new ESModel();
ESModel.Result child = new ESModel.Result();
child.setName("aaa");
Map<String, Object> map = new HashMap<>();
map.put("age", 12);
esModel.setId(1L);
esModel.setResult(child);
esModel.setExtra(map);
System.out.println(JSON.toJSONString(esModel));
}
The output is following which I expected.
{"id":1,"name":"aaa","age":12}
And then test deserialization:
String json = "{\"id\":1,\"name\":\"aaa\",\"age\":12}";
ESModel model = JSON.parseObject(json, ESModel.class);
System.out.println(model);
The output is following which out of my expectation. The property 'name' has been deserialized twice.
ESModel(id=1, result=ESModel.Result(name=aaa), extra={name=aaa, age=12})
PS:The JSON utitliy class is follow:
public abstract class JSON {
private static ObjectMapper objectMapper;
static {
objectMapper = new ObjectMapper();
objectMapper.setTimeZone(TimeZone.getDefault());
objectMapper.setSerializationInclusion(NON_ABSENT);
objectMapper.disable(FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.disable(READ_DATE_TIMESTAMPS_AS_NANOSECONDS);
objectMapper.disable(WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
objectMapper.disable(DEFAULT_VIEW_INCLUSION);
objectMapper.enable(ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER);
objectMapper.enable(PROPAGATE_TRANSIENT_MARKER);
}
/*-----------------------deserialization-----------------------*/
public static <T> T parseObject(String json, Class<T> clazz) {
try {
return objectMapper.readValue(json, clazz);
} catch (IOException e) {
throw new JSONException(e.getMessage(), e);
}
}
/*-----------------------serialization-----------------------*/
public static String toJSONString(Object object) {
try {
return objectMapper.writeValueAsString(object);
} catch (IOException e) {
throw new JSONException(e.getMessage(), e);
}
}
}