javawsdlxsdwsgen

wsgen: returning an abstract class


I wrote an abstract class

import javax.xml.bind.annotation.*;
public abstract class Parent
    {
    @XmlAttribute(name = "one")
    public String getOne() { return "one";}
    }

and two derived classes:

import javax.xml.bind.annotation.*;
@XmlRootElement(name="child1")
public class Child1 extends Parent
    {
    @XmlAttribute(name = "two")
    public String getTwo() { return "2";}
    }



import javax.xml.bind.annotation.*;
@XmlRootElement(name="child2")
public class Child2 extends Parent
    {
    @XmlAttribute(name = "three")
    public String getThree() { return "3";}
    }

and a @webservice:

import javax.xml.ws.Endpoint;
import javax.jws.*;
import java.util.*;

@WebService(serviceName="MyServerService", name="MyServer")
public class MyServer
    {
        private int count=0;
    @WebResult(name="test")
        @WebMethod
    public Parent getOne() { return ++count%2==0?new Child1():new Child2();}

    public static void main(String[] args) {

      Endpoint.publish(
            "http://localhost:8080/path",
            new MyServer());

        }
    }

When the code is generated using wsgen, the resulting XML schema only contains the definition for the abstract class Parent but not for Child1 or Child2. Is there any way to tell wsgen to generate the definition for the two concrete classes ?

Thanks,


Solution

  • Adding an annotation @XmlSeeAlso should do the trick:

    @XmlSeeAlso({Child1.class, Child2.class})
    public abstract class Parent {
        @XmlAttribute(name = "one")
        public String getOne() { 
           return "one";
        }
    }
    

    If you prefer not to make parent class aware of its subclasses you can put that annotation on the WS level as well:

    @WebService(serviceName="MyServerService", name="MyServer")
    @XmlSeeAlso({Child1.class, Child2.class})
    public class MyServer {
        private int count=0;
    
        @WebResult(name="test")
        @WebMethod
        public Parent getOne() { 
            return ++count%2==0?new Child1():new Child2();
        }
    
        public static void main(String[] args) {
            Endpoint.publish("http://localhost:8080/path", new MyServer());
        }
    }
    

    Interesting information about this behavior you can find here