我需要使用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由代码更新,设置空属性。
有没有更好的方法呢?我最终可以克隆该对象并对其进行处理,但我不确定它是否正确。