현재 사용자 지정지도 유형을 Jackson 2.8.4를 사용하여 JSON으로 직렬화 및 비 직렬화하려고합니다. this answer을 기반으로 직렬화 작업을 할 수 있었지만 비 직렬화에 어려움을 겪고 있습니다. 나는 위와 역 직렬화 할 때잭슨과 사용자 정의지도 비 직렬화
public class TestMapSerialize {
public interface TestMapGetters {
Map<String, String> getFooMap();
Map<String, String> getBarMap();
}
@JsonSerialize(as = TestMapGetters.class)
public static class TestMap extends ForwardingMap<String, String>
implements TestMapGetters {
private Map<String, String> fooMap;
private Map<String, String> barMap;
@Override
protected Map<String, String> delegate() {
return ImmutableMap.<String, String>builder()
.putAll(fooMap)
.putAll(barMap)
.build();
}
// Getters and setters...
}
public static void main(String[] args) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
final TestMap map = new TestMap();
map.setFooMap(ImmutableMap.of("a", "b", "c", "d"));
map.setBarMap(ImmutableMap.of("e", "f", "g", "h"));
final String json = mapper.writeValueAsString(map);
// Prints {"fooMap":{"a":"b","c":"d"},"barMap":{"e":"f","g":"h"}} as expected.
System.out.println(json);
// Throws JsonMappingException, see below.
final TestMap copy = mapper.readValue(json, TestMap.class);
}
}
, 나는 예외가 얻을 :
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
at [Source: {"fooMap":{"a":"b","c":"d"},"barMap":{"e":"f","g":"h"}}; line: 1, column: 11] (through reference chain: test.TestMapSerialize$TestMap["fooMap"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1075)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:60)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:517)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:362)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:27)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842)
at test.TestMapSerialize.main(TestMapSerialize.java:66)
을 그래서 잭슨은 여전히 원 일반적인 Map
, 비록 나의 클래스를 deseralize하려고 다음은 그 예이다 콩이기 때문에 일하지 않아. 나뿐만 아니라 @JsonDeserialize(as = TestMapGetters.class)
를 추가 시도했지만, 그때 얻을 : 그것은 하지 하위 유형을 때문에, 의미가
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Failed to narrow type [map type; class test.TestMapSerialize$TestMap, [simple type, class java.lang.String] -> [simple type, class java.lang.String]] with annotation (value test.TestMapSerialize$TestMapGetters), from 'test.TestMapSerialize$TestMap': Class test.TestMapSerialize$TestMapGetters not subtype of [map type; class test.TestMapSerialize$TestMap, [simple type, class java.lang.String] -> [simple type, class java.lang.String]]
at com.fasterxml.jackson.databind.AnnotationIntrospector.refineDeserializationType(AnnotationIntrospector.java:1194)
at com.fasterxml.jackson.databind.deser.DeserializerCache.modifyTypeByAnnotation(DeserializerCache.java:519)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:333)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:476)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3899)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3794)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842)
at test.TestMapSerialize.main(TestMapSerialize.java:68)
Caused by: java.lang.IllegalArgumentException: Class test.TestMapSerialize$TestMapGetters not subtype of [map type; class test.TestMapSerialize$TestMap, [simple type, class java.lang.String] -> [simple type, class java.lang.String]]
at com.fasterxml.jackson.databind.type.TypeFactory.constructSpecializedType(TypeFactory.java:359)
at com.fasterxml.jackson.databind.AnnotationIntrospector.refineDeserializationType(AnnotationIntrospector.java:1192)
... 10 more
. 내 객체가 Map
의 하위 유형이 아닌 경우이 객체가 비 직렬화 될 것이므로 차라리 맞춤형 디시리얼라이저를 작성하지 않아도됩니다. Jackson이 내 수업이 Map
이고 콩으로 역 직렬화한다는 사실을 무시하도록 할 수있는 방법이 있습니까?
@JsonCreator
static TestMap fromJson(
@JsonProperty("fooMap") ImmutableMap<String, String> fooMap,
@JsonProperty("barMap") ImmutableMap<String, String> barMap) {
final TestMap map = new TestMap();
map.setFooMap(fooMap);
map.setBarMap(barMap);
return map;
}
여전히 "단지 직렬화와 POJO로 역 직렬화"를을 피하기 위해 말할 수있는 방법이 좋을 것이다 :