springboot在implements HandlerInterceptor时controller类return 中文字符串时出现中文乱码

本文介绍了一种在使用拦截器时遇到中文乱码问题的解决方案,并分享了通过在GetMapping注解中添加produces参数来正确设置响应内容类型和字符集,从而避免中文乱码并实现跨域请求的经验。

解决办法:

我在拦截器里添加

response.setHeader("Content-type", "text/html;charset=UTF-8");

这句,但是返回的中文还是乱码,我把拦截器去掉后,返回正常,但是我需要这个拦截器实现request的跨域请求

后来我直接在

GetMapping(value = "/test2",produces = {"text/html;charset=UTF-8"})
public String test2() {}

添加produces = {"text/html;charset=UTF-8"}

返回的中文字符正常

<think>我们正在讨论SpringBootSecurity中HandlerInterceptor和OncePerRequestFilter的执行优先级问题。根据Spring框架的处理流程,我们需要明确这两者在请求处理管道中的位置。在SpringMVC中,请求的处理流程大致如下:1.请求首先经过过滤器链(FilterChain),包括SpringSecurity的过滤器链。2.然后进入DispatcherServlet,由它负责将请求分发给对应的处理器(Handler)。3.在处理器执行前后,会经过HandlerInterceptor的preHandle和postHandle方法,以及在视图渲染后触发afterCompletion。特别地,OncePerRequestFilter是ServletFilter的一个实现,它确保在同一个请求中只执行一次。在SpringSecurity中,许多过滤器都继承自OncePerRequestFilter。因此,从整个请求处理流程来看,过滤器的执行是在拦截器之前的。具体来说:-所有的Filter(包括OncePerRequestFilter)都在DispatcherServlet之前执行。-而HandlerInterceptor是在DispatcherServlet处理请求的过程中,在处理器执行前后被调用的。所以,OncePerRequestFilter(作为Filter)的执行优先级高于HandlerInterceptor。为了更清晰地说明,我们可以参考以下执行顺序:1.请求进入Servlet容器,首先经过过滤器链(FilterChain):-Security相关的过滤器(如OncePerRequestFilter的子)-其他过滤器2.请求到达DispatcherServlet3.DispatcherServlet根据HandlerMapping找到对应的处理器,然后执行拦截器链:-HandlerInterceptor的preHandle方法(按配置顺序执行)-执行处理器方法(Controller方法)-HandlerInterceptor的postHandle方法(按配置的逆序执行)-视图渲染-HandlerInterceptor的afterCompletion方法(按配置的逆序执行)因此,OncePerRequestFilter的执行在HandlerInterceptor的preHandle方法之前。我们可以通过一个简单的例子来验证:假设我们有一个OncePerRequestFilter和一个HandlerInterceptor:-OncePerRequestFilter会在doFilterInternal方法中打印日志。-HandlerInterceptor会在preHandle方法中打印日志。执行顺序将是:1.OncePerRequestFilter的doFilterInternal2.HandlerInterceptor的preHandle3....(处理器执行)4.HandlerInterceptor的postHandle(如果有)5.视图渲染(如果有)6.HandlerInterceptor的afterCompletion7.OncePerRequestFilter的doFilterInternal方法之后的代码(即过滤器链继续执行直到响应返回)注意:在过滤器中,只有调用了filterChain.doFilter(request,response)才会将请求传递到下一个过滤器(最后传递到DispatcherServlet),然后才会进入拦截器阶段。因此,结论是:OncePerRequestFilter(作为Filter)的执行优先级高于HandlerInterceptor。引用说明:[^1]中展示了两个拦截器的执行顺序,但未涉及过滤器。我们可以通过理解整个请求生命周期来推断。[^2]展示了自定义拦截器的实现,同样没有直接说明与过滤器的顺序,但我们可以根据SpringMVC架构推断。所以,在SpringBootSecurity中,由于Security的过滤器链位于整个过滤器链中,而拦截器在DispatcherServlet之后,因此Security过滤器(包括OncePerRequestFilter)会先于拦截器执行。相关问题:1.在SpringBoot中如何自定义过滤器(Filter)和拦截器(Interceptor)?2.如何控制多个过滤器的执行顺序?3.如何控制多个拦截器的执行顺序?4.在OncePerRequestFilter中如何跳过某些请求?5.在HandlerInterceptor中如何阻止请求继续处理?</think>### Spring Boot Security 中 HandlerInterceptor 与 OncePerRequestFilter 的执行优先级 在 Spring Boot Security 中,**OncePerRequestFilter(过滤器)的执行优先级高于 HandlerInterceptor(拦截器)**,这是由 Spring MVC 的请求处理流程决定的: 1. **请求处理流程顺序**: - 请求首先经过 **Servlet 过滤器链**(包括 `OncePerRequestFilter`) - 然后进入 **DispatcherServlet** - 最后才执行 **HandlerInterceptor** 链 2. **具体执行顺序**: ```markdown 1. OncePerRequestFilter.doFilterInternal() // 过滤器逻辑 2. HandlerInterceptor.preHandle() // 拦截器前置处理 3. 控制器方法执行 // 业务逻辑 4. HandlerInterceptor.postHandle() // 拦截器后置处理 5. 视图渲染 6. HandlerInterceptor.afterCompletion() // 拦截器完成处理 ``` 3. **关键区别**: - **OncePerRequestFilter**: - 属于 Servlet 规范中的 `Filter` - 在请求进入 DispatcherServlet **之前**执行 - 通常用于安全过滤、日志记录等底层操作 - 示例代码: ```java public class CustomFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { System.out.println("过滤器执行前"); filterChain.doFilter(request, response); // 继续过滤器链 System.out.println("过滤器执行后"); } } ``` - **HandlerInterceptor**: - 属于 Spring MVC 的拦截机制 - 在控制器方法执行**前后**介入 - 通常用于权限检查、参数预处理等业务相关操作 - 示例代码: ```java public class CustomInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("拦截器前置处理"); return true; // 继续执行 } } ``` 4. **在 Spring Security 中的表现**: - Spring Security 的过滤器链(如 `SecurityContextPersistenceFilter`, `UsernamePasswordAuthenticationFilter` 等)都继承自 `OncePerRequestFilter` - 这些安全过滤器**优先于**自定义的 `HandlerInterceptor` 执行 - 典型流程: ```markdown Security 过滤器 → 自定义过滤器 → DispatcherServlet → 自定义拦截器 → 控制器 ``` 5. **验证方法**: 在日志中观察输出顺序: ``` [OncePerRequestFilter] - doFilterInternal // 先执行 [HandlerInterceptor] - preHandle // 后执行 ``` ### 总结 - **优先级排序**:`OncePerRequestFilter` > `HandlerInterceptor` - **选择建议**: - 需要操作 `HttpServletRequest/Response` 底层对象 → 用 `OncePerRequestFilter` - 需要与 Spring MVC 控制器交互(如访问 `ModelAndView`) → 用 `HandlerInterceptor` - **性能提示**:过滤器中应避免阻塞操作,因其位于请求处理最前端[^1][^2]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值