首页 > 解决方案 > Apache CXF 日志拦截器未在 Spring Boot 应用程序上的 Weblogic 上触发

问题描述

我正在使用 Apache CXF 在 Spring Boot 应用程序上实现自下而上的 Soap WS。在部署到 Weblogic (12.2.1.3.0) 之前一切正常。问题是我尝试使用的 LoggingInterceptors 根本没有被执行。

第一个问题实际上是 WebService 实现类上的 @Autowired 注入上的空指针。为了解决这个问题,我使用了我在 StackO 上创建的一些解决方法。似乎weblogic启动了分离的上下文加载器,一个用于spring和所有bean,一个用于CXF。因此,当通过 wsdl url 调用 webservice impl 类时,注入不会完成。修复此问题后,WS 工作正常,但未触发通过 spring boot 配置添加的日志记录拦截器。该应用程序的一项重要功能是将soap请求响应存储在数据库中的能力。所以拦截器链的工作很重要。

Spring Boot 配置类:

@Configuration
public class LmsReloadCXFWSConfig implements ServletContextInitializer{

    private static WebApplicationContext webApplicationContext;

    public static WebApplicationContext getCurrentWebApplicationContext() {
        return webApplicationContext;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public ServletRegistrationBean servletRegistration() {
        return new ServletRegistrationBean(new CXFServlet(), "/*");
    }

    @Bean
    public LoggingInInterceptor logInInterceptor() {
        return new LmsReloadWSInboundInterceptor();
    }
    @Bean
    public LoggingOutInterceptor  logOutInterceptor() {
        return new LmsReloadWSOutboundInterceptor();
    }

    @Bean(name=Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {   
        SpringBus springBus = new SpringBus();  
        return springBus;
    }

    @Bean
    public LmsReloadWebService lmsReloadWebService() {
        LmsReloadWebService lmsReloadWebService =  new LmsReloadWebServiceImpl();     
        return lmsReloadWebService;
    }

    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), lmsReloadWebService());   
        endpoint.getInInterceptors().add(logInInterceptor());
        endpoint.getOutInterceptors().add(logOutInterceptor());
        endpoint.publish("/Soap");
        return endpoint;
    }
}

两者都是扩展 LoggingInInterceptor 和 LoggingOutInterceptor 的自定义拦截器:

public class LmsReloadWSInboundInterceptor extends LoggingInInterceptor{
...
}

public class LmsReloadWSOutboundInterceptor extends LoggingOutInterceptor{    
...
}

Web Service 接口和实现:

@WebService(name = "LmsServiceInterface", targetNamespace=LmsReloadUtil.LMSRELOAD_NAMESPACE_ORI)
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
public interface LmsReloadWebService {
...
}

@WebService(portName = "LmsServicePort", serviceName = "Soap", targetNamespace = LmsReloadUtil.LMSRELOAD_NAMESPACE_ORI, endpointInterface = "com.dell.lms.reload.ws.LmsReloadWebService")
public class LmsReloadWebServiceImpl implements LmsReloadWebService {

    @Autowired
    private LmsReloadService lmsReloadService;

    @Autowired
    private LmsReloadLoggingService lmsReloadLoggingService;

    public LmsReloadWebServiceImpl() {
        AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
        WebApplicationContext currentContext = LmsReloadCXFWSConfig.getCurrentWebApplicationContext();
        bpp.setBeanFactory(currentContext.getAutowireCapableBeanFactory());
        bpp.processInjection(this);
    }   
    ...
}

我 pom.xml 上的 CXF 版本是 3.2.7

我需要做的是让这些拦截器工作,这样我就可以将请求和响应保存在数据库中。同样,当使用 Eclipse 中启动的 spring boot tomcat 执行应用程序时,该应用程序工作正常且完整。由于 WebService Impl 类上的 Autowired 问题,我认为这与 weblogic 部署应用程序的方式有关。不同的上下文加载器。

上周正在调查这个问题,找到了很多可能的解决方案,尝试了所有但没有成功。

标签: javaweb-servicesspring-bootweblogiccxf

解决方案


推荐阅读