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

SpringBoot 1.5.10+Jackson2接收非Unicode的REST POST请求问题

在Spring Boot 1.5.10中让Jackson2支持非Unicode编码的JSON请求

核心问题

Spring Boot 1.5.10里的AbstractJackson2HttpMessageConverter默认直接将请求的InputStream传给Jackson解析,没有根据请求头Content-Type中指定的编码创建InputStreamReader,导致非UTF-8编码的JSON请求里的非ASCII字符解析失败。即便设置server.servlet.encoding.force-request=false关闭强制UTF-8,也无法解决这个问题——因为底层根本没读取请求头里的编码信息。

可行解决方案

方案一:自定义MappingJackson2HttpMessageConverter并替换默认实现

这是最稳妥的方式,不会有类路径冲突风险:

  1. 自定义转换器类
    继承MappingJackson2HttpMessageConverter,重写read方法,根据请求头的编码创建InputStreamReader后再交给Jackson解析:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.lang.reflect.Type;

public class EncodingAwareJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {

    public EncodingAwareJackson2HttpMessageConverter(ObjectMapper objectMapper) {
        super(objectMapper);
    }

    @Override
    public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        // 从请求头获取编码,默认用UTF-8
        Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
        try (InputStreamReader reader = new InputStreamReader(inputMessage.getBody(), charset)) {
            return getObjectMapper().readValue(reader, getJavaType(type, contextClass));
        }
    }

    private Charset getContentTypeCharset(org.springframework.http.MediaType contentType) {
        if (contentType != null && contentType.getCharset() != null) {
            return contentType.getCharset();
        }
        return StandardCharsets.UTF_8;
    }
}
  1. 配置替换默认转换器
    创建一个WebMvcConfigurerAdapter的子类,覆盖configureMessageConverters方法,移除默认的Jackson转换器,添加自定义的:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    private final ObjectMapper objectMapper;

    // 注入Spring默认的ObjectMapper,保证原有配置生效
    public WebMvcConfig(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 移除默认的MappingJackson2HttpMessageConverter
        converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);
        // 添加自定义的转换器
        converters.add(new EncodingAwareJackson2HttpMessageConverter(objectMapper));
        // 保留其他默认转换器(比如StringHttpMessageConverter等)
        super.configureMessageConverters(converters);
    }
}

方案二:类路径替换AbstractJackson2HttpMessageConverter(不推荐)

直接替换Spring的AbstractJackson2HttpMessageConverter类到类路径,但这种方式风险极高:

  • Fat jar或war打包时,类加载顺序可能导致自定义类不生效,或者和Spring原有类冲突
  • 后续Spring版本升级(哪怕是小版本)都可能导致兼容性问题
  • 排查问题时很难定位到类替换的影响

所以除非万不得已,不建议使用这种方式。

验证

配置完成后,发送带有指定编码的JSON请求(比如Content-Type: application/json;charset=GBK),Jackson就能正确解析其中的非ASCII字符了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:01:02