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互转的方法详解

posted @ 2020-12-14 23:55  strongmore  阅读(1242)  评论(1编辑  收藏  举报