我需要在一个类被解组后对它执行某些操作 (在由JAXB构建之后,而不是由我自己构建)。
JAXB中是否有这样的功能?
如果没有,我怎么能实现它?
答案 0 :(得分:5)
您可以使用'class defined'事件回调。
在这里阅读更多http://java.sun.com/javase/6/docs/api/javax/xml/bind/Unmarshaller.html#unmarshalEventCallback
例如,将此方法放在JAXB对象中:
//This method is called after all the properties (except IDREF) are unmarshalled for this object, //but before this object is set to the parent object. void afterUnmarshal( Unmarshaller u, Object parent ) { System.out.println( "After unmarshal: " + this.state ); }
答案 1 :(得分:3)
尽管JAXB中似乎没有要求的功能,但我还是成功了 实现朝着正确方向发展的事情:
@PostConstruct
注释
(它只是一个缺乏注释,JSR没有提供任何功能)@PostConstruct
注释
<强>测试。作品。强>
这是代码。对不起,我正在使用一些外部反射API来获取所有方法,但我认为这个想法是可以理解的:
JAXBContext context = // create the context with desired classes
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setListener(new Unmarshaller.Listener() {
@Override
public void afterUnmarshal(Object object, Object arg1) {
System.out.println("unmarshalling finished on: " + object);
Class<?> type = object.getClass();
Method postConstructMethod = null;
for (Method m : ReflectionUtils.getAllMethods(type)) {
if (m.getAnnotation(PostConstruct.class) != null) {
if (postConstructMethod != null) {
throw new IllegalStateException(
"@PostConstruct used multiple times");
}
postConstructMethod = m;
}
}
if (postConstructMethod != null) {
System.out.println("invoking post construct: "
+ postConstructMethod.getName() + "()");
if (!Modifier.isFinal(postConstructMethod.getModifiers())) {
throw new IllegalArgumentException("post construct method ["
+ postConstructMethod.getName() + "] must be final");
}
try {
postConstructMethod.setAccessible(true); // thanks to skaffman
postConstructMethod.invoke(object);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}
}
});
修改强>
添加了对@PostConstruct
- 注释方法的检查,以确保它是最终的
你认为这是一个有用的限制吗?
以下是该概念的使用方法。
@XmlAccessorType(XmlAccessType.NONE)
public abstract class AbstractKeywordWithProps
extends KeywordCommand {
@XmlAnyElement
protected final List<Element> allElements = new LinkedList<Element>();
public AbstractKeywordWithProps() {
}
@PostConstruct
public final void postConstruct() {
// now, that "allElements" were successfully initialized,
// do something very important with them ;)
}
}
// further classes can be derived from this one. postConstruct still works!
答案 2 :(得分:0)
这不是100%的解决方案,但您始终可以使用XmlAdapter
注册@XmlJavaTypeAdapter annotation
对于这种类型。
缺点是你必须自己序列化这个类(?)。我不知道访问和调用默认序列化机制的任何简单方法。但是使用自定义[XmlAdapter
],您可以控制序列化的类型以及在它之前/之后发生的事情。