用FIELD访问器类型重写@XmlElement注释



我有一个@XmlAccessorType(XmlAccessType.FIELD)注释的类,每个privateprotected字段都用@XmlElement(name='...')注释。

挑战:我可能希望在稍后阶段重命名其中一个xml元素名称。这让我想到了一个问题。如果我创建一个子类,是否有办法重写/重新定义这些注释?

我相信JaxB的一些实现允许XML配置覆盖注释。在这种情况下,这实际上是可能的。这是一篇来自Eclipslink的文章,解释了如何做到这一点http://www.eclipse.org/eclipselink/documentation/2.4/solutions/jpatoxml004.htm

在我看来,您可以为要覆盖的JaxB文件构建一个XML配置。

我首先尝试用@XmlAccessorType(XmlAccessType.FIELD)@XmlTransient隐藏。这只有在你用@XmlTransient标记父类和子类中的字段时才有效。但我想,这不是你想要的。

作为第二种方法,我在超类中尝试了更严格的@XmlAccessorType(XmlAccessType.PROPERTY),在子类中尝试了@XmlAccessorType(XmlAccessType.NONE)。请看我的例子:

package com.so.example;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/myresource")
public class MyResource {
    @GET
    @Path("/car")
    @Produces(MediaType.APPLICATION_XML)
    public Car getCar() {
        Car car = new Car();
        car.setWheels(4);
        return car;
    }
    @GET
    @Path("/suv")
    @Produces(MediaType.APPLICATION_XML)
    public Suv getSuv() {
        Suv suv = new Suv();
        List<String> bigWheels = new ArrayList<>();
        bigWheels.add("left front wheel");
        bigWheels.add("right front wheel");
        bigWheels.add("left rear wheel");
        bigWheels.add("right rear wheel");
        suv.setBigWheels(bigWheels);
        return suv;
    }
}

汽车类:

package com.so.example;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlRootElement
public class Car {
    protected Integer wheels;
    public Car() {
    }
    @XmlElement(name = "wheels", nillable = true)
    public Integer getWheels() {
        return wheels;
    }
    public void setWheels(Integer wheels) {
        this.wheels = wheels;
    }
}

类别Suv (Child):

package com.so.example;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Suv extends Car {
    @XmlTransient
    private Integer wheels;
    private List<String> bigWheels;
    public Suv() {
    }
    @Override
    @XmlTransient
    public Integer getWheels() {
        return wheels;
    }
    @Override
    public void setWheels(Integer wheels) {
        this.wheels = wheels;
    }
    @XmlElement
    public List<String> getBigWheels() {
        return bigWheels;
    }
    public void setBigWheels(List<String> bigWheels) {
        this.bigWheels = bigWheels;
    }
}

"隐藏"超类的元素轮的一种方法是将其标记为"nillable=true",并且不使用基本类型。在本例中,字段轮将被编组到<wheels xsi:nil="true"/>

如果可以不使用父类进行封送,而只使用子类,则可以使用下面描述的方法:

http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html

你也可以使用moxy并指定一个自定义绑定:http://www.eclipse.org/eclipselink/documentation/2.4/moxy/runtime003.htm

而在java中,据我所知,重写注释@XmlElement(name='...')以改变name属性是不可能的;你可以在你的代码中创建一个全局变量,并在@XmlElement(name='...')之后通过你的类或函数传递它。

在下面的代码中,我创建了一个类,但它包含了setter和getter方法,如果你想把它传递给另一个类

@XMLAccessorType(XMLAccessType.FIELD)
public class YourClass {
    @XmlTransient
    private String string = ""; //This can be replaced with whatever variable you are manipulating
                                //That could be an int or a file or anything really
    @XmlElement(name = "your_name")
    private void doSomething() {
        String temp = getString(); //This variable is normally used to pass between different
                                   //classes but may as well use it if you have one
        //Your code which manipulates the String
        setString(temp); //This variable is normally used to pass between different classes but
                         //may as well use it if you have one
    }

    @XmlElement(name = "your_other_name")
    private void doSomethingElse() {
        String temp = getString();
        //Your code which manipulates the String
        setString(temp);
    }
    public void getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }
}

我建议查看@XmlTransient的Java文档和其他两个相关的SO问题。

如何重写JAXB @XMLAccessorType(XMLAccessType.FIELD)指定在类级别与@XMLElement getter方法上的属性?

Jaxb -重写XMLElement name属性

最新更新