自定义LoggingOutInterceptor始终调用父类方法问题求助
问题概况
启用CXF默认日志拦截器能正常记录SOAP请求和响应负载,但为了给LoggingMessage添加Transaction-ID,我继承LoggingInInterceptor和LoggingOutInterceptor实现了两个自定义拦截器。入站拦截器重写formatLoggingMessage方法后,日志修改正常;但出站拦截器完全没调用我重写的方法,反而一直执行父类LoggingOutInterceptor的逻辑,反复检查配置也没解决。
排查方向与解决办法
1. 确认拦截器配置是否覆盖默认实现
默认CXF会自动加载自带的出站日志拦截器,如果你的配置只是追加自定义拦截器,默认的那个可能还是会先执行甚至覆盖你的逻辑。
- 解决:在
cxf.xml里移除默认的LoggingOutInterceptor,只保留自定义的出站拦截器。示例配置:<jaxws:endpoint id="yourService" implementor="com.your.ImplClass" address="/servicePath"> <jaxws:outInterceptors> <bean class="com.your.package.CustomLoggingOutInterceptor"/> </jaxws:outInterceptors> </jaxws:endpoint> - 也可以调整自定义拦截器的优先级,让它比默认拦截器先执行(优先级数值越小越先执行)。
2. 检查方法重写的正确性
要确认你重写的是LoggingOutInterceptor里正确的方法,注意方法签名必须完全匹配,而且父类方法不能是final的(不然没法重写)。
- 以CXF 3.x版本为例,正确的重写代码应该是这样:
@Override protected String formatLoggingMessage(LoggingMessage loggingMessage) { // 这里添加Transaction-ID逻辑 String txId = getCurrentTransactionId(); // 替换成你的获取逻辑 loggingMessage.getMetadata().put("Transaction-ID", txId); return super.formatLoggingMessage(loggingMessage); } - 如果父类的
formatLoggingMessage是final,那你得换个思路,比如重写log方法,或者自定义LoggingMessage的生成逻辑。
3. 验证拦截器是否被正确加载
- 检查
cxf.xml里自定义拦截器的类路径有没有拼写错误,确保Spring能正确实例化它。 - 打开CXF的DEBUG日志,查看拦截器链的加载日志,确认出站拦截器链里包含你的自定义拦截器,而且执行顺序正确。比如找类似这样的日志:
InterceptorChain doIntercept added com.your.package.CustomLoggingOutInterceptor
InterceptorChain doIntercept executing com.your.package.CustomLoggingOutInterceptor
4. 先确认拦截器方法是否被调用
如果不确定重写的formatLoggingMessage有没有被调用,可以先在自定义出站拦截器的handleMessage方法里加个日志,确认整个拦截器有没有被执行:
@Override public void handleMessage(Message message) throws Fault { System.out.println("CustomLoggingOutInterceptor 被调用了"); super.handleMessage(message); }
如果这个日志都打不出来,那就是拦截器根本没被加入到链里,回头查配置;如果打出来了,再排查formatLoggingMessage的重写问题。
其他检查点
- 核对CXF版本:不同版本的
LoggingOutInterceptor方法结构可能不一样,要对应你使用的版本来写代码。 - 检查是否有其他拦截器配置:比如如果用了
jaxws:outFaultInterceptors,要确认自定义拦截器有没有加到错误处理的拦截器链里。
内容的提问来源于stack exchange,提问作者M A.

