You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Jackson 3及Spring Boot 4环境下自定义XML序列化的正确实现方式咨询

Jackson 3及Spring Boot 4环境下自定义XML序列化的正确实现方式咨询

各位好,最近升级到Jackson 3和Spring Boot 4之后,原来用来自定义XML序列化的配置代码跑不通了,折腾了半天还是卡壳,想请教下正确的实现方式。

先给大家看下升级前能正常工作的代码:

升级前(Jackson <3、Spring Boot <4)的可用代码:

import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;

@Configuration
public class XmlSerialization {
 
     @Bean("mappingJackson2XmlHttpMessageConverter")
     public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter() {
        JacksonXmlModule customModule = new JacksonXmlModule();
        customModule.addSerializer(new CustomListSerializer());
 
        XmlMapper xmlMapper = new XmlMapper(customModule);
 
        return new MappingJackson2XmlHttpMessageConverter(xmlMapper);
     }
 }

我自己尝试适配升级后的API,写出了下面的代码,但发现XmlModule里根本没有addSerializer()方法,直接卡在这里:

import org.springframework.http.converter.xml.JacksonXmlHttpMessageConverter;
import tools.jackson.dataformat.xml.XmlModule;
import tools.jackson.dataformat.xml.XmlMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class XmlSerialization {

    @Bean("mappingJackson2XmlHttpMessageConverter")
    public JacksonXmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter() {
        XmlModule customModule = new XmlModule();
        // 这里直接报错:XmlModule找不到addSerializer()方法
        customModule.addSerializer(new CustomListSerializer());

        XmlMapper xmlMapper = XmlMapper.builder().addModule(customModule).build();

        return new JacksonXmlHttpMessageConverter(xmlMapper);
    }
}

正确的实现方式

其实Jackson 3对模块体系做了重构,XmlModule作为XML格式的核心内置模块,现在不推荐直接实例化并修改它,而且它的API也做了调整。给你两种可行的解决方案:

方案一:用SimpleModule封装自定义序列化器

这是最规范的方式,适合需要注册多个自定义组件的场景:

import org.springframework.http.converter.xml.JacksonXmlHttpMessageConverter;
import tools.jackson.databind.module.SimpleModule;
import tools.jackson.dataformat.xml.XmlMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;

@Configuration
public class XmlSerialization {

    @Bean("mappingJackson2XmlHttpMessageConverter")
    public JacksonXmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter() {
        // 用SimpleModule来承载自定义序列化器
        SimpleModule customXmlModule = new SimpleModule();
        // 注册你的自定义序列化器,指定目标类型让Jackson精准匹配
        customXmlModule.addSerializer(List.class, new CustomListSerializer());

        XmlMapper xmlMapper = XmlMapper.builder()
                .addModule(customXmlModule)
                .build();

        return new JacksonXmlHttpMessageConverter(xmlMapper);
    }
}

方案二:直接在XmlMapper.Builder上注册序列化器

如果只需要添加单个序列化器,这种方式更简洁:

import org.springframework.http.converter.xml.JacksonXmlHttpMessageConverter;
import tools.jackson.dataformat.xml.XmlMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;

@Configuration
public class XmlSerialization {

    @Bean("mappingJackson2XmlHttpMessageConverter")
    public JacksonXmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter() {
        XmlMapper xmlMapper = XmlMapper.builder()
                // 直接在Builder上添加序列化器,明确指定目标类型
                .addSerializer(List.class, new CustomListSerializer())
                .build();

        return new JacksonXmlHttpMessageConverter(xmlMapper);
    }
}

额外说明

  1. 你已经注意到Jackson 3的包名从com.fasterxml改成了tools.jackson,这部分是对的,不用调整;
  2. Spring Boot 4对应的XML消息转换器也从MappingJackson2XmlHttpMessageConverter改成了JacksonXmlHttpMessageConverter,你的代码里这部分也已经改对了;
  3. 如果你的CustomListSerializer是通用型的(不绑定特定类型),可以去掉类型参数直接调用addSerializer(new CustomListSerializer()),但还是建议尽量明确目标类型,避免序列化逻辑冲突。

这样调整后应该就能正常工作了,要是还有细节问题咱们再聊~

火山引擎 最新活动