java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring MVC POST请求乱码

Spring MVC POST请求乱码的原因与完整解决方案

作者:步行cgn

本文系统分析Spring MVC中POST请求中文乱码的根本原因--请求体与解码字符集不一致(如Tomcat默认ISO-8859-1vs前端UTF-8),并分场景给出完整解决方案,需要的朋友可以参考下

POST 请求中文乱码是 Spring MVC 开发中的高频问题。前端提交的中文到了后端变成问号、乱码,或者后端返回给前端的中文显示异常,本质原因通常只有一个:请求体、响应体在编码和解码时使用的字符集不一致。

Tomcat 默认使用 ISO-8859-1 解码请求体,而前端通常使用 UTF-8 编码。两边不统一,中文就会乱码。解决思路是让整条链路统一使用 UTF-8:前端请求、Spring 过滤器、Tomcat 连接器、JVM、响应转换器、数据库连接,每一环都要确认。

下面按项目类型和问题环节分别说明。

一、Spring Boot 项目:优先使用配置

Spring Boot 提供了开箱即用的编码配置,在 application.properties 或 application.yml 中添加:

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true

force=true 是关键,它会强制把请求和响应的编码覆盖为 UTF-8。

注意旧版本中的 spring.http.encoding.* 已经废弃,不要继续使用。

如果使用 YAML:

server:
  servlet:
    encoding:
      charset: UTF-8
      enabled: true
      force: true

对于大多数 Spring Boot 项目,这一组配置就能解决 POST 表单和普通请求的乱码问题。

二、传统 Spring MVC 项目:注册 CharacterEncodingFilter

传统 Spring MVC 项目需要手动注册 CharacterEncodingFilter。

方式一:web.xml

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这个过滤器必须配置在其他过滤器之前,否则可能被其他过滤器提前读取请求参数,导致编码设置失效。

方式二:Java Config

@Bean
public FilterRegistrationBean<CharacterEncodingFilter> encodingFilter() {
    FilterRegistrationBean<CharacterEncodingFilter> bean = new FilterRegistrationBean<>();
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("UTF-8");
    filter.setForceEncoding(true);
    bean.setFilter(filter);
    bean.addUrlPatterns("/*");
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
}

setOrder(Ordered.HIGHEST_PRECEDENCE) 保证它在过滤器链最前面执行。

三、Tomcat 与 JVM 层面

如果过滤器已经配置,仍然有乱码,检查 Tomcat 的 conf/server.xml 中 <Connector> 配置:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8"
           useBodyEncodingForURI="true" />

同时建议给 JVM 加上默认编码参数。Linux/macOS 在 bin/setenv.sh 中:

export JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"

Windows 在 catalina.bat 中:

set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8

这可以避免日志、文件路径等出现乱码。

四、JSON 请求体乱码

如果乱码发生在 @RequestBody 接收的 JSON 参数上,先检查客户端请求头:

Content-Type: application/json;charset=UTF-8

如果客户端无法修改,可以在服务端强制 Jackson 使用 UTF-8:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                MappingJackson2HttpMessageConverter jacksonConverter =
                        (MappingJackson2HttpMessageConverter) converter;
                jacksonConverter.setDefaultCharset(StandardCharsets.UTF_8);
            }
        }
    }
}

这样即使客户端没有在 Content-Type 中声明 charset,Jackson 也会按 UTF-8 读取请求体。

五、响应乱码

如果后端返回的 JSON 或字符串乱码,可以从两个方向处理。

1. 指定 produces

@RequestMapping(value = "/api", produces = "application/json;charset=UTF-8")

2. 调整 StringHttpMessageConverter

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }
}

将 UTF-8 的 StringHttpMessageConverter 放在最前面,避免默认转换器使用其他编码。

六、数据库连接乱码

如果数据到了数据库才乱码,检查 JDBC URL:

jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8

同时确认数据库和表的字符集:

SHOW CREATE TABLE your_table;

推荐使用 utf8mb4,兼容中文和 emoji。

七、排查清单

出现 POST 乱码时,按下面顺序排查:

检查位置关键点
前端请求Content-Type 是否包含 charset=UTF-8
Spring Boot 配置server.servlet.encoding.force=true
传统项目过滤器CharacterEncodingFilter 是否生效,是否在最前面
Tomcat 连接器URIEncoding="UTF-8"、useBodyEncodingForURI="true"
JVM 参数-Dfile.encoding=UTF-8
JSON 请求体Jackson 是否按 UTF-8 读取
响应转换器StringHttpMessageConverter 或 produces
数据库JDBC URL 编码、库表字符集

八、总结

POST 请求乱码不是单一配置能覆盖所有场景的问题,它涉及前端、Spring、Tomcat、JVM、数据库多个环节。解决的核心原则是:保证请求、处理、响应、存储每一环都使用 UTF-8。

实际项目中可以按这个优先级处理:

  1. Spring Boot 项目先加 server.servlet.encoding.* 配置。
  2. 传统项目优先检查 CharacterEncodingFilter。
  3. 仍有问题时检查 Tomcat 连接器和 JVM 编码。
  4. JSON 乱码单独处理 Jackson 的默认字符集。
  5. 响应乱码检查 StringHttpMessageConverter 和 produces。
  6. 数据库乱码检查 JDBC URL 和库表字符集。

按这个顺序排查,绝大多数 POST 中文乱码都能定位并解决。

以上就是Spring MVC POST请求乱码的原因与完整解决方案的详细内容,更多关于Spring MVC POST请求乱码的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文