How do you marshall a parameterized type with JAX-WS / JAXB?
Consider the following classes (please assume public getter and setter methods for the private fields).
// contains a bunch of properties
public abstract class Person { private String name; }
// adds some properties specific to teachers
public class Teacher extends Person { private int salary; }
// adds some properties specific to students
public class Student extends Person { private String course; }
// adds some properties that apply to an entire group of people
public class Result<T extends Person> {
private List<T> group;
private String city;
// ...
}
We might have the following web service implementation annotated as follows:
@WebService
public class PersonService {
@WebMethod
public Result<Teacher> getTeachers() { ... }
@WebMethod
public Result<Student> getStudents() { ... }
}
The problem is that JAXB appears to marshall the Result object as a Result<Person>
instead of the concrete type. So the Result returned by getTeachers() is serialized as containing a List<Person>
instead of List<Teacher>
, and the same for getS开发者_JS百科tudents(), mutatis mutandis.
Is this the expected behavior? Do I need to use @XmlSeeAlso on Person?
Thanks!
LES
The answer to this one was rather tricky. It turns out that the version of jettison used by the jax-ws json plugin is a bit old (1.0-beta-1 IIRC). That particular version doesn't handle this case well (it crashes). If you do add the @XmlSeeAlso then the JSON marshalling will crash! Of course, this sucks!
I read on some forum (don't have the link - this is all from memory) that the jax-ws json plugin isn't actively maintained. If you try to 1) exclude the default jettison dependency from the jax-ws json depedency (assuming maven here) and add a newer version you get an error about JSONException not existing. Jax-ws json will NOT work with a newer version of jettison (I tried).
This is documented on another website (someone stated that they would like for someone to port jax-ws json to the latest jettison).
In the end, I switched to DWR for remoting. JAX-WS is best left for system-to-system (backend) integration. It's too heavy-weight for front-end stuff. DWR works AWESOMELY in this case.
Found link to forum I read: http://forums.java.net/jive/thread.jspa?messageID=384385 . Note that Collab.net is currently down for maintenance but they'll be back up soon.
As far as answering the general question (without the JAX-WS JSON plugin part), the answer is yes - you must use the @XmlSeeAlso annotation on the Person class. Otherwise the schema will only contain Person and not Teacher or Student elements. Only the elements defined in Person are marshalled without the @XmlSeeAlso annotation.
精彩评论