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

如何配置Spring Boot处理Windows-1252编码的JSON请求?

解决Spring Boot 2中Windows-1252编码JSON请求乱码问题

问题根源

Spring Boot默认的MappingJackson2HttpMessageConverter仅默认处理UTF-8编码的请求,当客户端发送application/json; charset=Windows-1252格式的请求时,转换器未按指定编码解码请求体,导致乱码。以下是两种可行的解决方案:


方案一:自定义MappingJackson2HttpMessageConverter(推荐)

通过扩展Spring MVC的消息转换器,让Jackson支持Windows-1252编码的JSON请求,符合Spring Boot的原生设计逻辑。

创建Web MVC配置类:

import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        
        // 添加支持Windows-1252编码的JSON媒体类型
        MediaType windows1252Json = MediaType.APPLICATION_JSON.withCharset(Charset.forName("Windows-1252"));
        jsonConverter.getSupportedMediaTypes().add(windows1252Json);
        
        // 保留默认UTF-8支持,确保兼容原有正常请求
        jsonConverter.setDefaultCharset(StandardCharsets.UTF_8);
        
        // 将自定义转换器放在首位,优先使用
        converters.add(0, jsonConverter);
    }
}

补充说明

如果需要调整Jackson的序列化/反序列化规则,可以给转换器绑定自定义ObjectMapper:

ObjectMapper customMapper = new ObjectMapper();
// 例如允许未转义的控制字符等
customMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
jsonConverter.setObjectMapper(customMapper);

方案二:自定义请求编码转换过滤器

若方案一未生效,可通过自定义过滤器在请求到达Spring MVC组件前,将Windows-1252编码的请求体转换为UTF-8,确保后续流程正常处理。

创建过滤器类:

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 确保过滤器最先执行
public class Windows1252EncodingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String contentType = httpRequest.getContentType();
        
        // 仅处理Windows-1252编码的JSON请求
        if (contentType != null && contentType.contains("application/json") && contentType.contains("charset=Windows-1252")) {
            byte[] rawBody = readRawRequestBody(httpRequest);
            // 用Windows-1252解码请求体,再转成UTF-8字节流
            String bodyStr = new String(rawBody, Charset.forName("Windows-1252"));
            byte[] utf8Body = bodyStr.getBytes(StandardCharsets.UTF_8);
            
            // 包装请求,替换输入流为UTF-8编码的内容
            HttpServletRequestWrapper wrappedRequest = new HttpServletRequestWrapper(httpRequest) {
                @Override
                public BufferedReader getReader() throws IOException {
                    return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(utf8Body), StandardCharsets.UTF_8));
                }

                @Override
                public ServletInputStream getInputStream() throws IOException {
                    return new ServletInputStream() {
                        private final ByteArrayInputStream inputStream = new ByteArrayInputStream(utf8Body);

                        @Override
                        public int read() throws IOException {
                            return inputStream.read();
                        }

                        @Override
                        public boolean isFinished() {
                            return inputStream.available() == 0;
                        }

                        @Override
                        public boolean isReady() {
                            return true;
                        }

                        @Override
                        public void setReadListener(ReadListener listener) {}
                    };
                }
            };
            chain.doFilter(wrappedRequest, response);
        } else {
            // 其他请求直接放行
            chain.doFilter(request, response);
        }
    }

    // 读取原始请求体字节数组
    private byte[] readRawRequestBody(HttpServletRequest request) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        try (ServletInputStream inputStream = request.getInputStream()) {
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }
        return outputStream.toByteArray();
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}
}

方案选择建议

优先使用方案一,因为它直接集成在Spring MVC的消息转换体系中,更贴合框架设计,维护成本更低;若方案一无法解决问题(比如存在其他自定义转换器干扰),再尝试方案二的过滤器方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:25:17