实现:
OSGI服务侧的应用场景有两个,一个是将Web容器内嵌到OSGI环境中,另一种是将OSGI环境以WAR的方式发布到独立的Web容器中。这里使用的是第一种方式。所以在前面的Bundle列表中可以看到Jetty的Bundle。
如果使用方案一就需要通过一个OSGI的HTTP服务将外部的HTTP请求转发给CXF内部的Servlet,所以这里要使用OSGI的服务Bundle。
CXF2.1.1版本中包含很多第三方的库,这里需要清理一下,不是所有库都需要最终封装到CXF Bundle中,清理的库包括:
(1) CXF tools需要的库;包括jaxb-xjc-2.1.6.jar
(2) Jms库,因为这里不需要使用Jms;
(3) Spring的所有库;
(4) JAXB2.1的库,这两个库可以放到JDK6的lib\endorse目录下,做为公共库,替代JVM缺省的JAXB2.0的库;
(5) XMLBean的库,这里不使用XMLBean的编码方式;
(6) Log库,我们使用OSGI中的logging Bundle来实现log功能;
(7) Javax.ws的库,因为使用的环境是JDK6,这个库是给JDK5准备的;
(8) Jetty的库;
(9) Js和Json的库;
(10) Velocity库;
这里保留了REST方式需要的库。最后的保留的库列表:
abdera-core-0.4.0-incubating.jar
abdera-extensions-html-0.4.0-incubating.jar
abdera-extensions-json-0.4.0-incubating.jar
abdera-extensions-main-0.4.0-incubating.jar
abdera-i18n-0.4.0-incubating.jar
abdera-parser-0.4.0-incubating.jar
abdera-server-0.4.0-incubating.jar
commons-codec-1.3.jar
commons-httpclient-3.1.jar
commons-lang-2.4.jar
cxf-2.1.1.jar
cxf-manifest.jar
FastInfoset-1.2.2.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.3.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
htmlparser-1.0.5.jar
jaxen-1.1.jar
jdom-1.0.jar
neethi-2.0.4.jar
opensaml-1.1.jar
saaj-api-1.3.jar
saaj-impl-1.3.jar
slf4j-api-1.3.1.jar
slf4j-jdk14-1.3.1.jar
stax-utils-20060502.jar
wsdl4j-1.6.1.jar
wss4j-1.5.4.jar
wstx-asl-3.2.4.jar
xml-resolver-1.2.jar
XmlSchema-1.4.2.jar
xmlsec-1.4.0.jar
创建CXFBundle:
创建时候一定要选择OSGI标准选项:
按照CXF的要求,如果使用非Spring的场景,需要使用CXFNonSpringServlet来接受HTTP请求,所以需要将这个Servlet注册给OSGI的Http服务:
public class CXFWrapperServlets extends CXFNonSpringServlet{
private static final long serialVersionUID = -6994879522066465447L;
private static Map BusMap = new HashMap();
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
BusMap.put("servletBus", getBus());
Bus bus = CXFWrapperServlets.getMyBus("servletBus");
BusFactory.setDefaultBus(bus);
}
...
注册类:
public class HttpServiceTracker extends ServiceTracker{
public HttpServiceTracker(BundleContext context) {
super(context, HttpService.class.getName(), null);
}
public Object addingService(ServiceReference reference) {
HttpService httpService = (HttpService) context.getService(reference);
try {
Servlet ss = (Servlet)new CXFWrapperServlets();
httpService.registerServlet("/services",ss , null, null);
} catch (Exception e) {
e.printStackTrace();
}
return httpService;
}
注意这里的注册路径” /services”,就是说访问http://localhost/services/*的所有HTTP请求都将发送给CXFWrapperServlets来处理。
定义Web Service注册接口:
public interface WSRegister {
public void Regiser(Object impl,String address);
}
这里的参数是Web Service的实现类和访问这个Web Service 的URL地址。接口实现类:
public class WSRegisterImpl implements WSRegister{
public void Regiser(Object impl,String address){
EndpointImpl endpoint = new EndpointImpl(impl);
endpoint.setAddress(address);
endpoint.publish();
...
下面是通过Spring DM提供的能力来发布这个OSGI服务。分别定义两个XML文件用于发布服务,一个文件是这样的:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
context-class-loader="service-provider"/>
另一个文件是:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd">
interface="CXFWrapper.interfaces.WSRegister" context-class-loader="service-provider">
这两个文件都要放到META-INF/spring目录下,这样Spring DM的运行时才会动态的实现OSGI的注册。
在CXFBundle的BundleActivator类中实现HTTP服务的启动:
public void start(BundleContext context){
httpServiceTracker = new HttpServiceTracker(context);
httpServiceTracker.open();;
}
然后是整理MANIFEST.MF文件:
Dependencies TAB页面在导入包选择中,导入如下包:
Import-Package:
javax.servlet;version="2.4.0",
javax.servlet.http;version="2.4.0",
org.apache.commons.logging;version="1.0.4",
org.osgi.framework;version="1.4.0",
org.osgi.service.http;version="1.2.0",
org.osgi.util.tracker;version="1.3.3"
Runtime TAB页面在导出包中要导出注册接口:
Export-Package: CXFWrapper.interfaces
在Classpath输入框中,选择上面列出的所有保留的库。