【问题标题】:after/before (Un)Marshal event fires twice and for xml onlyafter/before (Un)Marshal 事件触发两次,仅用于 xml
【发布时间】:2013-07-05 10:45:53
【问题描述】:

一个简单的类,正在编组输出:

@XmlRootElement
public class Foobar {
    // ...

    void beforeMarshal(Marshaller m) {
        System.out.println("beforeMarshal fired");
    }
}

JAX-RS 也很简单:

@GET
public Response getResponse() {
    Foobar fb = new Foobar();
    // ...
    return Response.ok(fb).build();
}

预期的输出将是“在Marshal 触发之前”一次,但它会触发两次?
这是正常的吗?我不认为使用额外的标志是一个好主意..

@XmlTransient
private boolean marshalled;

void beforeMarshal(Marshaller m) {
    if (!this.marshalled) {
        System.out.println("beforeMarshal");
        this.marshalled = true;
    }
}

此外,在查询资源以获取 json 输出时,它根本不会触发 marshal 事件。

【问题讨论】:

    标签: jaxb eclipselink jax-rs glassfish-3 moxy


    【解决方案1】:

    更新

    MOXy 中存在一个错误(请参阅:http://bugs.eclipse.org/412417),该错误会阻止在 OSGi 环境(如 GlassFish)中调用编组/解组方法。这现在已在 EclipseLink 2.3.3、2.4.3、2.5.1 和 2.6.0 流中得到修复。从 2013 年 7 月 10 日开始,您可以从以下链接下载每晚构建:

    我无法重现同一事件被调用两次的问题。如果您有演示此问题的代码示例,请通过我的博客与我进行电子邮件对话:


    XML 绑定

    如果您看到beforeMarshal 方法被调用了两次而不是一次,那么您使用的是参考实现而不是EclipseLink MOXy 作为您的JAXB (JSR-222) 提供程序。

    演示代码

    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Foobar.class);
            System.out.println(jc.getClass());
    
            Foobar foobar = new Foobar();
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.marshal(foobar, System.out);
        }
    
    }
    

    输出 - JAXB 参考实现

    class com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl
    beforeMarshal fired
    beforeMarshal fired
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?><foobar/>
    

    输出 - EclipseLink MOXy

    class org.eclipse.persistence.jaxb.JAXBContext
    beforeMarshal fired
    <?xml version="1.0" encoding="UTF-8"?>
    <foobar/>
    

    要启用 MOXy 作为您的 JAXB 提供程序,您需要在与域模型相同的包中包含一个名为 jaxb.properties 的文件,并使用以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)。

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    JSON 绑定

    MOXy 对 XML 和 JSON 绑定使用相同的管道。这意味着您将看到两者的相同事件行为。如果您没有看到事件,那么是 MOXy 以外的 JSON 绑定提供程序。

    【讨论】:

    • 我确实有 jaxb.properties 文件集和 web.xml 中的自定义应用程序 &lt;param-value&gt;rest.MyApplication&lt;/param-value&gt;。所以我认为 MOXy 是我的 JAXB 提供者。
    • @Imperative - 在beforeMarahal 方法中传递给你的Marshaller 的实现类是什么?如果是org.eclipse.persistence.jaxb.JAXBMarshaller,那么您使用的是MOXy
    • 它是org.eclipse.persistence.jaxb.JAXBMarshaller。我的目标是在我的 JAX-RS 服务器上处理对象时调用事件。您的演示运行良好,但是否可以将这种机制用于 JAX-RS?我问这个,因为我找不到任何样本。
    • @Imperative - 接下来几天我要离开。我将在星期二挖掘我的第一件事。
    猜你喜欢
    • 1970-01-01
    • 2014-04-07
    • 2013-03-28
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多