By using @XmlSeeAlso on a class, sub types of the bound class can be listed thereby allowing them to be bound also and therefore reachable by JAX-WS when marshalling and unmarshalling.
It can also be used to overcome the problem of using generics in a JAXB annotated class as the following simple example will describe. Given the below LogFile class, it will only be marshalled/unmarshalled if the T at runtime is bound.
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class LogFile<T> { @XmlElement(name="logFileLine") private List<T> logFileLines; public LogFile() { logFileLines = new ArrayList<T>(); } public LogFile(List<T> logFileLines) { this.logFileLines = logFileLines; } public List<T> getLogFileLines() { return logFileLines; } public void setLogFileLines(List<T> logFileLines) { this.logFileLines = logFileLines; } public void addLogFileLine(T logFileLine) { this.logFileLines.add(logFileLine); } }
If LogFile contains a collection of eg Strings then this will work fine but if T is a class not bound, eg com.city81.domain.LogLine then an error similar to below will be thrown:
javax.xml.bind.MarshalException - with linked exception: [javax.xml.bind.JAXBException: class com.city81.domain.LogLine nor any of its super class is known to this context.]
To resolve this, the class LogLine needs to be included the @XmlSeeAlso annotation.
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlSeeAlso(LogLine.class) public class LogFile<T> { .... }
This does of course mean you need to know what potential classes can be T before runtime but at least it means you can use Generics on JAXB annotated classes.
No comments:
Post a Comment
Note: only a member of this blog may post a comment.