java中bean和xml相互轉換


簡介

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;
  }
}

參考

JavaBean與xml互轉的方法詳解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM