Java Jackson(反)序列化对象作为其id

Java Jackson(反)序列化对象作为其id,java,json,jackson,Java,Json,Jackson,鉴于POJO: @XmlRootElement public class Categories implements Serializable { private int id; private String name; private Categories parent; // .... } 我想将其序列化为以下json: { id: 1, name: "some name", parent: 5 } 所以,这里的主要挑战是将父对象表示

鉴于POJO:

@XmlRootElement
public class Categories implements Serializable {
    private int id;    
    private String name;

    private Categories parent;

    // ....    

}
我想将其序列化为以下json:

{ id: 1, name: "some name", parent: 5 }
所以,这里的主要挑战是将父对象表示为其id 用于反序列化

我浏览了相当大的Jackson wiki,没有发现任何允许的内容 在不编写过多自定义代码的情况下完成此任务。 我认为这是一项非常常见的任务,解决方案应该在附近的某个地方

若解决方案允许自定义空值情况,那个也不错

UPD:

现在尝试使用
XmlTypeAdapter
approch,顺便说一句,不满意,因为我需要编写TypeAdapter 对于我所有的everyy单一类型,它们将包含几乎相同的代码:

public class CategoriesTypeAdapter extends XmlAdapter<Integer, Categories> {

    @Inject
    CategoriesFacade dao;

    @Override
    public Categories unmarshal(Integer v) throws Exception {
        return dao.find(v);
    }

    @Override
    public Integer marshal(Categories v) throws Exception {
        return v.getId();
    }
}
UPD1:

这对我来说也不起作用,至少反序列化现在总是返回null来代替object,不知道如何调试它: 对于此JSON:

{ id: 1, name: "test", parent: 5 }
我现在得到的父项总是空的:

Categories{categoryId=1, name="test", parentId=null}
UPD2:

我发现这是我失败的原因,只是没有正确地设置东西,并且我的web.xml缺少以下条目:

<servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.neopod.rest</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>

Jersey Web应用程序
com.sun.jersey.spi.container.servlet.ServletContainer
com.sun.jersey.config.property.packages
com.neopod.rest
com.sun.jersey.api.json.POJOMappingFeature
真的

使用对字段
类别的适当访问

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Categories implements Serializable {

    @XmlElement
    Integer categoryId;

    @XmlElement
    String name;

    Categories parentId;

    public Integer getCategoryId() {
        return categoryId;
    }

    public String getName() {
        return name;
    }

    @XmlElement
    public Integer getParentId()
    {
        return parentId == null ? null : parentId.getCategoryId();
    }
}
试验

Categories c = new Categories();
c.categoryId = 1;
c.name = "name";
Categories c1 = new Categories();
c1.categoryId = 2;
c.parentId = c1;
System.out.println(new ObjectMapper().writeValueAsString(c));  
输出

{"categoryId":1,"parentId":2,"name":"name"}  
编辑:
做两个盖特。 @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) 公共类类别实现可序列化{

    @XmlElement
    Integer categoryId;

    @XmlElement
    String name;

    Categories parentId;

    public Integer getCategoryId() {
        return categoryId;
    }

    public String getName() {
        return name;
    }  
    public Category getParentId()
    {
        return parentId;
    }

    @XmlElement(name = "parentId")
    Integer getParentIdForJSON()
    {
        return parentId == null ? null : parentId.getCategoryId();
    }  

}

使用属性访问字段
类别

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Categories implements Serializable {

    @XmlElement
    Integer categoryId;

    @XmlElement
    String name;

    Categories parentId;

    public Integer getCategoryId() {
        return categoryId;
    }

    public String getName() {
        return name;
    }

    @XmlElement
    public Integer getParentId()
    {
        return parentId == null ? null : parentId.getCategoryId();
    }
}
试验

Categories c = new Categories();
c.categoryId = 1;
c.name = "name";
Categories c1 = new Categories();
c1.categoryId = 2;
c.parentId = c1;
System.out.println(new ObjectMapper().writeValueAsString(c));  
输出

{"categoryId":1,"parentId":2,"name":"name"}  
编辑:
做两个盖特。 @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) 公共类类别实现可序列化{

    @XmlElement
    Integer categoryId;

    @XmlElement
    String name;

    Categories parentId;

    public Integer getCategoryId() {
        return categoryId;
    }

    public String getName() {
        return name;
    }  
    public Category getParentId()
    {
        return parentId;
    }

    @XmlElement(name = "parentId")
    Integer getParentIdForJSON()
    {
        return parentId == null ? null : parentId.getCategoryId();
    }  

}

根据确切的语义,有两种方法可能有效

第一种是使用注释对
@JsonManagedReference
/
@JsonBackReference
,其中第一种用于“forward”属性,第二种用于“backward”引用。在这种情况下,第二种属性不包括在序列化中,而是在反序列化过程中恢复。这适用于简单的层次结构对象


第二个是
@JsonIdentityInfo
(在2.0中添加),并且它添加了对任意对象引用的支持,而不考虑方向。它通过序列化每个对象来工作,就像第一次看到它一样;但是在以后的引用中,它将它们序列化为ID。反序列化会自动恢复链接。

根据确切的语义,可能有两种方法可以工作

第一种是使用注释对
@JsonManagedReference
/
@JsonBackReference
,其中第一种用于“forward”属性,第二种用于“backward”引用。在这种情况下,第二种属性不包括在序列化中,而是在反序列化过程中恢复。这适用于简单的层次结构对象


第二个是
@JsonIdentityInfo
(在2.0中添加),并且它添加了对任意对象引用的支持,而不考虑方向。它通过序列化每个对象来工作,就像第一次看到它一样;但是在以后的引用中,它将它们序列化为ID。反序列化会自动恢复链接。

有任何使用示例吗?我尝试了这两种方法,但没有明显的成功。字段仍然反序列化d作为所有字段都为空的对象。特别对
PropertyGenerator
用法感兴趣,我需要基于
getId/setId
pojopropertyjackson 2.0.0公告()生成id,有一个例子,但单元测试可能是最好的源代码。
PropertyGenerator
是“自带id”方法。一件事:没有办法避免在第一次完全序列化引用对象的第一个实例;这是正确反序列化事物所必需的。我看到了这篇博文erlaier,但有一个IntSequenceGenerator的示例,我决定不需要它,因为我已经由数据库生成了id,所以我把PropertyGenerator放在那里或者,关于反序列化似乎没有任何改变。要检查测试,谢谢。有任何使用示例吗?我尝试了这两种方法,但没有明显的成功。字段仍然反序列化为对象,所有字段都为空。特别是对
PropertyGenerator
用法感兴趣,我需要基于
getId/setId
POJO propertyJ生成idackson 2.0.0发布()有一个例子,但单元测试可能是最好的源代码。
PropertyGenerator
是“自带Id”方法。一件事:没有办法避免在第一次完全序列化引用对象的第一个实例;这是正确反序列化事物所必需的。我看到了这篇博文erlaier,但有一个IntSequenceGenerator的示例,我决定不需要它,因为我已经由数据库生成了id,所以我把PropertyGenerator放在那里或者,关于反序列化似乎没有什么变化。去检查测试,谢谢。我想这不是我需要的,我有getter和setter已经返回/接受
类别
对象,而不是
整数
。谢谢你的建议,但这对我也不起作用。我想这不是我需要的,我有getter和setter已返回/接受
类别
对象,而不是
整数
。感谢您的建议,但这对我也不起作用