使用注解标注需要被转化的Java类
@XmlRootElement(name = "Car")
public class Car {
private String carName;
private String carType;
private Driver driver;
private List<Driver> driverList;
@XmlElement(name = "drivers")
public List<Driver> getDriverList() {
return driverList;
}
public void setDriverList(List<Driver> driverList) {
this.driverList = driverList;
}
public Driver getDriver() {
return driver;
}
public void setDriver(Driver driver) {
this.driver = driver;
}
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
public String getCarType() {
return carType;
}
public void setCarType(String carType) {
this.carType = carType;
}
}
@XmlRootElement
public class Driver {
private String driverName;
private String driverAge;
public String getDriverName() {
return driverName;
}
public void setDriverName(String driverName) {
this.driverName = driverName;
}
public String getDriverAge() {
return driverAge;
}
public void setDriverAge(String driverAge) {
this.driverAge = driverAge;
}
}
实例中仅用了最简单的注解使用方法,即先用@XmlRootElement标注在类名上,默认会使用类名作为xml根节点,可以使用name属性指定标签名称。@XmlElement则标注在属性上用来定义子标签。更多详细的注解请参考https://zhuanlan.zhihu.com/p/343893930。
bean转xml方法
public static void main(String[] args) throws JAXBException {
Car car = new Car();
car.setCarName("123");
car.setCarType("456");
Driver driver = new Driver();
driver.setDriverName("abc");
driver.setDriverAge("def");
Driver driver2 = new Driver();
driver2.setDriverName("abcd");
driver2.setDriverAge("defg");
car.setDriver(driver);
car.setDriverList(Arrays.asList(driver,driver2));
JAXBContext context = JAXBContext.newInstance(Car.class);
Marshaller marshaller = context.createMarshaller();
//格式化输出
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//去掉xml头
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
StringWriter writer = new StringWriter();
marshaller.marshal(car,writer);
System.out.println(writer.toString());
}
转换后结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Car>
<carName>123</carName>
<carType>456</carType>
<driver>
<driverAge>def</driverAge>
<driverName>abc</driverName>
</driver>
<drivers>
<driverAge>def</driverAge>
<driverName>abc</driverName>
</drivers>
<drivers>
<driverAge>defg</driverAge>
<driverName>abcd</driverName>
</drivers>
</Car>
xml转bean
public static Object xmlStrToOject(Class<?> clazz, String xmlStr) throws Exception {
Object xmlObject = null;
Reader reader = null;
JAXBContext context = JAXBContext.newInstance(clazz);
// XML 转为对象的接口
Unmarshaller unmarshaller = context.createUnmarshaller();
reader = new StringReader(xmlStr);
xmlObject = unmarshaller.unmarshal(reader);
if (null != reader) {
reader.close();
}
return xmlObject;
}
入参分别为要转换为的bean的class与xml串,如果xml标签中不包含任何命名空间则可以使用上面的方法,若xml中存在标签(例如标签<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
)则需要参考下面的方法:
public static Object xmlStrToOject(Class<?> clazz, String xmlStr) throws Exception {
Object xmlObject = null;
Reader reader = null;
JAXBContext context = JAXBContext.newInstance(Car.class);
// XML 转为对象的接口
Unmarshaller unmarshaller = context.createUnmarshaller();
// reader = new StringReader(xml1);
reader = new StringReader(xml2);
//忽视标签上的命名空间
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(false);
XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
SAXSource saxSource = new SAXSource(xmlReader, new InputSource(reader));
//无命名空间的xml可直接转换,否则报错
// xmlObject = unmarshaller.unmarshal(reader);
xmlObject = unmarshaller.unmarshal(saxSource);
if (null != reader) {
reader.close();
}
return xmlObject;
}
若命名空间格式不正确例如xml报文是截取出来的,这个方法同样会报错,此时可以借助dom4j Element的remove(Attribute attr)方法去掉不规范的命名空间(不匹配的命名空间会被识别为属性)。
截取xml可以用dom4j Element的asXml()方法截取。
如果xml中某个多次出现的标签被映射到bean的一个非数组属性中时,会使用最后出现的标签赋值。
注意点
在使用jaxb时尽量不配合lombook使用,lombook在生成get方法时的方法名称会引起冲突导致重复内容的标签出现。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。