51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Spring之Jackson-转换XML与Java对象的方法

简介 {#简介}

本文介绍使用Spring自带的Jackson转换XML与Java对象的方法。

XML与Java对象转换的方法有很多,最好的方法是使用Spring自带的XmlMapper,本文介绍此工具的用法。

XmlMapper类是 ObjectMapper类的子类,两者使用方式几乎一致。

依赖 {#依赖}

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>`
`<groupId>`com.fasterxml.jackson.dataformat`</groupId>`
`<artifactId>`jackson-dataformat-xml`</artifactId>`
`<!-- 版本由spring-boot-starter-parent指定-->`
`</dependency>`
`

jackson-dataformat-xml依赖了jackson-core、jackson-databind、jackson-annotations等,这些都在spring-boot-starter-web中引入了。

工具类 {#工具类}

package com.itjing.springboot.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.\*;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.itjing.springboot.entity.SchoolBO;
import com.itjing.springboot.entity.StudentBO;
import lombok.SneakyThrows;


import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**




* 
  xml工具类





* 


* 
  @author lijing





* 
  @date 2024-06-28
  \*/
  public class XmlUtil {
  private static final XmlMapper XML_MAPPER = createXmlMapper();



  /**



  * 创建一个配置好的XmlMapper实例。


  * 该方法配置了XmlMapper的各种设置,包括序列化和反序列化的行为。


  * 


  * @return 配置好的XmlMapper实例。
    */
    private static XmlMapper createXmlMapper() {
    // 创建一个XmlMapper实例,并通过builder模式进行配置。
    XmlMapper xmlMapper = XmlMapper.builder()
    // 忽略实体类没有对应属性。如果为 true 会抛出异常
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    //  忽略null
    .serializationInclusion(JsonInclude.Include.NON_NULL)
    // 属性使用 驼峰首字母小写
    .propertyNamingStrategy(PropertyNamingStrategies.LOWER_CAMEL_CASE)
    .defaultUseWrapper(false)
    .configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true)
    // 配置XmlMapper在序列化XML时包含XML声明。
    .configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true)
    // 配置XmlMapper在序列化时使用缩进,以美化输出。
    .enable(SerializationFeature.INDENT_OUTPUT)
    // 禁止忽略重复的模块注册,以确保后续注册的模块生效。
    .disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS)
    .build();
    // 注册自定义的模块,以扩展XmlMapper的功能。
    xmlMapper.registerModule(configTimeModule());
    // 返回配置好的XmlMapper实例。
    return xmlMapper;
    }




  /**



  * 
    配置Java时间模块,以支持序列化和反序列化Java 8的时间类。





  * 
    这个方法设置了DateTimeFormatter的模式,用于将LocalDateTime、LocalDate、LocalTime和Date类的对象





  * 
    序列化为JSON字符串,以及将JSON字符串反序列化为这些时间类的对象。





  * 


  * 
    @return 配置好的JavaTimeModule实例。
    \*/
    private static JavaTimeModule configTimeModule() {
    JavaTimeModule javaTimeModule = new JavaTimeModule();



    // 定义日期时间格式,用于序列化和反序列化
    String localDateTimeFormat = "yyyy-MM-dd HH:mm:ss";
    String localDateFormat = "yyyy-MM-dd";
    String localTimeFormat = "HH:mm:ss";
    String dateFormat = "yyyy-MM-dd HH:mm:ss";


    // 添加序列化器,用于将Java 8的时间类序列化为JSON字符串
    // 序列化
    javaTimeModule.addSerializer(
    LocalDateTime.class,
    new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(localDateTimeFormat)));
    javaTimeModule.addSerializer(
    LocalDate.class,
    new LocalDateSerializer(DateTimeFormatter.ofPattern(localDateFormat)));
    javaTimeModule.addSerializer(
    LocalTime.class,
    new LocalTimeSerializer(DateTimeFormatter.ofPattern(localTimeFormat)));
    javaTimeModule.addSerializer(
    Date.class,
    new DateSerializer(false, new SimpleDateFormat(dateFormat)));


    // 添加反序列化器,用于将JSON字符串反序列化为Java 8的时间类对象
    // 反序列化
    javaTimeModule.addDeserializer(
    LocalDateTime.class,
    new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(localDateTimeFormat)));
    javaTimeModule.addDeserializer(
    LocalDate.class,
    new LocalDateDeserializer(DateTimeFormatter.ofPattern(localDateFormat)));
    javaTimeModule.addDeserializer(
    LocalTime.class,
    new LocalTimeDeserializer(DateTimeFormatter.ofPattern(localTimeFormat)));
    javaTimeModule.addDeserializer(Date.class, new DateDeserializers.DateDeserializer() {
    @SneakyThrows
    @Override
    public Date deserialize(JsonParser jsonParser, DeserializationContext dc) {
    String text = jsonParser.getText().trim();
    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    return sdf.parse(text);
    }
    });


    return javaTimeModule;
    }






  /**



  * 将给定的对象转换为XML格式的字符串。


  * <p>


  * 使用Jackson库的XMLMapper将Java对象序列化为XML格式的字符串。


  * 此方法封装了序列化过程,并在发生异常时抛出运行时异常。


  * 


  * @param o 待转换为XML字符串的Java对象。


  * @return 对象的XML表示形式的字符串。


  * @throws RuntimeException 如果序列化过程中发生错误。
    */
    public static String toXml(Object o) {
    String xml = null;
    try {
    // 使用XML_MAPPER将对象序列化为XML字符串
    xml = XML_MAPPER.writeValueAsString(o);
    } catch (JsonProcessingException e) {
    // 在序列化过程中发生异常时,抛出运行时异常
    throw new RuntimeException(e);
    }
    return xml;
    }




  /**



  * 将XML格式的字符串转换为指定类型的对象。


  * <p>


  * 本方法使用Jackson库的XMLMapper来解析XML字符串,将其映射为Java对象。


  * 这种方式提供了便利的XML到对象的转换,适用于处理XML格式的数据。


  * 


  * @param xml 待转换的XML格式的字符串。


  * @param cls 指定转换后的对象类型,使用Class对象来表示。


  * @return 返回转换后的对象实例。


  * @throws RuntimeException 如果XML字符串无法解析为指定类型的对象,则抛出运行时异常。
    */
    public static <T> T toObject(String xml, Class<T> cls) {
    T t = null;
    try {
    // 使用XML_MAPPER的readValue方法将XML字符串转换为指定类型的对象。
    t = XML_MAPPER.readValue(xml, cls);
    } catch (JsonProcessingException e) {
    // 在解析过程中发生错误时,抛出运行时异常。
    throw new RuntimeException(e);
    }
    return t;
    }







}


测试 {#测试}

实体类 {#实体类}

  • @JacksonXmlRootElement:指定生成xml根标签的名字

    • 属性:namespace,localName
  • @JacksonXmlProperty:指定包装标签名,或者指定标签内部属性名

    • 属性:namespace,localName,isAttribute(default:false)
  • @JacksonXmlElementWrapper:可用于List等集合类,用来指定外围标签名

    • 属性:namespace,localName,useWrapping (default:true)
  • @JacksonXmlText:指定当前这个值,没有xml标签包裹。

    • 属性:namespace,localName
package com.itjing.springboot.entity;

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 lombok.Data;


import java.util.List;


/**




* @author lijing


* @date 2024-06-28
  */




@Data
@JacksonXmlRootElement(localName = "school")
public class SchoolBO {


    <span class="hljs-comment">// 可以指定XML标签的名字。若不指定,则为字段名</span>
    <span class="hljs-meta">@JacksonXmlProperty(localName = "SchoolName")</span>
    <span class="hljs-keyword">private</span> String schoolName;

    <span class="hljs-comment">// isAttribute 设为true时,该字段做为根标签的属性</span>
    <span class="hljs-meta">@JacksonXmlProperty(isAttribute = true)</span>
    <span class="hljs-keyword">private</span> Integer schoolId;

    <span class="hljs-keyword">private</span> String schoolEmail;

    <span class="hljs-keyword">private</span> String schoolAddress;

    <span class="hljs-comment">// 指定外层的XML标签名</span>
    <span class="hljs-meta">@JacksonXmlElementWrapper(localName = "studentList")</span>
    <span class="hljs-comment">// 指定单个元素的XML标签名</span>
    <span class="hljs-meta">@JacksonXmlProperty(localName = "student")</span>
    <span class="hljs-keyword">private</span> List&lt;StudentBO&gt; studentList;



`}
`

package com.itjing.springboot.entity;

import lombok.Data;

import java.time.LocalDateTime;

/**
 * @author lijing
 * @date 2024-06-28
 */
@Data
public class StudentBO {

    /**
     * 学生姓名
     */
    private String studentName;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

}

输出程序 {#输出程序}

public static void main(String[] args) {
    SchoolBO schoolBO = new SchoolBO();
    schoolBO.setSchoolId(222);
    schoolBO.setSchoolName("ABC中学");
    schoolBO.setSchoolEmail("aa@163.com");
    schoolBO.setSchoolAddress("A省B市");

    List&lt;StudentBO&gt; studentBOList = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();
    <span class="hljs-type">StudentBO</span> <span class="hljs-variable">student1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StudentBO</span>();
    student1.setStudentName(<span class="hljs-string">"Tony"</span>);
    student1.setCreateTime(LocalDateTime.now());

    <span class="hljs-type">StudentBO</span> <span class="hljs-variable">student2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StudentBO</span>();
    student2.setStudentName(<span class="hljs-string">"Peter"</span>);
    student2.setCreateTime(LocalDateTime.now().plusSeconds(<span class="hljs-number">2</span>));

    studentBOList.add(student1);
    studentBOList.add(student2);

    schoolBO.setStudentList(studentBOList);

    System.out.println(toXml(schoolBO));



`}
`

结果:

<?xml version='1.0' encoding='UTF-8'?>
<school schoolId="222">
  <schoolEmail>aa@163.com</schoolEmail>
  <schoolAddress>A省B市</schoolAddress>
  <SchoolName>ABC中学</SchoolName>
  <studentList>
    <student>
      <studentName>Tony</studentName>
      <createTime>2024-06-28 23:47:31</createTime>
    </student>
    <student>
      <studentName>Peter</studentName>
      <createTime>2024-06-28 23:47:33</createTime>
    </student>
  </studentList>
</school>
赞(3)
未经允许不得转载:工具盒子 » Spring之Jackson-转换XML与Java对象的方法