JAXB Marshall XML配置文件过滤器

时间:2015-04-29 14:14:46

标签: java xml jaxb marshalling

我需要使用JAXB将对象编组为XML。

Marshall / Unmarshall代码工作正常,但现在我们想要根据注释过滤生成的XML。

XmlProfile.java

@Retention (RUNTIME)
@Target({TYPE, METHOD, FIELD})
public @interface XmlProfile {
    String[] value();
}

FooPojo.java

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class FooPojo {

    @XmlElement
    @XmlProfile("config")
    public String bar;

    @XmlElement
    @XmlProfile("operational")
    public String bartender;

    @XmlElement
    @XmlProfile({"config", "operational"})
    public String spy;

}

我阅读了JAXB文档,但是我没有找到关于如何将一些代码注入到marshall进程中的示例/主题,不同于适配器或eventHandlers。

特别是我读到了关于事件处理程序的内容,但我发现的是在元帅之后/编组事件之后的支持。

我希望找到一个beforeFieldMarshal事件,但这是不可能的,所以我想编写一段扫描当前实体的代码,并将null设置为与当前配置文件不匹配的属性:

private class ProfileListener extends Marshaller.Listener {

    private String profile;

    public ProfileListener(String profile) {
        this.profile = profile;
    }

    @Override
    public void beforeMarshal(Object source) {
        if (source == null || profile == null || profile.length() == 0) return;

        Field[] fields = source.getClass().getFields();
        for (Field f : fields){
            XmlProfile xmlProfile = f.getAnnotation(XmlProfile.class);
            if (xmlProfile == null) continue;

            String[] annValues = xmlProfile.value();
            if (annValues == null 
                || annValues.length == 0 
                || findInArray(annValues)) {
                continue;
            }

            // Remove from object
            f.setAccessible(true);
            try {
                f.set(source, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        super.beforeMarshal(source); //To change body of generated methods, choose Tools | Templates.
    }

    private boolean findInArray(String[] annValues){
        for (String annVal : annValues) {
            if (profile.equalsIgnoreCase(annVal)){
                return true;
            }
        }
        return false;
    }

}

代码工作正常,也有嵌套对象,这是我获得的代码:

工作Pojo

FooPojo fooPojo = new FooPojo();
fooPojo.bar = "Tijuana Cafe";
fooPojo.bartender = "Cynthia";
fooPojo.spy = "Antony Fisco";
fooPojo.phone = "555 555 555";

**配置文件的结果XML:**

<fooPojo>
    <bar>Tijuana Cafe</bar>
    <spy>Antony Fisco</spy>
    <phone>555 555 555</phone>
</fooPojo>

**生成的操作配置文件的XML:**

<fooPojo>
    <bartender>Cynthia</bartender>
    <spy>Antony Fisco</spy>
    <phone>555 555 555</phone>
</fooPojo>

有一个功能错误,我不知道如何解决: POJO由代码更新,设置空属性。

有没有更好的方法呢?我最终可以克隆该对象并对其进行处理,但我不确定它是否正确。

0 个答案:

没有答案