如何从使用Simple的自定义Converter访问字段注释?
我正在使用Simple(http://simple.sourceforge.net/)库来编组/解组Java中的XML数据。 对于我的一些更复杂的数据结构,我需要编写自己的转换器。 例如,假设我有一个List<List>
我需要编组。 我写了以下内容:
class WorldObject { @Element(name="vector-names") @Convert(ListListConverter.class) private List<List> vectorNames; /** Constructor and other details ... **/ }
与ListListConverter一起(我暂时遗漏了unmarshaller):
class ListListConverter implements Converter<List<List>> { @Override public List<List> read(InputNode node) throws Exception { // stub return null; } @Override public void write(OutputNode node, List<List> value) throws Exception { node.setName("list-list-string"); for (List list : value) { OutputNode subList = node.getChild("list-string"); for (String str : list) { OutputNode stringNode = subList.getChild("string"); stringNode.setValue(str); } subList.commit(); } node.commit(); } }
此设置工作正常,并生成我想要的XML。 但是,我想访问@Element
注释的name
字段,以便我可以为标记指定名称(在本例中为"vector-names"
)而不是默认名称( "list-list-string"
)。 这就是编组适用于Simple处理开箱即用的所有类型的方式,因此必须有一种方法可以从自定义Converter访问该数据。
我怎么能做到这一点?
您无法以这种方式获取注释,因为它无法通过字段转换器中的字段访问。
解决方案是编写WorldObject
-Converter – 即使您只想编写单个字段。
WorldObject
类:
@Root @Convert(WorldObjectConverter.class) // specify converter for this class public class WorldObject { @Element(name = "vector-names") private List> vectorNames; // only for the example below - write whatever constructor(s) you need public WorldObject() { this.vectorNames = new ArrayList<>(); } // constructor, getter / setter, etc. // a getter is required to access the field in the converter. public List> getVectorNames() { return vectorNames; } }
WorldObjectConverter
类:
public class WorldObjectConverter implements Converter { @Override public WorldObject read(InputNode node) throws Exception { throw new UnsupportedOperationException("Not supported yet."); } @Override public void write(OutputNode node, WorldObject value) throws Exception { final Field f = value.getClass().getDeclaredField("vectorNames"); // get the field 'vectorNames' of the 'WorldObject' class final Element elementAnnotation = f.getAnnotation(Element.class); // get the 'Element' annotation of the Field final String name = elementAnnotation.name(); // get the 'name'-value of the annotation node.setName(name); // set Nodename for( List list : value.getVectorNames() ) { OutputNode subList = node.getChild("list-string"); for( String str : list ) { OutputNode stringNode = subList.getChild("string"); stringNode.setValue(str); } subList.commit(); } node.commit(); } }
例:
final File f = new File("test.xml"); // output file WorldObject wo = new WorldObject(); // the object to serialize // some testdata ... List l = new ArrayList<>(); l.add("a"); l.add("b"); wo.getVectorNames().add(l); l = new ArrayList<>(); l.add("c"); l.add("d"); wo.getVectorNames().add(l); // create the serializer - dont forget the AnnotationStrategy! Serializer ser = new Persister(new AnnotationStrategy()); ser.write(wo, f); // serialize it to file
输出:
a b c d
完成!