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 をスキャンしましたが、大量のカスタム コードを書かなくてもこれを達成できるものは見つかりませんでした。これはかなり一般的なタスクであり、解決策は近くにあるはずだと思います。

また、ソリューションが null 値のケースをカスタマイズできるようになるとよいでしょう。

更新:

XmlTypeAdapter、approch を使用しようとしていますが、それに満足していません。なぜなら、私が持っているすべての単一の型に対して 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 }

私は親を常にnullにするようになりました:

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

正確なセマンティクスに応じて、2 つの方法があります。

1 つ目は、アノテーション ペア@JsonManagedReference/を使用することです。1 つ@JsonBackReference目は「前方」プロパティで使用され、2 つ目は「後方」参照で使用されます。このような場合、2 番目のプロパティはシリアル化に含まれませんが、逆シリアル化中に回復されます。これは、単純な階層オブジェクトに対して機能します。

2 つ目は@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"}  

編集:
2つのガッターを作ります。@XmlRootElement @XmlAccessorType(XmlAccessType.NONE)パブリッククラスCategoriesはSerializableを実装します{

    @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 に答える