1

Payload<T>Java オブジェクトに、 xml にマーシャリングする必要があるジェネリックが含まれている状況があります。したがって、次のクラスが与えられます。

抽象ボックス

@XmlTransient
public abstract class AbstractBox {
    String type = this.getClass().getSimpleName();
    String name = this.getClass().getCanonicalName();

    // setters/getters snipped

    public abstract String saySomething();
}

ちいさな箱

@XmlRootElement(name="small-box")
@XmlType(name="small-box")
public class SmallBox extends AbstractBox {

    @XmlElement
    public String getMsg() {
        return saySomething();
    }
    public void setMsg(String msg) {
        // do nothing
    }

    @Override
    public String saySomething() {
        return "I'm a small box";
    }
}

ペイロード

@XmlTransient
public class Payload<T> {
    private T payload;

    public T getPayload() {
        return payload;
    }

    public void setPayload(T payload) {
        this.payload = payload;
    }
}

そして、次のようないくつかのコード:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class JaxbAnnotationsTest<P>
{
    String name;
    int age;
    int id;
    Payload<P> payload;

    // setters and getters snipped

    public static void main(String[] args) {
        JaxbAnnotationsTest<AbstractBox> example = new JaxbAnnotationsTest<AbstractBox>();
        example.setName("Brion");
        example.setId(100);
        example.setAge(34);
        Payload<AbstractBox> object = new Payload<AbstractBox>();
        object.setPayload(new SmallBox());
        example.setPayloadContainer(object);

        try {
            XmlMapper xmapper = new XmlMapper();
            xmapper.writeValue(System.out, example);
        } catch (Exception ex) {
            System.err.println("Damn..." + ex.getMessage());
        }
    }

私は見ることを期待しています:

<JaxbAnnotationsTest>
  <name>Brion</name>
  <age>34</age>
  <id>100</id>
  <payloadContainer>
    <small-box>
      <type>SmallBox</type>
      <name>sandbox.xml.jaxb.annotations.SmallBox</name>
      <msg>I'm a small box</msg>
    </small-box>
  </payloadContainer>
</JaxbAnnotationsTest>

しかし、代わりに私は得る:

<JaxbAnnotationsTest>
  <name>Brion</name>
  <age>34</age>
  <id>100</id>
  <payloadContainer>
    <payload>
      <type>SmallBox</type>
      <name>sandbox.xml.jaxb.annotations.SmallBox</name>
      <msg>I'm a small box</msg>
    </payload>
  </payloadContainer>
</JaxbAnnotationsTest>

@XmlType具体的なサブクラスを使用して変更しようとしpayloadましたsmall-boxが、それもうまくいきませんでした。オブジェクトを削除し、単純にジェネリック型 PPayload<P>のクラス メンバーを持つと 、タグはなくなりますが、指定した名前は使用されずに残ります。payloadpaymentContainerpayloadsmall-box

ジェネリック型プロパティではなく、サブクラスで指定された名前にタグを設定するように JAXB (任意の実装) に強制する方法はありますか?

更新: 選択した回答は解決策を提供しますが、質問でもフォローアップしたかったのです。私の問題は2つありました:

  1. 私はクラスで使用@XmlTransientしていましたが、代わりにメソッドで注釈を使用する必要がありました(ただし、セッター/ゲッターのペアのどちらのメソッドに注釈が付けられていても、注釈が付けられているのは問題ではないと思います)。Payload<T>@XmlAnyElementsetPayload(T payload)
  2. -annotated プロパティの値として使用される要素JacksonJaxbXmlProviderを無視していた不完全な JAXB 実装であるJackson 2 を使用していました。@XmlRootElement@XmlAnyElement

Java 6/7 組み込み JAXB プロバイダーを使用するように JAXB プロバイダーを変更すると、期待どおりの出力が生成されました。

4

1 に答える 1