Spring Boot过滤器中HttpServletResponse.sendError未返回自定义错误信息如何解决
问题原因
- Spring Boot 默认错误处理机制的配置限制:Spring Boot 2.3+ 版本开始,
server.error.include-message配置项默认值为never,默认不会把sendError方法传入的自定义错误信息暴露到响应体中。 sendError方法的执行逻辑:调用该方法后,Servlet 容器会清空当前响应缓冲区,将请求转发到 Spring Boot 内置的/error错误端点,由BasicErrorController处理生成最终响应,你传入的自定义信息会被默认的错误生成逻辑忽略。
解决方案
方案1:修改配置开启message暴露
在application.yml或application.properties中添加如下配置:
server: error: include-message: always include-binding-errors: always # 可选,参数校验错误也同步暴露信息
该配置全局生效,所有错误响应都会自动带上message字段,适合对错误信息暴露没有严格限制的场景。
方案2:在Filter中直接构造响应返回(更推荐)
不走sendError逻辑,直接往HttpServletResponse中写入自定义JSON结构,完全避免默认错误处理的干扰,修改后的代码示例:
// 签名校验失败场景 if (!apiKeyObject.getSignature().equalsIgnoreCase(Hex.toHexString(messageDigest))) { log.error("Invalid signature, expected: {}, received: {}", Hex.toHexString(messageDigest), apiKeyObject.getSignature()); // 构造自定义错误响应体 Map<String, Object> errorRes = new HashMap<>(); errorRes.put("timestamp", LocalDateTime.now(ZoneOffset.UTC)); errorRes.put("status", HttpServletResponse.SC_PRECONDITION_FAILED); errorRes.put("error", "Precondition Failed"); errorRes.put("message", StatusCode.getStatusMessage(StatusCode.VERIFY_SIGNATURE_FAIL)); // 设置响应属性 httpServletResponse.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED); httpServletResponse.setContentType("application/json;charset=UTF-8"); // 写入响应并返回 httpServletResponse.getWriter().write(jsonUtils.toJsonString(errorRes)); httpServletResponse.getWriter().flush(); return; } // 运行时异常捕获场景同理 catch (RuntimeException ex){ log.error("Exception happened: {}", ex.getMessage()); Map<String, Object> errorRes = new HashMap<>(); errorRes.put("timestamp", LocalDateTime.now(ZoneOffset.UTC)); errorRes.put("status", HttpServletResponse.SC_INTERNAL_SERVER_ERROR); errorRes.put("error", "Internal Server Error"); errorRes.put("message", "Internal Server Error"); httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.getWriter().write(jsonUtils.toJsonString(errorRes)); httpServletResponse.getWriter().flush(); return; }
该方案完全自主可控,不需要依赖全局配置,也不会和项目其他自定义错误处理逻辑冲突,更适合过滤器场景下的错误返回。
内容的提问来源于stack exchange,提问作者Tan Jin Peng
相关产品推荐
相关产品推荐

