使用OncePerRequestFilter无法返回自定义HttpServletResponse错误求助
解决OncePerRequestFilter中无法返回自定义HttpServletResponse错误的问题
我之前也踩过这个坑!在OncePerRequestFilter里直接return根本没用,因为你没给HttpServletResponse写入任何有效内容,容器完全不知道要返回什么给前端。正确的做法是手动构建并写入自定义错误响应,然后终止过滤器链的执行。
核心思路
当校验失败(token为空或用户不存在)时,你需要:
- 给
response设置正确的状态码(比如401 Unauthorized) - 指定响应的Content-Type(通常是
application/json) - 写入自定义的错误信息(比如JSON格式的提示)
- 不要调用
filterChain.doFilter(request, response),直接结束方法,避免后续过滤器或控制器继续执行
修改后的代码示例
public class ApiAuthenticationFilter extends OncePerRequestFilter { @Autowired private UserService userService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String token = request.getHeader("X-Authorization"); // 校验token是否为空 if (StringUtils.isEmpty(token)) { buildErrorResponse(response, HttpStatus.UNAUTHORIZED.value(), "请求未携带认证token"); return; // 终止过滤器链 } User user = userService.findUserByToken(token); // 校验用户是否存在 if (user == null) { buildErrorResponse(response, HttpStatus.UNAUTHORIZED.value(), "无效的认证token"); return; // 终止过滤器链 } // 校验通过,继续执行过滤器链 filterChain.doFilter(request, response); } // 封装自定义错误响应的工具方法 private void buildErrorResponse(HttpServletResponse response, int statusCode, String message) throws IOException { // 设置响应状态码 response.setStatus(statusCode); // 设置响应内容类型和编码,避免乱码 response.setContentType("application/json;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); // 构建自定义错误JSON(也可以用Map或自定义DTO对象转JSON) String errorJson = String.format("{\"code\":%d,\"message\":\"%s\"}", statusCode, message); // 写入响应内容并刷新 response.getWriter().write(errorJson); response.getWriter().flush(); } }
关键细节说明
- 为什么不能直接
return?默认情况下response是空的,前端会收到空白响应或者容器默认的错误页面,完全不是你想要的自定义内容。 - 如果需要更复杂的错误结构(比如包含错误码、请求路径、时间戳),可以创建一个
ErrorResponseDTO类,用Jackson等工具序列化后写入响应。 - 一定要设置
charset=UTF-8,否则中文错误提示大概率会乱码。 - 调用
flush()能确保内容立即发送到前端,避免缓存导致的延迟问题。
这样修改后,前端就能准确收到你自定义的JSON错误响应了!
内容的提问来源于stack exchange,提问作者ip696
相关产品推荐
相关产品推荐

