WebService技术中CXF框架与Spring整合和常见bug

Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。

简单的来说,如果两个项目之间需要进行数据互通,就可以用到WebService技术。客户端通过http访问服务器端接口获得所需json或者xml等数据,再转化成对应的实体类,比如,我们平时访问的天气预报,百度地图等等,一般服务都使用RESTful风格。

RESTful,一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。所有资源都共享统一的接口,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET(查询)、PUT(修改)、POST(保存)和 DELETE(删除)。Hypermedia 是应用程序状态的引擎,资源表示通过超链接互联。

例如我们需要获得北京今天的天气位置,我们可以通过http访问:

我们将得到对应的json数据:

WebService技术中CXF框架与Spring整合和常见bug

下面写出WebService的CXF框架与Spring整合的流程:

第一步:导入CXF所需要的依赖,maven坐标如下:

<code class="language-html"> <cxf.version>3.0.1</cxf.version>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-frontend-jaxws</artifactId>

<version>${cxf.version}</version>

</dependency>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-transports-http</artifactId>

<version>${cxf.version}</version>

</dependency>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-frontend-jaxrs</artifactId>

<version>${cxf.version}</version>

</dependency>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-rs-client</artifactId>

<version>${cxf.version}</version>

</dependency>

<dependency>

<groupId>org.apache.cxf</groupId>

<artifactId>cxf-rt-rs-extension-providers</artifactId>

<version>${cxf.version}</version>

</dependency>

<dependency>

<groupId>org.codehaus.jettison</groupId>

<artifactId>jettison</artifactId>

<version>1.3.7</version>

</dependency></code>

第二步:在web.xml文件中配置一个CxfServlet

<code class="language-html"> <servlet>

<servlet-name>CXF</servlet-name>

<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>CXF</servlet-name>

<url-pattern>/services/*</url-pattern> 这里配置的是将来webService访问路径的一部分

</servlet-mapping>

</code>

第三步:在applicationContext.xml文件中整合Cxf框架

在配置之前,我们需引入jaxrs命名空间

xmlns:jaxrs="http://cxf.apache.org/jaxrs"

http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd

<code class="language-html"> <jaxrs:server name="customerService" address="/customerService" > address配置的为将来访问webService的路径

<jaxrs:serviceBeans>

<bean class="com.itheima.service.CustomerServiceImpl"></bean> <span style="color:#FF0000;"> </span>bean 配置的是将来服务的实现类全路径

</jaxrs:serviceBeans>

</jaxrs:server></code>

第四步:搭建服务

1、搭建无参数服务

<code class="language-java">@Transactional //给服务配置事物管理

@Produces("*/*")

public interface CustomerService {

@GET //通过get请求访问此方法

@Path("/findCustomer") //webService访问路径的最后一部分

@Produces({"MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML"}) //表明此方法生产的返回值由什么格式返回(json,xml)

public List<Customer> findAllCustomer (); //方法名</code>

服务的访问路径为

<code class="language-html">"http://localhost:端口号/项目名/services/customerService/findCustomer</code>

2、搭建带参服务

1、搭建需要简单参数服务两种方式:第一种为http传参,第二种是为RESTful风格

<code class="language-java"> @GET

@Path("/FindByCustomerId/{customerid}")

@Produces({"application/json"}) //<span style="color:#FF0000;"><span style="color:#000000;">生产的类型</span> <span style="color:#000000;">restful风格传参方式</span></span>

public List<Customer> findhasassocaitionCustomer(@PathParam("customerid") String id); //此处customerid应与path中的一样</code>

服务的访问路径:

<code class="language-html"> "http://localhost:端口号/项目名/services/customerService/FindByCustomerId/1</code>

2、搭建复杂参数服务,方法需加@Consumes注解,表明消费的类型

<code class="language-java"> @POST

@Path("/saveCustomer")

@Consumes("application/json")

public void saveCustomer(Customer customer);</code>

五:通过java代码访问webService服务

1、通过CXF自带的WebClient类

<code class="language-java">Collection<? extends Customer> customers = WebClient

.create("http://localhost:9001/crm_management/services/customerService/findCustomer") //代表了服务路径

.accept(MediaType.APPLICATION_JSON) //代表接受的数据类型格式

.getCollection(Customer.class); //将返回的json格式封装到对应的实体类</code>

2、一般来说,HttpClient使用更为普遍

六:常见bug解决问题

1、http 404之类的问题,检查访问路径是否正确

2、http 500之类的问题 :

一、检查服务端代码是否是否正确。

二、如果两个项目共同依赖同一个实体类用来互通数据,那么这个实体类需用

<code class="language-java">@Entity

@Table(name = "T_CUSTOMER")

@XmlRootElement(name = "Customer") //name为生成的json或xml最外一层的name

public class Customer {</code>

但如果实体类带泛型,例如PageBean之类的实体,那么需

<code class="language-java">@XmlRootElement(name = "pageBean")

@XmlSeeAlso({Promotion.class}) //此处数组里写泛型可能的所有类型

public class PageBean<T> {</code>

如果实体类中有集合属性,那么需保证集合泛型的类也加有@XmlRootElement

相关推荐