我正在尝试将Apache CXF与OSGI enRoute一起使用。扭曲的是我不想使用cfg.xml文件,而是通过API启动我的服务端点。以下是这样一个例子:
InvolvedPartySoap12EndpointImpl involvedPartyServiceImpl = new InvolvedPartySoap12EndpointImpl();
ServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(InvolvedPartyPortType.class);
svrFactory.setAddress("/bin/InvolvedParty");
svrFactory.setBus(bus);
svrFactory.setServiceBean(involvedPartyServiceImpl);
_server = svrFactory.create();
我遇到的问题是为每个OSGI包创建一个不同的CXF总线,因此每次激活/停用相应的包时,我都可以创建/销毁总线。复制以下Karaf命令也是一个目标:
问题是我没有看到用于创建和销毁CXF总线的API。上面列出的Karaf代码似乎不适用于enRoute。
我想可以在bundle中创建一个cfg.xml文件来创建总线,但是我没有看到用于获取具有给定别名的总线的API。啊。
以下链接看起来很有希望,但是当适应CXFNonSpringServlet的子类时...我没有得到相应的CXF总线,我似乎也无法通过API创建一个:
registering servlet in OSGi that receives parameters
所以我的问题是......有没有人成功通过OSGI内的API获取,创建和销毁CXF总线(以及相应的servlet)?
谢谢, 好色
答案 0 :(得分:1)
CXFNonSpringServlet源代码显示此servlet子类根据需要创建CXF总线。因此,我采用的方法是简单地创建一个CXFNonSpringServlet类的实例,并将其注册到具有所需别名的HTTPService。
catch是在BundleActivator类中无法调用的以下代码,因为无法保证在bundle激活时注册servlet所需的HTTPService。为此,我创建了一个带有HTTPService引用的组件,并在组件激活期间注册了servlet。我进一步将该组件作为“直接组件”,以确保在启动期间进行服务注册。
@Component(immediate = true)
public class SoapBootstrap
{
private static final long serialVersionUID = 1L;
private static final String Alias = "/party";
private HttpService _httpService;
private CXFNonSpringServlet _servlet;
@Reference
public void setHttpService(HttpService theHttpService)
{
try {
_httpService = theHttpService;
_servlet = new CXFNonSpringServlet();
_httpService.registerServlet(Alias, _servlet, null, null);
registerEndpoints();
} catch (NamespaceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
private void registerEndpoints()
{
try {
XyzSoap12EndpointImpl xyzServiceImpl = new XyzSoap12EndpointImpl();
ServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(XyzPortType.class);
svrFactory.setAddress("/xyz");
svrFactory.setBus(_servlet.getBus());
svrFactory.setServiceBean(xyzServiceImpl);
svrFactory.create();
} catch (Throwable e) {
e.printStackTrace();
} finally {
}
}
@Activate
void activate(BundleContext context)
{
}
@Deactivate
void deactivate(BundleContext context)
{
_httpService.unregister(Alias);
}
欢迎将此代码移至Bundle Activator类的建议,但请注意,在调用Bundle Activator时,必须确保HTTPService可用。
答案 1 :(得分:0)
您可以实现Bundle-Activator,在bundle start / stop上注册/取消注册CXF总线。
要创建总线,您可以使用BusFactory类。创建的总线必须注册为服务。已注册的服务保存在列表中,以便能够在捆绑停止时取消注册。
以下(也许不是太美)的例子应该给你一个想法:
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
...
public class MyBundleActivator implements BundleActivator {
private final List<ServiceRegistration> serviceReferences = new ArrayList<>();
private Bus cxfBus;
private BundleContext bundleContext;
@Override
public void start(BundleContext bundleContext) throws Exception {
this.bundleContext = bundleContext;
createAndRegisterCxfBus();
}
private void createAndRegisterCxfBus() {
cxfBus = BusFactory.newInstance().createBus();
cxfBus.setExtension(MyBundleActivator.class.getClassLoader(), ClassLoader.class);
registerService(Bus.class.getName(), cxfBus);
}
private void registerService(String serviceTypeName, Object service) {
Dictionary properties = new Properties();
ServiceRegistration serviceReference = bundleContext.registerService(serviceTypeName, service, properties);
serviceReferences.add(serviceReference);
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
unregisterServices();
}
private void unregisterServices() {
for (ServiceRegistration serviceReference : serviceReferences) {
serviceReference.unregister();
}
}
}
对于JAX-RS服务,您现在可以继续这样:
JAXRSServerFactoryBean serviceFactory = new JAXRSServerFactoryBean();
serviceFactory.setBus(cxfBus);
... configure with providers etc using factory API ....
Server server = serviceFactory.create();
有关详细信息,请参阅http://cxf.apache.org/docs/jaxrs-services-configuration.html。