Apache CXF与Spring集成实现Soap Webservice与RESTFul WebService

想比较下Jersey以及cxf的使用方便性,所以就研究了下,做了个例子。这里我把两种webservice一块了。

步骤如下:

1.建立web工程

2.使用maven下载依赖

3.修改web.xml

4.编写示例

5.编写spring的applicationContext.xml



建立web工程,我用的myeclipse,勾上myeclipse maven。

pom.xml内容如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>cxfrest</groupId>
	<artifactId>cxfrest</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name />
	<description />
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<cxf.version>3.0.1</cxf.version>
	</properties>
	<build>
		<sourceDirectory>${basedir}/src</sourceDirectory>
		<outputDirectory>${basedir}/WebRoot/WEB-INF/classes</outputDirectory>
		<resources>
			<resource>
				<directory>${basedir}/src</directory>
				<excludes>
					<exclude>**/*.java</exclude>
				</excludes>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<configuration>
					<webappDirectory>${basedir}/WebRoot</webappDirectory>
					<warSourceDirectory>${basedir}/WebRoot</warSourceDirectory>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
		</plugins>
	</build>


	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.0.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxws</artifactId>
			<version>${cxf.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.ws.rs</groupId>
			<artifactId>javax.ws.rs-api</artifactId>
			<version>2.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxrs</artifactId>
			<version>${cxf.version}</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-jaxrs</artifactId>
			<version>1.9.13</version>
		</dependency>
	</dependencies>
</project>

我使用了spring 4.0.6 ,几乎是最新的,也不是故意的,随便选了个。

增加cxf-rt-frontend-jaxrs与cxf-rt-frontend-jaxws的包。

另外,要引用javax.ws.rs-api这个包,这个是JSR规范规定的API,@GET @PUT @DELETE @POST @Path 等jax-rs规范注解应该是在里面定义的。

jackson是为jaxrs将po对象转成json用的,不添加,那你只能返回text结果了。也可以用其它的,如jettison,不过我没试通,另外不知阿里的fastjson能不能用,这个要研究下JSONProvider,应该是有这么个接口。

再看web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<display-name></display-name>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<servlet>
		<description>Apache CXF Endpoint</description>
		<display-name>cxf</display-name>
		<servlet-name>cxf</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>cxf</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>

	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>


listener是用来初始化spring的,不用多说了。

servlet是注册cxf用的,这个servlet是可以处理soap 和restful两种webservice 的。

这个servlet 是必须要注册的。
filter是用来防止中文乱码的,具体为什么我还没研究。

编写RS示例:

package com.example;

import java.util.HashMap;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.springframework.stereotype.Component;

import com.example.po.Order;

@Component("restSample")
public class RestTest1 {

	@GET
	@Path("/order")
	@Produces({ MediaType.APPLICATION_JSON })

	public Order getOrder() {
		Order o = new Order(10L, "李先生", "牛肉面", 20);
		return o;
	}
}

其中Order类:

package com.example.po;

public class Order {
	Long orderid;
	String customer;
	String itemname;
	Integer itemcount;

	public Order(Long orderid, String customer, String itemname,
			Integer itemcount) {
		this.orderid = orderid;
		this.customer = customer;
		this.itemname = itemname;
		this.itemcount = itemcount;
	}

	public Long getOrderid() {
		return orderid;
	}

	public void setOrderid(Long orderid) {
		this.orderid = orderid;
	}

	public String getCustomer() {
		return customer;
	}

	public void setCustomer(String customer) {
		this.customer = customer;
	}

	public String getItemname() {
		return itemname;
	}

	public void setItemname(String itemname) {
		this.itemname = itemname;
	}

	public Integer getItemcount() {
		return itemcount;
	}

	public void setItemcount(Integer itemcount) {
		this.itemcount = itemcount;
	}

}

再编写个soap的webservice示剑
package com.example;

import javax.jws.WebService;

@WebService
public interface HelloWorld {

	String sayHi(String text);

}

实现类:

package com.example;

import javax.jws.WebService;

import org.springframework.stereotype.Component;

@Component
@WebService(endpointInterface = "com.example.HelloWorld")
public class HelloWorldImpl implements HelloWorld {

	@Override
	public String sayHi(String text) {
		return "hello " + text;
	}

}

实现类写好了,我们来写spring配置文件了,这里是关键。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:jaxrs="http://cxf.apache.org/jaxrs"
	xsi:schemaLocation=" http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd 
	http://cxf.apache.org/jaxws
	http://cxf.apache.org/schemas/jaxws.xsd 
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-4.0.xsd 
	http://cxf.apache.org/jaxrs
    http://cxf.apache.org/schemas/jaxrs.xsd">

	<context:component-scan base-package="com.example"
		use-default-filters="true" />

	<import resource="classpath:META-INF/cxf/cxf.xml" />

	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
	<!-- soap webservice -->
	<jaxws:endpoint id="helloWorld" implementor="com.example.HelloWorldImpl"
		address="/HelloWorld">
	</jaxws:endpoint>
	<!-- restful webservice -->
	<jaxrs:server id="rs1" address="/rs">
		<jaxrs:serviceBeans>
			<ref bean="restSample" />
		</jaxrs:serviceBeans>
		<jaxrs:providers>
			<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
		</jaxrs:providers>
	</jaxrs:server>
</beans>

component-scan是spring的注解类扫描路径,用于依赖注入。这里没怎么用到。

两个import 是官方文档规定要引入的。

下面就是webservice定义了。

jaxws:endpoint(cxf风格)是定义的一个soap WebService,还有另一种jaxws:server标签(xfire风格,因为Apache CXF = Celtix + XFire ,是XFire的演进版)可以用。

再下面的jaxrs:server定义的是一个RESTful WebService。ref bean里面填的bean name就是我们@Component注解的bean的命名。

providers是来用进行对象转换的,这里用的是 jackson。如果这里没有配置,那你的方法返回对象时,就会报这个错:

No message body writer has been found for class com.example.po.Order, ContentType: application/json
如果你的返回结果是乱码,可以看看filter。

如果报no class found,那你要检查你的jar包版本是否匹配,以及tomcat的是否已正确地部署了工程,也可能是maven依赖的问题。

如果在tomcat启动时,有**.jar not loaded提示信息打印,那你的jar可能有冲突。

如果你看到这篇文章,并在模仿,祝你好运!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值