You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OncePerRequestFilter无法返回自定义HttpServletResponse错误求助

解决OncePerRequestFilter中无法返回自定义HttpServletResponse错误的问题

我之前也踩过这个坑!在OncePerRequestFilter里直接return根本没用,因为你没给HttpServletResponse写入任何有效内容,容器完全不知道要返回什么给前端。正确的做法是手动构建并写入自定义错误响应,然后终止过滤器链的执行。

核心思路

当校验失败(token为空或用户不存在)时,你需要:

  1. 给response设置正确的状态码(比如401 Unauthorized)
  2. 指定响应的Content-Type(通常是application/json)
  3. 写入自定义的错误信息(比如JSON格式的提示)
  4. 不要调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:31:01