Marshalling/Unmarshalling Java superclass and subclasses using JAXB

女生的网名这么多〃 提交于 2019-12-01 14:14:46

Thanks everyone for your input. I used feedback from all your answers but ultimately it was a combination of them that worked which is why I created a seperate answer for anyone who may have this problem in the future.

To get this to work I had to ensure that all getter methods within the super and sub classes being marhsalled/unmarshalled were annotated with @XmlElement. This would determine the XML tag for the corresponding variable.

@XmlElement (name = "OwnerID")
    public int getOwnerId()
    {
        return ownerId;
    }

The superclass had to be annotated with @XmlSeeAlso to bind the subclasses to it. i.e In my code RoadVehicle was the superclass and both the Car and Van classes extended it.

@XmlSeeAlso({Car.class, Van.class})
public class Vehicle
{

With the super and subclasses now annotated the only other class that required annotations was the list class (Garage in my code). The changes here would determine what the XML tags were populated with.

The root XML tag was set by applying the @XmlRootElement annotation to the top of the class. i.e. "Vehicle" would be the root XML tag in my example.

@XmlRootElement(name = "Vehicle")
public class Garage
{

Finally an @XmlElements list had to be declared with an @XmlElements annotation for each sub class that required an XML tag with the name supplying the name of the XML tag. This list had to be declared above the getter method for the collection.

@XmlElements
    ({
        @XmlElement(name = "Car", type = Car.class, required = false),
        @XmlElement(name = "Van", type = Van.class, required = false)
    })    
    public List<Vehicle> getListOfVehicles()
    {
        return vehicleCollection;
    }

you are on right track. May something below will help

@XmlRootElement(name = "car")
public class Car extends BasicType{

}

@XmlRootElement(name = "van")
public class Van extends BasicType{

}

@XmlRootElement(name = "vehicle")
    public class Vehicle {
         List<BasicType> basicType;


    }

The simplest solution is to have different subclasses for cars and vans, even it they don't add anything to the base classes. Then, the root element class contains a list of the base class, with element QNames identifying the actual class.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Vehicle")
public class Vehicle {
    @XmlElements({
        @XmlElement(name = "Car", type = Car.class, required = false),
        @XmlElement(name = "Van", type = Van.class, required = false)
    })
    protected List carOrVan;
    public List getCarOrVan() {
        if (carOrVan == null) {
            carOrVan = new ArrayList();
        }
        return this.carOrVan;
    }
}

Here's the base class and the subclasses:

public class Basic {
    private String regplate;
    private String color;
    private String energyrating;

    public String getRegplate(){ return regplate; }
    public void setRegplate( String v ){ regplate = v; }
    public String getColor(){ return color; }
    public void setColor( String v ){ color = v; }
    public String getEnergyrating(){ return energyrating; }
    public void setEnergyrating( String v ){ energyrating = v; }
}

public class Car extends Basic {}

public class Van extends Basic {}

This will go smoothly if cars and vans develop into distinct subclasses.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!