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(); } }
问题分析
- 过滤器代码遗漏关键调用:在HTTP请求分支(
if块)中,未调用filterChain.doFilter(request, response),导致请求无法继续向下传递到后续处理链。POST请求可能因请求体读取逻辑触发了部分日志,让你误以为过滤器生效;而GET请求因无请求体直接中断,表现为“无效”。 - 过滤器配置层级问题:使用
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的方式手动注册过滤器:
- 创建
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); } }); } }
- 在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
相关产品推荐
相关产品推荐

