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

Spring Boot REST接口JsonMappingException异常排查求助

问题分析

从异常栈可以明确看出:系统在Ubuntu Java17 Docker环境中,错误地使用了Jackson的XML生成器(ToXmlGenerator)处理响应,而非JSON生成器。XML的标签命名规范不允许以数字开头(你的Map key是627228f554e7655db21f2859,首字符为数字),因此触发了XMLStreamException。本地Mac环境正常是因为默认使用了JSON转换器,JSON对键名的开头字符没有限制。

解决方案

针对这个环境差异导致的转换器选择问题,可从以下几个方向解决:

1. 强制接口返回JSON格式

在Controller的接口方法上显式指定produces属性,强制Spring Boot使用JSON转换器处理响应,忽略请求头的Accept配置:

@GetMapping(value = "/your-api-path", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<TestModel> handleRequest() {
    // 业务逻辑
    TestModel model = buildTestModel();
    return ResponseEntity.ok(model);
}

2. 调整消息转换器优先级(保留XML支持的场景)

如果系统需要同时兼容JSON和XML响应,可调整转换器顺序,让JSON转换器优先;或配置XML转换器兼容非标准标签名:

方案A:提升JSON转换器优先级

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 找到JSON转换器并移至列表首位
        for (int i = 0; i < converters.size(); i++) {
            if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
                MappingJackson2HttpMessageConverter jsonConverter = (MappingJackson2HttpMessageConverter) converters.remove(i);
                converters.add(0, jsonConverter);
                break;
            }
        }
    }
}

方案B:配置XML转换器兼容数字开头的键名

通过自定义XmlMapper,允许生成非XML标准的标签名,或对Map的key进行转义(比如添加前缀):

@Bean
public XmlMapper xmlMapper() {
    XmlMapper xmlMapper = new XmlMapper();
    // 开启XML 1.1支持,允许更多字符作为标签开头
    xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_1_1, true);
    
    // 或自定义Map序列化,给数字开头的key加前缀
    xmlMapper.addMixIn(Map.class, MapXmlMixin.class);
    return xmlMapper;
}

// 定义Map的XML序列化Mixin
public static abstract class MapXmlMixin {
    @JsonAnySetter
    public void setEntry(String key, Object value) {}

    @JsonAnyGetter
    @JsonSerialize(using = SafeMapKeySerializer.class)
    public abstract Map<String, Object> getEntries();
}

// 自定义序列化器,处理数字开头的key
public static class SafeMapKeySerializer extends JsonSerializer<Map<String, Object>> {
    @Override
    public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        ToXmlGenerator xmlGen = (ToXmlGenerator) gen;
        for (Map.Entry<String, Object> entry : value.entrySet()) {
            String safeKey = entry.getKey().matches("^\\d.*") ? "id_" + entry.getKey() : entry.getKey();
            xmlGen.writeFieldName(safeKey);
            serializers.defaultSerializeValue(entry.getValue(), gen);
        }
    }
}

3. 排查请求头差异

确认Docker环境中发起的请求是否携带了Accept: application/xml头,导致Spring Boot优先选择XML转换器。可以用curl指定Accept头测试:

curl -H "Accept: application/json" http://your-service-address/your-api-path

如果测试正常,说明是请求头的问题,可在网关或客户端统一配置Accept: application/json。

4. 禁用XML转换器(不需要XML支持的场景)

如果系统不需要XML响应,可以直接排除Jackson XML的自动配置:

@SpringBootApplication(exclude = {JacksonAutoConfiguration.class})
public class YourApplication {
    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper();
    }
}

或者移除jackson-dataformat-xml依赖,避免XML转换器被自动加载。

内容的提问来源于stack exchange,提问作者Den B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 08:40:47