Spring Boot 拦截器返回中文乱码的解决方案(附全局优化思路)

在 Spring Boot 项目开发中,我们常常会在 拦截器 中进行登录校验,并在未登录时直接返回 JSON 提示信息。但很多同学会遇到一个问题:中文提示信息出现乱码 (如 ??? 或乱码字符)。


一、问题原因

根源在于:
HTTP 响应的字符编码(Charset)未正确设置,导致前端解析中文失败。

  • 拦截器中直接使用 response.getWriter().write(...) 输出字符串;
  • Tomcat 默认使用 ISO-8859-1 编码,不支持中文;
  • 前端一般默认用 UTF-8 解析,编码不一致 → 乱码。

二、临时方案:手动设置响应编码

这是最快速见效的办法。在 response.getWriter().write(...) 之前,明确设置字符编码和 Content-Type:

java 复制代码
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("{\"code\":401,\"msg\":\"请先登录!\"}");

修改拦截器示例:

java 复制代码
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String token = request.getHeader(jwtProperties.getTokenName());
    if (StringUtils.isBlank(token)) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("{\"code\":401,\"msg\":\"请先登录!\"}");
        return false;
    }
    return true;
}

👉 这样可以立刻解决乱码问题,但存在硬编码 JSON、不可复用的问题。


三、优雅方案:使用统一的 Result

如果项目里已经有统一的返回对象(如 Result),建议复用,避免硬编码 JSON。

1. 注入 ObjectMapper

Spring Boot 默认集成了 Jackson,可直接注入:

java 复制代码
@Autowired
private ObjectMapper objectMapper;

2. 生成统一响应

Result 封装后,再转成 JSON 输出:

java 复制代码
Result<?> result = Result.fail(401, "请先登录!");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(result));

这样既能保证编码正确,又能保持返回格式一致。


四、根治方案:全局配置响应编码

如果你不想每次都手动设置编码,可以通过全局配置彻底解决。

方式 1:在 application.yml 配置

yaml 复制代码
spring:
  http:
    encoding:
      force: true
      charset: UTF-8
      enabled: true

方式 2:全局配置消息转换器

WebMvcConfig 中统一设置编码:

java 复制代码
@Bean
public StringHttpMessageConverter stringHttpMessageConverter() {
    StringHttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
    return converter;
}

这样项目中所有返回字符串的响应都会默认使用 UTF-8。


五、验证效果

  1. 启动项目后,访问需要登录的接口(不带 Token);
  2. 查看返回结果:
json 复制代码
{"code":401,"msg":"请先登录!"}

若能正常显示中文而不是乱码,说明问题已解决 ✅。

相关推荐
一 乐1 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
Boilermaker19921 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
Cherry的跨界思维1 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
alonewolf_992 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
一嘴一个橘子2 小时前
spring-aop 的 基础使用(啥是增强类、切点、切面)- 2
java
码事漫谈2 小时前
Protocol Buffers 编码原理深度解析
后端
sheji34162 小时前
【开题答辩全过程】以 中医药文化科普系统为例,包含答辩的问题和答案
java
码事漫谈2 小时前
gRPC源码剖析:高性能RPC的实现原理与工程实践
后端
sunfove2 小时前
光网络的立交桥:光开关 (Optical Switch) 原理与主流技术解析
网络
恋爱绝缘体13 小时前
2020重学C++重构你的C++知识体系
java·开发语言·c++·算法·junit