技术开发 频道

运用Spring DM和CXF来实现WebService 的动态发布

  实现:

  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输入框中,选择上面列出的所有保留的库。

0
相关文章