如何使用Jackson在注释的基础上对对象的字段进行反序列化?

如何使用Jackson在注释的基础上对对象的字段进行反序列化?,第1张

如何使用Jackson在注释的基础上对对象的字段进行反序列化?

您的大部分(全部?)要求都可以通过使用上下文序列化程序来实现。通过ContextualDeserializer的一个答案,使用Jackson和Jackson的Wiki(http://wiki.fasterxml.com/JacksonFeatureContextualHandlers)将JSON映射到不同类型的地图,我能够提出以下内容。

您需要从@JsonId批注开始,这是指示属性仅需要使用Id属性的键。

import com.fasterxml.jackson.annotation.*;import java.lang.annotation.*;@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@JacksonAnnotation // important so that it will get included!public @interface JsonId {}

接下来是实际的ContextualSerializer,它完成了繁重的工作。

import com.fasterxml.jackson.databind.ser.*;import com.fasterxml.jackson.databind.*;import com.fasterxml.jackson.core.*;import java.io.*;public class ContextualJsonIdSerializer    extends JsonSerializer<baseResource>    implements ContextualSerializer{    private ObjectMapper mapper;    private boolean useJsonId;    public ContextualJsonIdSerializer(ObjectMapper mapper) { this(mapper, false); }    public ContextualJsonIdSerializer(ObjectMapper mapper, boolean useJsonId) {        this.mapper = mapper;        this.useJsonId = useJsonId;    }    @Override    public void serialize(baseResource br, JsonGenerator jgen, SerializerProvider provider) throws IOException    {        if ( useJsonId ) { jgen.writeString(br.getId().toString());        } else { mapper.writevalue(jgen, br);        }    }    @Override    public JsonSerializer<baseResource> createContextual(SerializerProvider config, BeanProperty property) throws JsonMappingException    {        // First find annotation used for getter or field:        System.out.println("Finding annotations for "+property);        if ( null == property ) { return new ContextualJsonIdSerializer(mapper, false);        }        JsonId ann = property.getAnnotation(JsonId.class);        if (ann == null) { // but if missing, default one from class ann = property.getContextAnnotation(JsonId.class);        }        if (ann == null ) {//|| ann.length() == 0) { return this;//new ContextualJsonIdSerializer(false);        }        return new ContextualJsonIdSerializer(mapper, true);    }}

此类查看

baseResource
属性并检查它们以查看是否
@JsonId
存在注释。如果是,则仅使用Id属性,否则将使用传入
ObjectMapper
来序列化该值。这很重要,因为如果您尝试使用(基本上)在上下文中的映射器,
ContextualSerializer
则将导致堆栈溢出,因为它最终将一遍又一遍地调用这些方法。

您的资源看起来应该如下所示。我使用

@JsonProperty
注解而不是在中包装功能,
ContextualSerializer
因为重新发明轮子似乎很愚蠢。

import java.util.*;import com.fasterxml.jackson.annotation.*;public class Resource extends baseResource{    private String name;    @JsonProperty("sub_resource_id")    @JsonId    private SubResource subResource;    @JsonProperty("sub_resource_ids")    @JsonId    private List<SubResource> subResources;    //getters and setters    public String getName() {return name;}    public void setName(String name) {this.name = name;}    public SubResource getSubResource() {return subResource;}    public void setSubResource(SubResource subResource) {this.subResource = subResource;}    public List<SubResource> getSubResources() {return subResources;}    public void setSubResources(List<SubResource> subResources) {this.subResources = subResources;}}

最后,执行序列化的方法只是创建一个附加对象,

ObjectMapper
并在原始对象中注册一个模块
ObjectMapper

// Create the original ObjectMapperObjectMapper objectMapper = new ObjectMapper();objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);// Create a clone of the original ObjectMapperObjectMapper objectMapper2 = new ObjectMapper();objectMapper2.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);objectMapper2.configure(SerializationFeature.WRAP_ROOT_VALUE, true);objectMapper2.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);// Create a module that references the Contextual SerializerSimpleModule module = new SimpleModule("JsonId", new Version(1, 0, 0, null));// All references to SubResource should be run through this serializermodule.addSerializer(SubResource.class, new ContextualJsonIdSerializer(objectMapper2));objectMapper.registerModule(module);// Now just use the original objectMapper to serialize


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5003103.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-14

发表评论

登录后才能评论

评论列表(0条)

保存