blueprint整合cxf提供restful服务

来源:互联网 发布:道路测量编程 编辑:程序博客网 时间:2024/05/07 19:07

blueprint整合cxf提供restful服务


前段时间太过繁忙,一直没有抽出时间来继续更新博客,最近几天抽出时间开始重新开始osgi的专栏,在前几篇文章中一直写的是osgi相关知识中的基础篇,从今天开始编写osgi中的一些高级篇,如osgi相关的web服务,mybatis的引入、如何将osgi项目中的基础模块抽离出来等等。今天就从如何整合cxf开始。

在这里整合cxf并不是使用cxf的webservice特性,而主要是使用restful服务,cxf是jsr311规范的实现,可以原生的使用提供的各种注解进行restful风格的web服务开发。该规范的另外一种实现是jersey,目前在互联网应用中应用极为广泛,jersey应该也能与osgi整合起来使用,但本人并没有试过,有了解过的朋友可以与我来沟通一下,话不多说,现在就开始使用cxf开始我们的osgi restful服务。


cxf依赖引入

在整个环境中我们使用了camel,camel这种EIP的中间件将大多数框架都进行一定程度的集成,cxf同样也是如此,在随后的在feature中,可以直接添加cxf的Bundle,但是在单独我们编写的Bundle中,还是需要添加我们的所需的相关依赖,我们所需的依赖如下所示:

        <dependency>            <groupId>org.apache.cxf</groupId>            <artifactId>cxf-rt-frontend-jaxrs</artifactId>            <version>${cxf.version}</version>            <scope>provided</scope>        </dependency>        <dependency>            <groupId>com.fasterxml.jackson.jaxrs</groupId>            <artifactId>jackson-jaxrs-json-provider</artifactId>            <version>2.4.3</version>            <scope>provided</scope>        </dependency>

一个提供我们所需的注解的相应实现,一个用于我们相应数据的序列化,在以上配置完成之后,犹如既往,我们需要在feature中添加当前的这两个依赖,这个feature如下:

    <feature name="example" version="${project.version}">        <feature>http</feature>        <feature>cxf</feature>        <feature>camel-core</feature>        <feature>camel-blueprint</feature>        <feature>camel-jackson</feature>        <feature>camel-cxf</feature>        <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/2.4.3</bundle>        <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/2.4.3</bundle>        <bundle start-level="100">mvn:${project.groupId}/example/${project.version}</bundle>    </feature>

整个feature中我添加了http、cxf、camel-cxf这几个feature,http这一个feature用于提供http的支持,cxf和camel-cxf都是对cxf的相关支持,在随后的两个Bundle钟,我们添加了我们在pom中添加的两个依赖,在这里我们使用的是mvn协议而不是wrap,说明这些原本就是支持osgi的,能否支持osgi可以在对应依赖中的元数据中清楚的看到,在此不多赘述。
以上完成之后,我们同时需要在相应的felix插件中添加我们需要引入的package,如下:

            <plugin>                <groupId>org.apache.felix</groupId>                <artifactId>maven-bundle-plugin</artifactId>                <configuration>                    <instructions>                        <Private-Package>cn.com.files.command.*</Private-Package>                        <Private-Package>cn.com.files.*</Private-Package>                        <Export-Package>                            cn.com.files.*                        </Export-Package>                        <Import-Package>                            *,                            org.apache.cxf.jaxrs.client                        </Import-Package>                    </instructions>                </configuration>            </plugin>

以上完成之后就能开始我们相应的service的编写了,首先编写一个接口HelloService,添加如下方法与注解:

package cn.com.files.service;import javax.ws.rs.*;import javax.ws.rs.core.MediaType;/** * Created by Administrator on 2016/4/20. */@Path("/")public interface HelloService {    @Path("/world")    @GET    @Consumes(MediaType.APPLICATION_JSON)    @Produces(MediaType.APPLICATION_JSON)    String hello();    @Path("/{name}")    @GET    @Consumes(MediaType.APPLICATION_JSON)    @Produces(MediaType.APPLICATION_JSON)    String hi(@PathParam("name") String name);}

在这里的@Path、@GET等注解就是jsr311中的规范,但是相应的实现由各个restful框架来完成,cxf就是其中之一,相应的@Path、@GET之类的注解不多详述,在此讲一下@Consumes和@Produces注解,这两个注解就是用于说明当前方法接收的数据的类型以及返回的数据类型,以上可以看到我们的接收与返回均为json数据,如果在发送相应请求时,数据类型为text/plain之类的就可能出现415之类的情况即数据类型不对。

在service完成之后,我们也需要一个相应的实现类,命名为HelloServiceImpl,实现如下:

package cn.com.files.service;/** * Created by Administrator on 2016/4/20. */public class HelloServiceImpl implements HelloService {    public String hello() {        return "hello world!";    }    public String hi(String name) {        return "hello " + name;    }}

是一个相当简单的实现,在如此完成之后,还需要在bluepring-cxf.xml中进行配置,如下:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"           xmlns:cxf="http://cxf.apache.org/blueprint/core"           xmlns:jaxrs-client="http://cxf.apache.org/blueprint/jaxrs-client"           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd                http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd                http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd">    <cxf:bus>        <cxf:features>            <cxf:logging/>        </cxf:features>    </cxf:bus>    <jaxrs:server id="HelloRestServer" address="/hello">        <jaxrs:serviceBeans>            <ref component-id="helloRestService"/>        </jaxrs:serviceBeans>        <jaxrs:providers>            <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />        </jaxrs:providers>    </jaxrs:server>    <bean id="helloRestService" class="cn.com.files.service.HelloServiceImpl" /></blueprint>

配置的bean中为我们之前编写的service,现在就需要将对应的服务发布出去,使用了jaxrs:server,发布地址为address,应用我们编写的服务。

现在启动karaf,在karaf启动完成之后,可以看到如下图所示,

这里是图片描述
可以看到当前发布的地址为/hello


演示

我们整合cxf之后,在相应的地址的开头必须加上cxf,而当前的karaf的配置文件中采用的默认的web的端口为8181,但是可以进行改变,相应文件为org.ops4j.pax.web.cfg,其中内容为:

#这个文件是用来改变端口设置的org.osgi.service.http.port=8281

这就是用来指定当前运行端口的,现在在web进行访问,输入http://localhost:8281/cxf将看到如下图:

这里写图片描述

点开为:

这里写图片描述

标准webservice的实现,现在输入localhost:8281/cxf/hello/world,将会如下:

这里写图片描述
我们的编写的服务正常响应,在此就不演示另外一个接口,功能相同,效果也差不多,我们的osgi整合cxf提供restful服务基本就是如此,后续讲一些难度深一些的也是在运用上更深入些,本质与这没有多大差别。


总结

  • cxf的引入其实相当简单,在这里我们只需要使用cxf的restful功能。

  • 在blueprint.xml文件中发布的地址里,不能有相同的address,否则会报错,但是我们编写的程序中可能需要两个service提供相同的前缀路径,但是将两个service写到一起并不优雅,因此在这里没有找到一个良好的解决办法。

  • 在我们使用cxf的restful相应的功能时候,其实同样可以使用其webservice的功能。

1 0