使用 eclispelink 时,嵌套 @XmlJavaTypeAdapter 注释会被忽略,其中嵌套对象是通用的

发布于 2024-11-16 00:18:27 字数 2675 浏览 3 评论 0原文

当编组对象树时,我使用@XmlJavaTypeAdapter。某些适配器返回的类对象本身具有 @XmlJavaTypeAdapter 注释。当我使用与 websphere 7 一起打包的 JAXB 实现时,这工作得很好,但是当我使用 org.eclipse.persistence.jaxb.JAXBContextFactory 时,在返回的对象上使用 @XmlJavaTypeAdapter 注释第一个适配器被忽略。这是一个已知问题,还是我做错了什么?

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class,C.class);

        System.out.println(jc.getClass());

        Root root = new Root();
        A a = new A();
        root.a = a;

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

Root

@XmlRootElement
public class Root {

   @XmlJavaTypeAdapter(AAdapter.class)
   public A a;

}

A

public class A {

   public B b = new B();

}

B

public class B {

  @XmlJavaTypeAdapter(GAdapter.class)
  @XmlElement(name="b")
  public G<C> gc = new G<C>();

  public B(){
    gc.t = new C();
  }
}

C

public class C {

    public String c = "Foo";

}

G

public class G<T> {

  T t;

}

然后是 A 的适配器...

public class AAdapter extends XmlAdapter<B, A> {

    @Override
    public A unmarshal(B b) throws Exception {

        A a = new A();
        a.b = b;

        return a;
    }

    @Override
    public B marshal(A a) throws Exception {

        return a.b;
    }

}

通用类型的适配器

public class GAdapter<T> extends XmlAdapter<T, G<T>> {

  @Override
  public G<T> unmarshal(T c) throws Exception {

    return new G<T>();
  }

  @Override
  public T marshal(G<T> g) throws Exception {

    return g.t;
  }

}

以及使用类 com.sun.xml.bind.v2.runtime.JAXBContextImpl

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<root>

    <a>

    <b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c">

        <c>Foo</c>

    </b>

    </a>

</root>

当使用 org.eclipse.persistence.jaxb.JAXBContext 封送时,

<?xml version="1.0" encoding="UTF-8"?>

<root>

   <a>

      <b>forum237.C@23752375</b>

   </a>

</root>

我认为问题出在泛型类型上。目标是跳过对泛型类型的封送,仅封送 T,以及处理 T 的注释(如果有)。

When marshaling an object tree I am making use of the @XmlJavaTypeAdapter. Some adapters return objects of classes which themselves have the @XmlJavaTypeAdapter annotation. This worked fine when I used the JAXB implementation packaged with websphere 7, but when I use org.eclipse.persistence.jaxb.JAXBContextFactory the @XmlJavaTypeAdapter annotations on the objects returned by the first adapter are ignored. Is this a known issue, or am I doing something wrong?

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class,C.class);

        System.out.println(jc.getClass());

        Root root = new Root();
        A a = new A();
        root.a = a;

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

Root

@XmlRootElement
public class Root {

   @XmlJavaTypeAdapter(AAdapter.class)
   public A a;

}

A

public class A {

   public B b = new B();

}

B

public class B {

  @XmlJavaTypeAdapter(GAdapter.class)
  @XmlElement(name="b")
  public G<C> gc = new G<C>();

  public B(){
    gc.t = new C();
  }
}

C

public class C {

    public String c = "Foo";

}

G

public class G<T> {

  T t;

}

Then the adapter for A...

public class AAdapter extends XmlAdapter<B, A> {

    @Override
    public A unmarshal(B b) throws Exception {

        A a = new A();
        a.b = b;

        return a;
    }

    @Override
    public B marshal(A a) throws Exception {

        return a.b;
    }

}

And the adapter for the generic type

public class GAdapter<T> extends XmlAdapter<T, G<T>> {

  @Override
  public G<T> unmarshal(T c) throws Exception {

    return new G<T>();
  }

  @Override
  public T marshal(G<T> g) throws Exception {

    return g.t;
  }

}

when marshaled with class com.sun.xml.bind.v2.runtime.JAXBContextImpl

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<root>

    <a>

    <b xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c">

        <c>Foo</c>

    </b>

    </a>

</root>

when marshaled with org.eclipse.persistence.jaxb.JAXBContext

<?xml version="1.0" encoding="UTF-8"?>

<root>

   <a>

      <b>forum237.C@23752375</b>

   </a>

</root>

I think the issue is with generic types. The goal is to skip the generic type from being marshaled, and only marshal T, as well as process T’s annotations, if any.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

傲性难收 2024-11-23 00:18:27

注意:我是 EclipseLink JAXB (MOXy) 负责人。

我已经能够重现此问题并确认这是一个错误(https://bugs.eclipse.org/350626< /a>)。

package example;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Root {

    @XmlJavaTypeAdapter(AAdapter.class)
    public A<B> a;

}

A

package example;

public class A<T> {

    public T t;

}

A适配器

package example;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class AAdapter<T> extends XmlAdapter<T, A<T>> {

    @Override
    public A<T> unmarshal(T v) throws Exception {
        return new A<T>();
    }

    @Override
    public T marshal(A<T> v) throws Exception {
        return v.t;
    }

}

B

package example;

public class B {

}

演示

package example;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class, B.class);

        Root root = new Root();
        A<B> a = new A<B>();
        a.t = new B();
        root.a = a;

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

输出

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <a>example.B@3ecfff</a>
</root>

预期输出

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="b"/>
</root>

Note: I'm the EclipseLink JAXB (MOXy) lead.

I have been able to recreate this issue and confirm that is a bug (https://bugs.eclipse.org/350626).

Root

package example;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Root {

    @XmlJavaTypeAdapter(AAdapter.class)
    public A<B> a;

}

A

package example;

public class A<T> {

    public T t;

}

AAdapter

package example;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class AAdapter<T> extends XmlAdapter<T, A<T>> {

    @Override
    public A<T> unmarshal(T v) throws Exception {
        return new A<T>();
    }

    @Override
    public T marshal(A<T> v) throws Exception {
        return v.t;
    }

}

B

package example;

public class B {

}

Demo

package example;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class, B.class);

        Root root = new Root();
        A<B> a = new A<B>();
        a.t = new B();
        root.a = a;

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

Output

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <a>example.B@3ecfff</a>
</root>

Expected Output

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="b"/>
</root>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文