我有一个JSON文件,我正在尝试使用JAXB注解方法将其转换为XML。现在一切正常,我能够将JSON转换为XML。现在,我正在尝试稍微重构一下代码,这样我的类看起来就更干净了。因此,我正在尝试删除我的class中存在的方法,并将其设置为JAXB XMLAdapter,以便其他类可以重用它。
基本上,我希望将XMLSupport方法从CarInfo类移动到XMLAdapter。当我将CarInfo对象移动到XMLAdapter时,我不确定如何填充它们。
以下是我的JSON文件(为简单起见,已对其进行了修改):
{
"brand": "Ferari",
"build": "Italy",
"engine": "Mercedes",
"year": "2021"
}下面是我期望JAXB提供的XML:(观察carInfo标记,它在JSON中不存在,但我需要在XML中匹配标准XSD)
<?xml version="1.0"?>
<Car>
<brand>Ferari</brand>
<build>Italy</build>
<carinfo>
<engine>Mercedes</engine>
<year>2021</year>
</carinfo>
</Car>以下是我拥有的类:(与JSON元素匹配的Car类)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlTransient
@XmlSeeAlso({MyCar.class});
public class Car{
private String brand;
private String build;
@XmlTransient
private String engine;
@XmlTransient
private String year;
//Getter, Setters and other consturctiores ommited
}下面是通过添加carInfo标记来构建XML的MYCar类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Car")
@XmlType(name = "Car", propOrder = {"brand","build", "carInfo"})
public class MyCar extends Car{
@XmlElement(name="carInfo")
private CarInfo carInfo;
public MyCar xmlSupport() {
if(carInfo == null){
carInfo = new Carinfo();
}
carInfo.setEngine(getEngine);
carInfo.setYear(getYear());
return this;
}
}下面是我的CarInfo类,它充当围绕MyCar类构建additional标记的帮助器:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"engine","year"})
public class Carinfo{
private String engine;
private String year;
//Getter, Setters and other consturctiores ommited
}下面是我的Main类,它使用JAXBCOntext实际构建XML
public class Main{
public static void main(String[] args){
JAXBContext context = JAXBContext.newInstance(MyCar.class);
Marshaller mar = context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
mar.marshal((MyCar).xmlSupport(), System.out);
System.out.println("-----------------");
}
}现在回到我的主要问题:正如我们从MyCar类中看到的,我有一个XMLSupport方法,它实际上填充了CarInfo对象,然后使用这个方法创建了XML。有没有办法把它移到XMLAdapter上?
我尝试创建XMLAdapter,但我不确定如何从适配器填充CarInfo对象:
public class MyCar extends Car{
@XmlElement(name="carInfo")
@XmlJavaTypeAdapter(ExtensionAdapter.class)
@XmlElement(name = "carInfo")
private CarInfo carInfo;
}下面是我尝试过的Adapter类:公共类ExtensionAdapter扩展了XmlAdapter {
@Override
public CarInfo unmarshal(CarInfo valueType) throws Exception {
System.out.println("UN-MARSHALLING");
return null;
}
@Override
public CarInfo marshal(CarInfo boundType) throws Exception {
System.out.println("MARSHALLING");
System.out.println(boundType);
//I get boundType as NULL so I am not sure how to convert the xmlSupport Method to Adapter so I can use this adapter with multiple class
return null;
}
}发布于 2021-04-28 22:05:48
你不需要任何适配器,你只需要一个定义良好的POJO。
诀窍是使用getter和setter,而不是字段访问,所以我们可以进行委托,然后使用@JsonIgnore和@XmlTransient来控制哪些getter/setter方法用于JSON vs XML。
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@XmlRootElement(name = "Car")
@XmlType(propOrder = { "brand", "build", "carinfo" })
@JsonPropertyOrder({ "brand", "build", "engine", "year" })
public final class Car {
@XmlType(propOrder = { "engine", "year" })
public static final class Info {
private String engine;
private String year;
public String getEngine() {
return this.engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
public String getYear() {
return this.year;
}
public void setYear(String year) {
this.year = year;
}
@Override
public String toString() {
return "Info[engine=" + this.engine + ", year=" + this.year + "]";
}
}
private String brand;
private String build;
private Info carinfo;
public Car() {
// Nothing to do
}
public Car(String brand, String build, String engine, String year) {
this.brand = brand;
this.build = build;
this.carinfo = new Info();
this.carinfo.setEngine(engine);
this.carinfo.setYear(year);
}
public String getBrand() {
return this.brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getBuild() {
return this.build;
}
public void setBuild(String build) {
this.build = build;
}
@JsonIgnore // For XML, not JSON
public Info getCarinfo() {
if (this.carinfo == null)
this.carinfo = new Info();
return this.carinfo;
}
public void setCarinfo(Info info) {
this.carinfo = info;
}
@XmlTransient // For JSON, not XML
public String getEngine() {
return getCarinfo().getEngine();
}
public void setEngine(String engine) {
getCarinfo().setEngine(engine);
}
@XmlTransient // For JSON, not XML
public String getYear() {
return getCarinfo().getYear();
}
public void setYear(String year) {
getCarinfo().setYear(year);
}
@Override
public String toString() {
return "Car[brand=" + this.brand + ", build=" + this.build + ", carinfo=" + this.carinfo + "]";
}
}测试
Car car = new Car("Ferari", "Italy", "Mercedes", "2021");
// Generate JSON
ObjectMapper jsonMapper = new ObjectMapper();
jsonMapper.enable(SerializationFeature.INDENT_OUTPUT);
String json = jsonMapper.writeValueAsString(car);
// Generate XML
JAXBContext jaxbContext = JAXBContext.newInstance(Car.class);
Marshaller xmlMarshaller = jaxbContext.createMarshaller();
xmlMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
String xml;
try (StringWriter writer = new StringWriter()) {
xmlMarshaller.marshal(car, writer);
xml = writer.toString();
}
// Print generated results
System.out.println(car);
System.out.println(json);
System.out.println(xml);
// Parse JSON
Car carFromJson = jsonMapper.readValue(json, Car.class);
System.out.println(carFromJson);
// Parse XML
Unmarshaller xmlUnmarshaller = jaxbContext.createUnmarshaller();
Car carFromXml = xmlUnmarshaller.unmarshal(new StreamSource(new StringReader(xml)), Car.class).getValue();
System.out.println(carFromXml);输出
Car[brand=Ferari, build=Italy, carinfo=Info[engine=Mercedes, year=2021]]{
"brand" : "Ferari",
"build" : "Italy",
"engine" : "Mercedes",
"year" : "2021"
}<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Car>
<brand>Ferari</brand>
<build>Italy</build>
<carinfo>
<engine>Mercedes</engine>
<year>2021</year>
</carinfo>
</Car>Car[brand=Ferari, build=Italy, carinfo=Info[engine=Mercedes, year=2021]]Car[brand=Ferari, build=Italy, carinfo=Info[engine=Mercedes, year=2021]]如您所见,生成的JSON和XML正是您想要的,输出的最后两行显示解析也是有效的。
https://stackoverflow.com/questions/67300882
复制相似问题