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

如何在SOAP插件应用中编程式添加jaxws:endpoint(loadBus/动态config-location)

Apache CXF 动态添加Endpoint解决方案

背景

当前Web服务从Axis迁移至Apache CXF,插件模块的Endpoint硬编码在servicesbeans.xml中,运行正常,但需要在应用启动时动态添加Endpoint,以下针对两种方案给出具体实现:


方案一:多配置文件加载(含编程式添加)

1. 多config-location的直接配置

CXFServlet支持通过逗号分隔多个配置文件路径,直接在web.xml中修改config-location参数即可:

<servlet>
  <servlet-name>ProvisioningApiCXFServlet</servlet-name>
  <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  <init-param>
     <param-name>config-location</param-name>
     <param-value>/WEB-INF/servicesbeans.xml,/WEB-INF/servicesbeans_2.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

注意:路径需确保在WEB-INF下可访问,若路径包含空格需转义,或使用相对路径。

2. 编程式动态添加配置文件

如果需要在应用启动时动态指定插件生成的配置文件,可通过自定义ServletContextListener实现:

import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class CxfConfigLoaderListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        // 获取CXFServlet实例
        CXFServlet cxfServlet = (CXFServlet) context.getAttribute("ProvisioningApiCXFServlet");
        
        // 动态加载额外配置文件
        String[] additionalConfigs = {"/WEB-INF/dynamic_servicesbeans.xml"};
        // 基于已有Bus创建上下文,合并配置
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(additionalConfigs, cxfServlet.getBus().getApplicationContext());
        ctx.refresh();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 清理资源
    }
}

在web.xml中注册监听器:

<listener>
  <listener-class>com.yourpackage.CxfConfigLoaderListener</listener-class>
</listener>

方案二:基于Bus的编程式创建Endpoint

无需依赖XML配置,直接通过Bus动态注册Endpoint:

1. 获取CXFServlet的Bus实例并创建Endpoint

在Tomcat环境中,通过ServletContext获取CXFServlet实例,进而拿到Bus并创建Endpoint:

import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import com.smarttrust.jam.dpadmin.request.CardHandler;
import org.apache.cxf.feature.LoggingFeature;
import javax.xml.namespace.QName;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.ArrayList;
import java.util.List;

public class DynamicEndpointRegisterListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        // 通过Servlet名称获取CXFServlet实例
        CXFServlet cxfServlet = (CXFServlet) context.getAttribute("ProvisioningApiCXFServlet");
        Bus bus = cxfServlet.getBus();

        // 创建Endpoint实现类实例
        CardHandler implementor = new CardHandler();

        // 添加LoggingFeature
        List<Object> features = new ArrayList<>();
        features.add(new LoggingFeature());

        // 动态创建并发布Endpoint
        EndpointImpl endpoint = new EndpointImpl(bus, implementor);
        endpoint.setEndpointName(new QName("http://your.namespace.com", "CardHandlerPort"));
        endpoint.setFeatures(features);
        endpoint.publish("/CardHandlerService");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 可选:销毁Endpoint
        // EndpointImpl endpoint = ...;
        // endpoint.stop();
    }
}

2. 注册监听器

在web.xml中添加监听器配置,确保在CXFServlet启动后执行:

<listener>
  <listener-class>com.yourpackage.DynamicEndpointRegisterListener</listener-class>
</listener>

注意:可通过调整load-on-startup值控制CXFServlet与监听器的加载顺序,确保CXFServlet先初始化。


关键注意事项

  • 未使用Spring时,需确保CXFServlet的Bus已完成初始化,避免空指针异常。
  • 动态添加的Endpoint实现类需被类加载器正确加载(插件需提前部署到类路径)。
  • 多配置文件加载时,重复的Bean ID会发生覆盖,需注意配置文件间的冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:45:29