【问题标题】:Camel CxfEndpoint interceptors failureCamel CxfEndpoint 拦截器失败
【发布时间】:2018-07-12 22:15:23
【问题描述】:

我有一个通过 Soap-endpoint 发送消息的 Camel 路由。

我想在 SOAP 中登录和注销消息 + 一些自定义数据。所以我为 CxfEnpoint bean 添加了拦截器。

@Bean
public CxfEndpoint myEndpoint(){
    CxfEndpoint cxfEndpoint = new CxfEndpoint();
    cxfEndpoint.setAddress("myuri");
    cxfEndpoint.setServiceClass(SomeType.class);
    cxfEndpoint.setDataFormat(DataFormat.POJO);
    cxfEndpoint.setLoggingFeatureEnabled(true);

    //LoggingINInterceptor
    cxfEndpoint.getInInterceptors().add(new Interceptor<Message>() {
        @Override
        public void handleMessage(Message message) throws Fault {
            LOGGER.info("Request body: ${body}"); ;
        }

        @Override
        public void handleFault(Message message) {
            LOGGER.info("Request fault body: ${body}"); ;
        }
    });

    //LoggingOutInterceptor
    cxfEndpoint.getOutInterceptors().add(new Interceptor<Message>() {
        @Override
        public void handleMessage(Message message) throws Fault {
             LOGGER.info("Response body: ${body}");
        }

        @Override
        public void handleFault(Message message) {
            LOGGER.info("Response fault body: ${body}"); ;
        }
    });
    return cxfEndpoint;
}

路线如下:

from("direct:myroute").routeId("cxf_myroute")
        .streamCaching()
        .setHeader(CxfConstants.OPERATION_NAME, constant("MyOperationName"))
        .log(LoggingLevel.INFO, "Call to cxf")
        .to("cxf:bean:myEndpoint").id("call_ws")
        .log(LoggingLevel.INFO, "Response from cxf")
        .process(responseProcessor).id("response_transform").end();

我得到异常:

{"timestamp":"2018-07-12T11:53:39.423+00:00","level":"ERROR","logger_name":"org.apache.camel.processor.DefaultErrorHandler","stack_trace":"java.lang.ClassCastException: myapp.RouteConfiguration$2 cannot be cast to org.apache.cxf.phase.PhaseInterceptor\r\n\tat org.apache.cxf.phase.PhaseInterceptorChain.add(PhaseInterceptorChain.java:232)\r\n\tat org.apache.cxf.phase.PhaseInterceptorChain.add(PhaseInterceptorChain.java:223)\r\n\tat org.apache.cxf.phase.PhaseInterceptorChain.add(PhaseInterceptorChain.java:214)\r\n\tat org.apache.cxf.phase.PhaseChainCache.getChain(PhaseChainCache.java:89)\r\n\tat org.apache.cxf.phase.PhaseChainCache.get(PhaseChainCache.java:71)\r\n\tat org.apache.cxf.endpoint.ClientImpl.setupInterceptorChain(ClientImpl.java:966)\r\n\tat org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:486)\r\n\tat org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:420)\r\n\tat org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:133)\r\n\tat org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)\r\n\tat org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)\r\n\tat org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)\r\n\tat org.apache.camel.processor.Pipeline.process(Pipeline.java:138)\r\n\tat org.apache.camel.processor.Pipeline.process(Pipeline.java:101)\r\n\tat org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)\r\n\tat org.apache.camel.component.direct.DirectBlockingProducer.process(DirectBlockingProducer.java:53)\r\n\tat org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)\r\n\tat org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)\r\n\tat org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)\r\n\tat org.apache.camel.processor.Pipeline.process(Pipeline.java:138)\r\n\tat org.apache.camel.processor.Pipeline.process(Pipeline.java:101)\r\n\tat org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)\r\n\tat org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)\r\n\tat org.apache.camel.http.common.CamelServlet.doService(CamelServlet.java:194)\r\n\tat org.apache.camel.http.common.CamelServlet.service(CamelServlet.java:73)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:790)\r\n\tat io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)\r\n\tat 

我还研究了使用 LoggingInInterceptor / LoggingOutInterceptor (How to log Apache CXF Soap Request and Soap Response using Log4j),但找不到添加自定义逻辑甚至自定义文本的方法。

任何帮助表示赞赏。

附:我知道我可以直接将日志放在我的路由中,但它们将包含尚未编组的正文和无 Soap 标头,因此不是一个选项。

【问题讨论】:

    标签: java apache-camel


    【解决方案1】:

    要删除异常,请这样做:

    //LoggingINInterceptor
        cxfEndpoint.getInInterceptors().add(new LoggingInInterceptor() {
            @Override
            public void handleMessage(Message message) throws Fault {
                LOGGER.info("Request body: ${body}");
            }
    
            @Override
            public void handleFault(Message message) {
                LOGGER.info("Request fault body: ${body}");
            }
        });
    
        //LoggingOutInterceptor
        cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor() {
            @Override
            public void handleMessage(Message message) throws Fault {
                LOGGER.info("Response body: ${body}");
            }
    
            @Override
            public void handleFault(Message message) {
                LOGGER.info("Response fault body: ${body}");
            }
        });
    

    对于自定义日志,只需禁用日志功能,然后在覆盖的方法中使用消息执行您想要的操作。 cxf 如何做到这一点你可以在日志记录方法 LoggingInInterceptor\LoggingOutInterceptor 类中看到。

    【讨论】:

    • 看起来内部自定义处理程序 $ 无效。我收到消息:“消息”:“响应正文:${body}”。有没有办法从 Message 对象中获取 nPayload?
    • CXF 会在你启用日志功能时默认显示负载。要接收有效负载,只需使用 message.getContent(InputStream.class) 方法从输入流中读取它。
    • getContent(InputStream.class) 返回流,但为了记录它,应该复制流并使用 message.setContent(copiedStream)。否则,后续阶段将无法读取已使用的流。
    • 查看 org.apache.cxf.interceptor.LoggingInInterceptor 中的 logInputStream 方法作为默认的日志实现。
    • 我知道,这就是为什么我在我的帖子中写道“cxf 如何做到这一点,您可以在日志记录方法 LoggingInInterceptor\LoggingOutInterceptor 类中看到”=)
    猜你喜欢
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 2018-12-28
    • 2022-01-19
    相关资源
    最近更新 更多