2

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

@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 事件。

4

1 回答 1

1

更新

MOXy 中有一个错误(参见:http : //bugs.eclipse.org/412417),它会阻止在诸如 GlassFish 等 OSGi 环境中调用 marshal/unmarshal 方法。这现在已在 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 绑定提供程序。

于 2013-07-05T14:16:01.420 回答