我目前正在尝试使用Jackson2.8.4将自定义映射类型序列化和反序列化为JSON。我已经设法基于这个答案实现了序列化,但我正在与反序列化作斗争。下面是一个例子:
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)
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
我发现可以向TestMap
类添加一个静态creator方法:
@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”,以避免整个@jsoncreator
和@jsonserialize(as)
rigamarole。
问题内容: 我正在使用Flickr API 。调用该方法时,默认的JSON结果为: 我想将此响应解析为Java对象: JSON属性应按以下方式映射: 不幸的是,我无法找到一种使用Annotations做到这一点的好方法。到目前为止,我的方法是将JSON字符串读入a 并从中获取值。 但是我认为,这是有史以来最不优雅的方式。有没有简单的方法,可以使用注释还是自定义反序列化器? 这对我来说将是很明显的,
我想反序列化表单中的类: 其中文本是加密的,反序列化应该在重建TestFieldEncryptedMessage实例之前取消对值的加密。 我采用的方法非常类似于:https://github.com/codesqueak/jackson-json-crypto 也就是说,我正在构建一个扩展SimpleModule的模块: 如您所见,设置了两个修饰符:EncryptedSerializerModif
我有下面的JSON,我正试图使用Jackson API反序列化它 我基本上需要一个附件类,它有一个AttachmentFile对象列表,如下所示: 如何使用自定义反序列化器实现这一点? 谢谢
情况如下:我已经设法让Jackson反序列化以下通用 作为HTTP客户端,并使用exchange
我想通过扩展默认的反序列化器来创建自己的反序列化器,在其后面设置更多的值: 如您所见,我还想将此DTO母类重用于其他DTO。 我没有找到任何这样的例子。我真的是世界上第一个 反序列化的“AsUsual”(p,ctxt)应该是什么 我应该使用什么motherclass?JsonDeserializer/StdDeserializer/UntypedObjectDeserializer 反序列化程序会
我有一个Spring项目,我尝试添加一个自定义反序列化器来反序列化日期属性,具体取决于它们的格式。如果我将其用作Date属性的注释,则效果很好。但是,如果我将反序列化器添加到对象映射器中,当Jackson反序列化日期时,它不会调用。 我尝试这样应用我的自定义反序列化程序: 我不想每次都对Date属性应用注释,我想默认使用此反序列化器。我做错了什么?