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

Camel-Jetty Rest DSL自定义过滤器对GET请求无效的问题

问题:Camel-Jetty过滤器仅对POST请求生效,GET请求无响应

环境信息

  • Camel版本:3.20.0
  • Jetty版本:9.4.4
  • 已配置的rest-configuration:
<restConfiguration component="jetty" port="9091" bindingMode="off" enableCORS="true">
    <componentProperty key="sendServerVersion" value="false"/>
    <endpointProperty key="filters" value="#logFilter"/>
</restConfiguration>
  • 自定义过滤器logFilter实现javax.servlet.Filter,核心代码:
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {

   try {
      if (servletRequest instanceof HttpServletRequest request && servletResponse instanceof HttpServletResponse response) {
         // Setup Logging
      } else {
         // Pass non-HTTP requests through without logging
         filterChain.doFilter(servletRequest, servletResponse);
      }
   } catch (Exception e) {
      sendErrorResponse((HttpServletResponse) servletResponse, e);
   } finally {
      MDC.clear();
   }

}

问题分析

  1. 过滤器代码遗漏关键调用:在HTTP请求分支(if块)中,未调用filterChain.doFilter(request, response),导致请求无法继续向下传递到后续处理链。POST请求可能因请求体读取逻辑触发了部分日志,让你误以为过滤器生效;而GET请求因无请求体直接中断,表现为“无效”。
  2. 过滤器配置层级问题:使用endpointProperty配置的filters仅作用于特定Endpoint的处理链,Camel-Jetty对GET请求的处理路径可能未经过该Endpoint过滤器链,导致过滤器未被触发。

解决方案

步骤1:修复过滤器代码,补充过滤器链调用

修改doFilter方法,在HTTP请求分支中添加filterChain.doFilter调用,确保请求能正常流转:

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
   try {
      if (servletRequest instanceof HttpServletRequest request && servletResponse instanceof HttpServletResponse response) {
         // 执行日志初始化逻辑
         // Setup Logging

         // 必须调用此方法,让请求继续传递到后续处理
         filterChain.doFilter(request, response);

         // 若需在请求结束后记录日志,可在此处添加后置处理逻辑
         // 注意:此时response可能已提交,需避免修改响应头/体
      } else {
         filterChain.doFilter(servletRequest, servletResponse);
      }
   } catch (Exception e) {
      sendErrorResponse((HttpServletResponse) servletResponse, e);
   } finally {
      MDC.clear();
   }
}

步骤2:调整过滤器配置层级(可选,若步骤1未解决)

将过滤器从endpointProperty移至componentProperty,让过滤器作用于整个Jetty组件的所有请求处理链:

<restConfiguration component="jetty" port="9091" bindingMode="off" enableCORS="true">
    <componentProperty key="sendServerVersion" value="false"/>
    <!-- 改用componentProperty配置过滤器 -->
    <componentProperty key="filters" value="#logFilter"/>
</restConfiguration>

步骤3:通过Jetty Handler注册过滤器(备选方案)

如果上述方法仍无效,可通过自定义Jetty Handler的方式手动注册过滤器:

  1. 创建HandlerWrapper子类,将过滤器嵌入请求链:
public class FilterHandlerWrapper extends HandlerWrapper {
    private Filter logFilter;

    public FilterHandlerWrapper(Filter logFilter) {
        this.logFilter = logFilter;
    }

    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        logFilter.doFilter(request, response, new FilterChain() {
            @Override
            public void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException {
                // 调用后续Handler处理请求
                getHandler().handle(target, baseRequest, (HttpServletRequest) req, (HttpServletResponse) res);
            }
        });
    }
}
  1. 在Camel配置中注册该Handler:
<restConfiguration component="jetty" port="9091" bindingMode="off" enableCORS="true">
    <componentProperty key="sendServerVersion" value="false"/>
    <componentProperty key="handler" value="#filterHandlerWrapper"/>
</restConfiguration>

<!-- 注册自定义Handler Bean -->
<bean id="filterHandlerWrapper" class="com.yourpackage.FilterHandlerWrapper">
    <constructor-arg ref="logFilter"/>
</bean>

内容的提问来源于stack exchange,提问作者Arthur Leywin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:02:10