@XmlSeeAlso alternative

I have the following:

class A{ @XmlElement String name; //getters and setters } 

and

 class B extends A{ @XmlElement String height; //getters and setters } 

Finally i

 @XmlRootElement class P{ @XmlElement List<A> things; //getters and setters } 

If i do

 List<A> l = new ArrayList<A>(); l.add(new B('hello', 20)) //Add new B with height of 20 and name hello P p = new P(); p.setThings(l); //Set things to list of B's. 

and Marshal P, I only get the field as part of things, not the height.

I know that I can add @XmlSeeAlso (B.class) to A and everything will work.

But the problem is that I do not know all the extended classes other than B, since A can be extended at runtime.

How do I dynamically detect @XmlSeeAlso at runtime?

+6
source share
2 answers

It depends on how you create the JAXBContext . the newInstance method can be called with an explicit list of all your classes, the documentation for this method also gives a similar example.

The client application should provide a list of classes that the new context object should recognize. Not only does the new context recognize all the specified classes, but it also recognizes any classes that directly / indirectly refer statically to the specified classes. Referenced subclasses and referenced @XmlTransient classes are not registered with JAXBContext. For example, in the following Java code, if you do newInstance (Foo.class), the newly created JAXBContext recognizes both Foo and Bar, but not Zot or FooBar:

 class Foo { @XmlTransient FooBar c; Bar b; } class Bar { int x; } class Zot extends Bar { int y; } class FooBar { } 

Edit: If you know at least the package names of potential jaxb classes, you can also create a context based on the context path .

If the above is not possible, you can also create a list of classes at runtime based on the object you want to serialize. I think it would be better to try reorganizing your code to make it unnecessary. The code below is not verified:

 Set<Class> classes = new HashSet<Class>(); classes.add(p.getClass()); for (A a : p.getThings()) { classes.add(a.getClass()); } JAXBContext context = JAXBContext.newInstance(classes.toArray(new Class[classes.size()])); 
+2
source

Please note that @XmlSeeAlso can also be annotated in the web service, see this post: http://weblogs.java.net/blog/kohlert/archive/2006/10/jaxws_and_type.html

This is useful if your base class does not have access to subclasses (for example, because they are in another module), but your web service does.

+1
source

Source: https://habr.com/ru/post/902706/


All Articles