java - Jackson 树结构的序列化/反序列化

标签 java json jaxb jackson

我有以下 POJO 类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Folder", propOrder = {
    "id",
    "parent"   
})
@XmlSeeAlso({
    FolderTree.class
})
public class Folder
{    
    protected int id;
    protected int parent;

    getters, setters...
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "FolderTree", propOrder = {
    "subFolders"
})
@XmlRootElement(name = "folderTree")
public class FolderTree extends Folder
{
    @XmlElement(name = "subFolder", type = Folder.class)
    protected List<Folder> subFolders;

    getter...
}

和包装器:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Folders", propOrder = {
    "folders"
})
@XmlRootElement(name = "folders")
public class Folders
{
    @XmlElement(name = "folder", type = Folder.class)
    protected List<Folder> folders;

    getter...
}

我需要在 XML 和 JSON 中序列化和反序列化它们。 XML 工作正常,但 JSON 按以下结构序列化:

{
    "folder": [
        {
            "subFolder": [
                {
                    "subFolder": [],
                    "id": 2,
                    "parent": 1

                },
                {
                    "subFolder": [],
                    "id": 3,
                    "parent": 1
                }
            ],
            "id": 1,
            "parent": null            
        }
    ]
}

解串器无法识别 subFolder 对象内的第二个字段 subFolder ("subFolder": [])。有没有办法让它只在父文件夹中包含子文件夹字段?或者可以采取什么措施让 Jackson 反序列化该对象本身?

我无法更改 POJO 类,因为它们是由 jaxb 创建的,并且一切都可以使用 XML 正常工作。

最佳答案

解决方案。

为了在没有子项的情况下摆脱空的 subFiolder 数组,我在序列化功能中禁用了 WRITE_EMPTY_JSON_ARRAYS。我使用 Spring,bean 如下所示:

<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    <property name="annotationIntrospector" ref="jaxbAnnotationIntrospector" />
    <property name="featuresToDisable">
        <list>
            <value type="com.fasterxml.jackson.databind.SerializationFeature">WRITE_EMPTY_JSON_ARRAYS</value>
        </list>
    </property>
</bean>

对于反序列化,由于我无法修改POJO类,所以我为Folder类添加了一个MixIn:

@JsonTypeInfo(  
        use = JsonTypeInfo.Id.NAME,  
        include = JsonTypeInfo.As.PROPERTY,  
        property = "folder",
        defaultImpl = FolderTree.class)
public class FolderMixin {

}

最后,我扩展了 ObjectMapper 来设置 MixInAnnotations:

public class CustomObjectMapper extends ObjectMapper
{
    public CustomObjectMapper()
    {
        super();
        customize();
    }

    protected void customize()
    {
        registerModule(new SimpleModule() {
            private static final long serialVersionUID = 1L;

            public void setupModule(SetupContext context) {
                super.setupModule(context);
                context.setMixInAnnotations(Folder.class, FolderMixin.class);
            }         
        });
    }
}

我添加了两个 AnnotationIntrospectors 用于反序列化:

<bean id="customObjectMapper" class="path.to.my.CustomObjectMapper"> 
    <property name="annotationIntrospector" ref="introspectors" />
</bean> 

<!-- introspectors  -->
<bean id="xmlAnnotation" class="com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector">
    <constructor-arg value="#{customObjectMapper.getTypeFactory()}" />
</bean>

<bean id="jsonAnnotation" class="com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector" />

<bean id="introspectors" class="com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair">
    <constructor-arg ref="xmlAnnotation" />
    <constructor-arg ref="jsonAnnotation" />
</bean>
<!--  end of introspectors  -->

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="objectMapper" ref="customObjectMapper"/>
</bean> 

我使用 Jackson 2.4.0。

关于java - Jackson 树结构的序列化/反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28354942/

相关文章:

java - 此代码中 "this"的含义?

jquery - 将具有多个属性的 JSON 对象转换为 html 元素

Java:调用 JAXBContext.newInstance() 时出现 JAXB IllegalAnnotationException

php - AFNetworking 1.x 将 JSON 发布到 PHP

java - 在 JavaEE 应用程序中使用 Jackson 作为 JAXB-JSON 处理器

java - 使用 JAXB 的具有属性和内容的 XML 元素

Java-创建对象类型的数组是不好的做法吗

java - 如何删除添加到膨胀的 LinearLayout 的 View 之间不需要的空格?

java - Prettyprint 在 JTextArea/JEditorPane 中提升为数字

javascript - 使用在 AJAX 中获得的 JSON 数据填充 JSTree