簡介
JAXB(Java Architecture for XML Binding) 是一個業界的標准,是一項可以根據XML Schema產生Java類的技術。該過程中,JAXB也提供了將XML實例文檔反向生成Java對象樹的方法,並能將Java對象樹的內容重新寫到XML實例文檔。從另一方面來講,JAXB提供了快速而簡便的方法將XML模式綁定到Java表示,從而使得Java開發者在Java應用程序中能方便地結合XML數據和處理函數。
bean轉xml
java在1.6之后內置了jaxb的實現,但在11中已經去除了,需要我們手動導入依賴
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
代碼實現
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
public class Client {
public static void main(String[] args) throws Exception {
User user = new User();
user.setUserId("1");
user.setUsername("lisi");
user.setPassword("123456");
user.setAddress(new Address("山東", "濟南"));
user.setHobbyList(Arrays.asList(new Hobby("游泳"), new Hobby("跑步")));
System.out.println(bean2Xml(user));
}
/**
* 將javabean轉換成xml字符串
*/
private static String bean2Xml(Object obj) throws Exception {
//獲取上下文
final JAXBContext context = JAXBContext.newInstance(obj.getClass());
//創建一個將bean序列化成xml的對象
Marshaller marshaller = context.createMarshaller();
//格式化輸出
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//設置編碼
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
StringWriter writer = new StringWriter();
//序列化
marshaller.marshal(obj, writer);
return writer.toString();
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"username", "password", "address", "hobbyList"})
@XmlRootElement(name = "User")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class User {
@XmlAttribute(name = "userId")
private String userId;
@XmlElement(name = "username")
private String username;
@XmlElement(name = "password")
private String password;
@XmlElement(name = "address")
private Address address;
@XmlElement(name = "hobby")
@XmlElementWrapper(name = "hobbyList")
private List<Hobby> hobbyList;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "address")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Address {
private String province;
private String city;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "hobby")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Hobby {
private String name;
}
}
輸出結果為
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<User userId="1">
<username>lisi</username>
<password>123456</password>
<address>
<province>山東</province>
<city>濟南</city>
</address>
<hobbyList>
<hobby>
<name>游泳</name>
</hobby>
<hobby>
<name>跑步</name>
</hobby>
</hobbyList>
</User>
- @XmlAccessorType,必填,FIELD表示每一個非靜態的,非瞬時的(@XmlTransient標注)屬性
- @XmlType,非必填,控制屬性的排序
- @XmlRootElement,必填,表示xml的根元素
- @XmlAttribute,表示xml屬性
- @XmlElement,表示xml元素
- @XmlElementWrapper,表示一個數組或集合的包裝器
xml轉bean
import java.io.StringReader;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
public class Client {
public static void main(String[] args) throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+ "<User userId=\"1\">\n"
+ " <username>lisi</username>\n"
+ " <password>123456</password>\n"
+ " <address>\n"
+ " <province>山東</province>\n"
+ " <city>濟南</city>\n"
+ " </address>\n"
+ " <hobbyList>\n"
+ " <hobby>\n"
+ " <name>游泳</name>\n"
+ " </hobby>\n"
+ " <hobby>\n"
+ " <name>跑步</name>\n"
+ " </hobby>\n"
+ " </hobbyList>\n"
+ "</User>";
System.out.println(xml2Bean(xml, User.class));
}
/**
* 將xml字符串轉換成javabean
*/
private static <T> T xml2Bean(String xml, Class<T> clazz) throws Exception {
//獲取上下文
final JAXBContext context = JAXBContext.newInstance(clazz);
//創建一個xml轉換成bean的對象
Unmarshaller unmarshaller = context.createUnmarshaller();
//反序列化
return clazz.cast(unmarshaller.unmarshal(new StringReader(xml)));
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "User")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class User {
@XmlAttribute(name = "userId")
private String userId;
@XmlElement(name = "username")
private String username;
@XmlElement(name = "password")
private String password;
@XmlElement(name = "address")
private Address address;
@XmlElement(name = "hobby")
@XmlElementWrapper(name = "hobbyList")
private List<Hobby> hobbyList;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "address")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Address {
private String province;
private String city;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "hobby")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Hobby {
private String name;
}
}
使用jackson將bean轉xml
引入依賴
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.11.3</version>
</dependency>
代碼實現
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.Arrays;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
public class Client {
public static void main(String[] args) throws Exception {
User user = new User();
user.setUserId("1");
user.setUsername("lisi");
user.setPassword("123456");
user.setAddress(new Address("山東", "濟南"));
user.setHobbyList(Arrays.asList(new Hobby("游泳"), new Hobby("跑步")));
System.out.println(bean2Xml(user));
}
/**
* 將javabean轉換成xml字符串
*/
private static String bean2Xml(Object obj) throws Exception {
XmlMapper mapper = new XmlMapper();
//格式化輸出
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
}
@JacksonXmlRootElement(localName = "user")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class User {
@JacksonXmlProperty(isAttribute = true)
private String userId;
@JacksonXmlProperty(localName = "userName")
private String username;
private String password;
private Address address;
@JacksonXmlProperty(localName = "hobby")
@JacksonXmlElementWrapper(localName = "hobbyList")
private List<Hobby> hobbyList;
}
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Address {
private String province;
private String city;
}
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Hobby {
private String name;
}
}
輸出結果同上
- @JacksonXmlRootElement,非必填,類似jaxb的@XmlRootElement
- @JacksonXmlProperty,isAttribute表示是否為屬性,為jaxb的@XmlElement和@XmlAttribute的組合
- @JacksonXmlElementWrapper,子元素包裝器,類似jaxb的@XmlElementWrapper
使用jackson將xml轉bean
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
public class Client {
public static void main(String[] args) throws Exception {
String xml = "<user userId=\"1\">\n"
+ " <password>123456</password>\n"
+ " <address>\n"
+ " <province>山東</province>\n"
+ " <city>濟南</city>\n"
+ " </address>\n"
+ " <userName>lisi</userName>\n"
+ " <hobbyList>\n"
+ " <hobby>\n"
+ " <name>游泳</name>\n"
+ " </hobby>\n"
+ " <hobby>\n"
+ " <name>跑步</name>\n"
+ " </hobby>\n"
+ " </hobbyList>\n"
+ "</user>";
System.out.println(xml2Bean(xml, User.class));
}
/**
* 將xml字符串轉換成javabean
*/
private static <T> T xml2Bean(String xml, Class<T> clazz) throws Exception {
XmlMapper mapper = new XmlMapper();
return mapper.readValue(xml, clazz);
}
@JacksonXmlRootElement(localName = "user")
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class User {
@JacksonXmlProperty(isAttribute = true)
private String userId;
@JacksonXmlProperty(localName = "userName")
private String username;
private String password;
private Address address;
@JacksonXmlProperty(localName = "hobby")
@JacksonXmlElementWrapper(localName = "hobbyList")
private List<Hobby> hobbyList;
}
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Address {
private String province;
private String city;
}
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public static class Hobby {
private String name;
}
}