扩展第三方现有的 JAXB class
Extending third party existing JAXB class
我有一个提供一组 classes 的第三方库。这些 classes 包含一个 XML 结构的对象图,并使用 JAXB 进行 XML (un) 封送处理。假设我有 classes 汽车、车轴和轮胎。
Car 包含 Axle 列表,Axle 包含 Tire 列表。
轮胎看起来像
public class Tire {
private double width;
private double radius;
public double getWidth() {
return width;
}
public double getRadius() {
return radius;
}
}
现在我想给轮胎
添加一个叫压力的属性
public class PressurizedTire extends Tire {
private double pressure;
public PressurizedTire(Tire t, double pressure) {
this.width = t.getWidth();
this.radius = t.getRadius();
this.pressure = pressure;
}
}
我想使用 JAXB 反序列化包含汽车的 xml 文档,找到所有轮胎并将压力数据添加到每个轮胎。然后我想将消息重新序列化为 XML。目前,额外的 属性 压力在编组时会下降,对象结构会恢复到原来的形式。
向现有 JAXB 模型添加属性的最佳方法是什么 class?我不想扩展每个 class,我不确定是否要重建和修改 .xsd 来完成这个?
是的,你可以做到,it is called Adding behavior
to existing JAXB classes。
下面的例子取自上面link:(你需要做的就是@Override对象的创建也一样。如果你错过了它,它就不会工作)。
package org.acme.foo.impl;
class PersonEx extends Person {
@Override
public void setName(String name) {
if(name.length()<3) throw new IllegalArgumentException();
super.setName(name);
}
}
@XmlRegistry
class ObjectFactoryEx extends ObjectFactory {
@Override
Person createPerson() {
return new PersonEx();
}
}
我认为这应该可行
我刚刚尝试了以下 类:
@XmlAccessorType( XmlAccessType.FIELD )
public class Tire
{
double width;
double radius;
}
@XmlRootElement
@XmlAccessorType( XmlAccessType.FIELD )
public class Axle
{
@XmlElement( name = "tire" )
List<Tire> tires = new ArrayList<>();
}
@XmlAccessorType( XmlAccessType.FIELD )
public class PressurizedTire extends Tire
{
double pressure;
public PressurizedTire( Tire t, double pressure )
{
this.width = t.width;
this.radius = t.radius;
this.pressure = pressure;
}
}
和下面的代码
JAXBContext context = JAXBContext.newInstance( Axle.class, PressurizedTire.class );
Unmarshaller unmarshaller = context.createUnmarshaller();
String xml = "<axle><tire><width>2.0</width><radius>1.5</radius></tire><tire><width>2.5</width><radius>1.5</radius></tire></axle>";
Axle axle = (Axle) unmarshaller.unmarshal( new StringReader( xml ) );
List<Tire> pressurizedTires = new ArrayList<>();
for ( Tire tire : axle.tires )
{
pressurizedTires.add( new PressurizedTire( tire, 1.0 ) );
}
axle.tires = pressurizedTires;
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
marshaller.marshal( axle, System.out );
得到这个输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<axle>
<tire xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="pressurizedTire">
<width>2.0</width>
<radius>1.5</radius>
<pressure>1.0</pressure>
</tire>
<tire xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="pressurizedTire">
<width>2.5</width>
<radius>1.5</radius>
<pressure>1.0</pressure>
</tire>
</axle>
我有一个提供一组 classes 的第三方库。这些 classes 包含一个 XML 结构的对象图,并使用 JAXB 进行 XML (un) 封送处理。假设我有 classes 汽车、车轴和轮胎。
Car 包含 Axle 列表,Axle 包含 Tire 列表。
轮胎看起来像
public class Tire {
private double width;
private double radius;
public double getWidth() {
return width;
}
public double getRadius() {
return radius;
}
}
现在我想给轮胎
添加一个叫压力的属性public class PressurizedTire extends Tire {
private double pressure;
public PressurizedTire(Tire t, double pressure) {
this.width = t.getWidth();
this.radius = t.getRadius();
this.pressure = pressure;
}
}
我想使用 JAXB 反序列化包含汽车的 xml 文档,找到所有轮胎并将压力数据添加到每个轮胎。然后我想将消息重新序列化为 XML。目前,额外的 属性 压力在编组时会下降,对象结构会恢复到原来的形式。
向现有 JAXB 模型添加属性的最佳方法是什么 class?我不想扩展每个 class,我不确定是否要重建和修改 .xsd 来完成这个?
是的,你可以做到,it is called Adding behavior
to existing JAXB classes。
下面的例子取自上面link:(你需要做的就是@Override对象的创建也一样。如果你错过了它,它就不会工作)。
package org.acme.foo.impl;
class PersonEx extends Person {
@Override
public void setName(String name) {
if(name.length()<3) throw new IllegalArgumentException();
super.setName(name);
}
}
@XmlRegistry
class ObjectFactoryEx extends ObjectFactory {
@Override
Person createPerson() {
return new PersonEx();
}
}
我认为这应该可行
我刚刚尝试了以下 类:
@XmlAccessorType( XmlAccessType.FIELD )
public class Tire
{
double width;
double radius;
}
@XmlRootElement
@XmlAccessorType( XmlAccessType.FIELD )
public class Axle
{
@XmlElement( name = "tire" )
List<Tire> tires = new ArrayList<>();
}
@XmlAccessorType( XmlAccessType.FIELD )
public class PressurizedTire extends Tire
{
double pressure;
public PressurizedTire( Tire t, double pressure )
{
this.width = t.width;
this.radius = t.radius;
this.pressure = pressure;
}
}
和下面的代码
JAXBContext context = JAXBContext.newInstance( Axle.class, PressurizedTire.class );
Unmarshaller unmarshaller = context.createUnmarshaller();
String xml = "<axle><tire><width>2.0</width><radius>1.5</radius></tire><tire><width>2.5</width><radius>1.5</radius></tire></axle>";
Axle axle = (Axle) unmarshaller.unmarshal( new StringReader( xml ) );
List<Tire> pressurizedTires = new ArrayList<>();
for ( Tire tire : axle.tires )
{
pressurizedTires.add( new PressurizedTire( tire, 1.0 ) );
}
axle.tires = pressurizedTires;
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
marshaller.marshal( axle, System.out );
得到这个输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<axle>
<tire xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="pressurizedTire">
<width>2.0</width>
<radius>1.5</radius>
<pressure>1.0</pressure>
</tire>
<tire xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="pressurizedTire">
<width>2.5</width>
<radius>1.5</radius>
<pressure>1.0</pressure>
</tire>
</axle>