1

给定 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,没有找到任何可以在不编写过多自定义代码的情况下完成此任务的东西。我认为这是很常见的任务,解决方案应该在附近的某个地方。

如果解决方案允许自定义空值情况,那就太好了。

升级版:

现在尝试使用XmlTypeAdapterapproch,但对它不满意,因为我需要为我拥有的每一种类型编写 TypeAdapter,并且它们都将包含几乎相同的代码:

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();
    }
}

Categories.java 的变化:

    @XmlJavaTypeAdapter(CategoriesTypeAdapter.class)
    private Categories parent;

UPD1:

这对我也不起作用,至少反序列化现在总是返回 null 代替对象,不知道如何调试这个:对于这个 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>
4

2 回答 2

4

有两种方法可能有效,具体取决于确切的语义。

首先是使用注释对@JsonManagedReference/ @JsonBackReference,其中第一个用于“向前”属性,第二个用于“向后”引用。在这些情况下,第二个属性不包含在序列化中,但会在反序列化期间恢复。这适用于简单的分层对象。

第二个是@JsonIdentityInfo(在 2.0 中添加),它增加了对任意对象引用的支持,无论方向如何。它通过序列化每个对象来工作,因为它是第一次看到的;但在后来的引用中将它们序列化为 id。反序列化会自动恢复链接。

于 2012-08-18T17:21:16.697 回答
1

使用正确的字段访问权限Categories

@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"}  

编辑:
做两个gatters。@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();
    }  

}
于 2012-08-18T12:10:18.283 回答