You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot测试中ObjectMapper误将XML当JSON解析,如何正确注入解析器?

Spring Boot测试中如何注入XmlMapper或配置ObjectMapper实现XML解析(带自定义反序列化器)

问题描述

我在Spring Boot测试里尝试用自定义反序列化器解析XML,测试代码如下:

@SpringBootTest
public class MyTest {
    @Autowired ObjectMapper mapper;
    @Test
    public void shouldParseXmlString() {
        final String input = "<abc>value</abc>"; // 合法的XML字符串
        MyClass myClass = mapper.readValue(input, MyClass.class);
        assertEquals("value", myClass.getAbc());
    }
}

我有一个继承自JsonDeserializer<MyClass>的自定义反序列化器,用来把XML转成MyClass对象。直接用XmlMapper的时候解析正常,但注入ObjectMapper后执行测试就报错:

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)) expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')

很明显ObjectMapper把输入的XML字符串当成JSON来解析了。请问怎么通过注入ObjectMapper或者XmlMapper来实现XML解析?我的pom.xml已经加了版本2.10.0的jackson-core和jackson-dataformat-xml依赖。


解决方案

这个问题的核心原因很简单:Spring Boot默认自动配置的ObjectMapper是专门处理JSON格式的,它不会识别XML的语法,所以才会抛出JSON解析错误。这里给你两种可行的解决思路:

方案一:直接注入XmlMapper(推荐)

当你的项目中引入了jackson-dataformat-xml依赖时,Spring Boot会自动配置一个XmlMapper的Bean,你可以直接注入它来处理XML解析,而且它能很好地兼容你的自定义反序列化器。

修改后的测试代码

@SpringBootTest
public class MyTest {
    @Autowired XmlMapper mapper; // 替换成XmlMapper
    
    @Test
    public void shouldParseXmlString() {
        final String input = "<abc>value</abc>";
        MyClass myClass = mapper.readValue(input, MyClass.class);
        assertEquals("value", myClass.getAbc());
    }
}

关联自定义反序列化器

如果你的自定义反序列化器是通过@JsonDeserialize注解标注在MyClass上的,比如:

@JsonDeserialize(using = MyCustomDeserializer.class)
public class MyClass {
    private String abc;
    
    // getter、setter省略
}

那XmlMapper会自动识别这个注解并应用你的反序列化逻辑,不需要额外配置。

如果需要手动注册反序列化器,可以自定义XmlMapper的Bean:

@Configuration
public class JacksonXmlConfig {
    @Bean
    public XmlMapper xmlMapper() {
        XmlMapper xmlMapper = new XmlMapper();
        // 注册自定义反序列化器
        xmlMapper.registerModule(new SimpleModule()
                .addDeserializer(MyClass.class, new MyCustomDeserializer()));
        return xmlMapper;
    }
}

方案二:配置ObjectMapper支持XML格式(不推荐,仅当需要复用ObjectMapper时考虑)

如果你一定要用ObjectMapper来处理XML,可以给它指定XML的底层工厂实现,但这样ObjectMapper会同时处理JSON和XML,可能带来格式识别的冲突,所以更推荐用专门的XmlMapper。

配置示例:

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        // 使用XmlFactory替换默认的JsonFactory,让ObjectMapper支持XML解析
        ObjectMapper objectMapper = new ObjectMapper(new XmlFactory());
        // 注册自定义反序列化器
        objectMapper.registerModule(new SimpleModule()
                .addDeserializer(MyClass.class, new MyCustomDeserializer()));
        return objectMapper;
    }
}

内容的提问来源于stack exchange,提问作者Not a bug

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:32:27