2016-10-20 2 views
0

현재 사용자 지정지도 유형을 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로 역 직렬화"를을 피하기 위해 말할 수있는 방법이 좋을 것이다 :

답변

0

나는 내 TestMap 클래스에 정적 제작자 방법을 추가 할 수 있다고 생각 전체 @JsonCreator@JsonSerialize(as) 리마 마롤.