gpt4 book ai didi

java - 使用 Jackson 的 TypeResolverBuilder 反序列化原始长字段

转载 作者:太空宇宙 更新时间:2023-11-04 12:12:08 25 4
gpt4 key购买 nike

运行以下测试应用程序时

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Main {

public static void main(String[] args) throws IOException {
// Create test data
Data data = new Data();
data.key = 1;
Map<String, Object> mapData = new HashMap<>();
mapData.put("longInMap", 2L);
mapData.put("longAsField", data);

// Configure Jackson to preserve types
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
StdTypeResolverBuilder resolver = new StdTypeResolverBuilder();
resolver.init(JsonTypeInfo.Id.CLASS, null);
resolver.inclusion(JsonTypeInfo.As.PROPERTY);
resolver.typeProperty("__t");
mapper.setDefaultTyping(resolver);
mapper.enable(SerializationFeature.INDENT_OUTPUT);

// Serialize
String json = mapper.writeValueAsString(mapData);
System.out.println("json = " + json);

// Deserialize
Map deserializedData = mapper.readValue(json, Map.class);
}

static class Data {

public long key;
}
}

我得到这个输出和异常

json = {
"__t" : "java.util.HashMap",
"longInMap" : [ "java.lang.Long", 2 ],
"longAsField" : {
"__t" : "com.pinkmatter.bean.serialization.Main$Data",
"key" : [ "java.lang.Long", 1 ]
}
}
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Class java.lang.Long not subtype of [simple type, class long] (through reference chain: java.util.HashMap["longAsField"]->com.pinkmatter.bean.serialization.Data["key"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:379)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:339)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1591)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:278)
...
Caused by: java.lang.IllegalArgumentException: Class java.lang.Long not subtype of [simple type, class long]
at com.fasterxml.jackson.databind.type.TypeFactory.constructSpecializedType(TypeFactory.java:359)
at com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver._typeFromId(ClassNameIdResolver.java:72)
at com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver.typeFromId(ClassNameIdResolver.java:42)
...

我正在尝试从我们正在使用的库中序列化一堆基本的普通旧java对象(因此我们无法修改类或添加注释),同时还尝试保留集合中值的类型(上面示例中的“longInMap”必须保留为Long对象)。

问题是 Jackson 在尝试反序列化 Data 类中的原始 public long key 时抛出上述异常。如果我将类型更改为public int key,则不会引发异常并且反序列化可以正常工作。

此外,由于有许多不同类型的对象,并且我在编译时不知道将序列化哪些内容,因此我认为使用 mix-ins 不起作用。

请告知我可能做错了什么或可能的解决方法,以反序列化原始长字段,同时维护集合中对象的类型。

我使用的是 Jackson 2.8.3。

最佳答案

此处提供了解决方法 https://github.com/FasterXML/jackson-databind/issues/1395

解决方法是替换

StdTypeResolverBuilder resolver = new StdTypeResolverBuilder();

StdTypeResolverBuilder resolver = new StdTypeResolverBuilder() {
@Override
public TypeSerializer buildTypeSerializer(SerializationConfig config, JavaType baseType, Collection<NamedType> subtypes) {
if (baseType.isPrimitive()) {
return null;
}
return super.buildTypeSerializer(config, baseType, subtypes);
}

@Override
public TypeDeserializer buildTypeDeserializer(DeserializationConfig config, JavaType baseType, Collection<NamedType> subtypes) {
if (baseType.isPrimitive()) {
return null;
}
return super.buildTypeDeserializer(config, baseType, subtypes);
}

};

修复已实现,并将在 jackson-databind 2.8.4 中提供,之后将不再需要解决方法。

关于java - 使用 Jackson 的 TypeResolverBuilder 反序列化原始长字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39773266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com