Spring MVC POST中文乱码解决

Spring MVC POST中文乱码解决

一次项目保存接口,HTTP METHOD为POST,检查数据库编码和数据库连接URL均为UTF-8,于是开始查找原因,最终定位为web.xml配置文问题,特此分享给大家,避免此坑。

<filter>
    <filter-name>CharacterEncodingFilter</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>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

其中/中的通配符要写/*而不是/

<think> 我们正在解决Spring接收POST请求时中文乱码的问题。根据引用内容,我们可以总结出以下几种解决方法: ### 方法1:配置字符编码过滤器(推荐) 在`web.xml`中配置Spring提供的`CharacterEncodingFilter`,并设置编码为UTF-8。这个过滤器会强制请求和响应使用指定的编码。 ```xml <filter> <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` ### 方法2:在Spring Boot中配置 如果是Spring Boot项目,可以在配置文件中设置: ```properties server.servlet.encoding.force=true server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true ``` ### 方法3:在控制器方法中指定produces属性 在@RequestMapping注解中指定produces属性,确保响应使用UTF-8编码: ```java @RequestMapping(value = "testdemo1", method = RequestMethod.POST, produces = "text/plain;charset=UTF-8") @ResponseBody public String testdemo1(@RequestBody String name) { // ... } ``` ### 方法4:手动设置请求编码 在读取请求参数之前,设置请求对象的字符编码(需要在过滤器或拦截器中设置,或者在每个Controller方法中设置): ```java request.setCharacterEncoding("UTF-8"); ``` ### 方法5:修改StringHttpMessageConverter的默认编码 当使用RestTemplate或Spring MVC的消息转换器时,需要确保使用的编码是UTF-8。例如,配置RestTemplate: ```java RestTemplate restTemplate = new RestTemplate(); // 获取消息转换器列表 List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters(); for (HttpMessageConverter<?> converter : converters) { if (converter instanceof StringHttpMessageConverter) { ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8); } } ``` ### 方法6:在读取输入流时指定编码 如果直接使用`HttpURLConnection`,则在读取输入流时指定编码: ```java BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream(), "utf-8") ); ``` ### 原因分析 POST请求乱码通常是因为容器(如Tomcat)默认使用ISO-8859-1编码解析请求,而客户端使用的是UTF-8。解决方法是在解析请求参数之前设置正确的字符编码。 ### 最佳实践 - **推荐使用过滤器方法(方法1)**:配置简单,且能全局处理所有请求。 - **对于Spring Boot应用(方法2)**:使用配置文件设置更简洁。 - **注意**:设置字符编码的操作必须在获取请求参数之前执行,因此过滤器是最合适的。 [^1]: 引用[1]中提供的字符编码过滤器配置。 [^4]: 引用[4]中在控制器方法中指定produces属性。 [^5]: 引用[5]中在读取输入流时指定编码。 §§相关问题§§ 1. 如何解决GET请求的中文乱码问题? 2. 在Spring Boot中如何自定义消息转换器以支持多种编码? 3. 如何测试Spring MVC接口的中文编码是否正确? </think> ### Spring接收POST请求中文乱码解决方案 中文乱码的根本原因是**字符编码不一致**,以下是完整的解决方案: #### 1. 配置全局字符编码过滤器(推荐⭐) 在`web.xml`中添加Spring官方提供的过滤器: ```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> <!-- 关键参数:强制请求响应均使用UTF-8 --> <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> ``` > 原理:在请求到达Controller前强制设置编码[^1] #### 2. Spring Boot配置(替代方案) 在`application.properties`中配置: ```properties # 强制请求/响应使用UTF-8 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.force=true ``` #### 3. 控制器层解决方案 在Controller方法上指定编码: ```java @PostMapping(value = "/api", consumes = MediaType.APPLICATION_JSON_VALUE, produces = "application/json;charset=UTF-8") // 关键设置 public ResponseEntity<String> handlePost( @RequestBody String body) { // 直接接收字符串 System.out.println("接收数据:" + body); // 正常显示中文 return ResponseEntity.ok(body); } ``` > 使用`produces`明确指定响应编码[^4] #### 4. 手动解码方案 ```java @PostMapping("/manual") public String manualDecode(HttpServletRequest request) throws IOException { // 手动设置请求编码 request.setCharacterEncoding("UTF-8"); // 使用Reader读取避免乱码 StringBuilder sb = new StringBuilder(); try (BufferedReader reader = request.getReader()) { String line; while ((line = reader.readLine()) != null) { sb.append(line); } } return sb.toString(); } ``` > 原理:在获取参数前设置编码[^3] #### 5. RestTemplate调用方解决方案 当作为客户端调用时: ```java RestTemplate restTemplate = new RestTemplate(); // 关键:修改消息转换器编码 restTemplate.getMessageConverters().forEach(converter -> { if (converter instanceof StringHttpMessageConverter) { ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8); } }); // 发送请求 String result = restTemplate.postForObject(url, "中文数据", String.class); ``` > 设置StringHttpMessageConverter默认编码[^2][^5] --- ### 根本原因分析 | 阶段 | 编码不一致场景 | 解决方案 | |------|----------------------------|-------------------------| | 请求 | 浏览器UTF-8 vs 服务器ISO-8859-1 | 配置`forceEncoding` | | 传输 | HTTP未声明charset | 设置`Content-Type`头 | | 处理 | Spring默认使用ISO-8859-1 | 修改消息转换器编码 | | 响应 | 未指定charset | 添加`produces`声明 | > **最佳实践**: 同时使用过滤器(方案1)+控制器声明(方案3)可确保万无一失
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值