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

Spring Boot Filter返回自定义格式RESTful JSON响应问题求助

问题根源

你拿到的响应带多余字段,核心问题是直接把Spring的ResponseEntity实例序列化后写入了响应流。ResponseEntity本身是封装了响应头、状态码、响应体的全量HTTP响应对象,Jackson序列化这个对象的时候,会把它内部所有字段(headers、statusCode、statusCodeValue、嵌套的body)全转成JSON输出,自然就出现了你看到的多余字段和body嵌套结构。
另外你提到的@ControllerAdvice不生效是正常的:过滤器执行在DispatcherServlet调度之前,默认链路下过滤器抛出的异常不会走到Spring MVC的全局异常处理逻辑。

可落地方案

方案1:直接修正过滤器写入逻辑(改造成本最低,适配你当前需求)

你根本不需要构造ResponseEntity对象,直接把ResponseGen.create()生成的纯业务响应对象序列化后写入流就行,修正后的可运行代码如下:

@Component
@RequiredArgsConstructor
public class HeaderValidationFilter extends OncePerRequestFilter {
    private final ObjectMapper objectMapper;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String headerValue = request.getHeader("RANDOM_HEADER");
        if (Objects.isNull(headerValue)) {
            // 直接生成业务响应对象,不要包装成ResponseEntity
            Object businessResp = ResponseGen.create("FAILED", "Missing Authentication Header", new Object());
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            // 序列化业务对象为字节数组写入响应
            response.getOutputStream().write(objectMapper.writeValueAsBytes(businessResp));
            return;
        }
        filterChain.doFilter(request, response);
    }
}

注:你贴的原代码里new Object())));多写了两层右括号,属于语法错误,修正时已经去掉。改完后接口会直接返回你期望的纯业务JSON结构,不会有多余字段。

方案2:打通过滤器到全局异常处理器的链路(适合多过滤器统一错误处理场景)

如果你项目里有多个过滤器,想统一复用@ControllerAdvice的错误响应逻辑,不需要每个过滤器都写序列化逻辑,可以通过请求转发把过滤器异常抛到MVC处理链路:

  1. 校验不通过时,把自定义异常绑定到request属性,转发到Spring内置的/error端点:
if (Objects.isNull(headerValue)) {
    request.setAttribute("javax.servlet.error.exception", new MissingRequestHeaderException("RANDOM_HEADER"));
    request.getRequestDispatcher("/error").forward(request, response);
    return;
}
  1. 自定义ErrorController处理/error路径的请求,从request中取出绑定的异常抛出,就会被@ControllerAdvice捕获,走你统一的响应封装逻辑。
避坑提示
  • 过滤器层不要直接序列化ResponseEntity、ServletServerHttpResponse这类Web层封装对象,这类对象是HTTP响应的元数据载体,不是返回给前端的业务数据
  • 过滤器返回JSON时必须显式设置Content-Type为application/json,否则部分网关或客户端会把响应当成纯文本解析
  • 写入响应后必须return终止过滤链,否则后续逻辑继续执行会触发“响应已提交”的IO异常

内容的提问来源于stack exchange,提问作者bishwa.poudel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 00:24:38