我有一个带有@XmlAccessorType(XmlAccessType.FIELD)
注释的班级,每个private
和protected
字段都注明了@XmlElement(name='...')
。
挑战:我可能想在稍后阶段重命名其中一个xml元素名称。这引出了我的问题。如果我创建一个子类,有没有办法覆盖/重新定义这些注释?
答案 0 :(得分:1)
虽然在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
finalName
和其他两个相关的SO问题。
答案 1 :(得分:1)
我先使用@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;
}
}
Class Car:
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;
}
}
Class 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
答案 2 :(得分:1)
我相信JaxB的某些实现允许XML配置覆盖注释。在这种情况下,这实际上是可能的。以下是Eclipslink的一篇文章,解释了如何做到这一点http://www.eclipse.org/eclipselink/documentation/2.4/solutions/jpatoxml004.htm
在我看来,您可以为要覆盖的JaxB文件构建XML配置。