博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CXF WebService 7 - Spring整合CXF,发布RSETful 风格WebService
阅读量:4132 次
发布时间:2019-05-25

本文共 15932 字,大约阅读时间需要 53 分钟。

这篇文章是承接之前CXF整合Spring的这个项目示例的延伸,所以有很大一部分都是一样的。关于发布CXF WebServer和Spring整合CXF这里就不再多加赘述了。如果你对Spring整合CXF WebService不了解,具体你可以参看这两篇文章:

如果你不了解restful风格的WebService,你可以参考:

SpringMVC对RESTful的支持:

使用 Jersey框架,搭建RESTful WebService(这个也比较简单)

官方文档:

其中,比较常用的RESTful框架就有Jersey、Spring REST、CXF RESTful,这些都可以很好的整合Spring框架,发布也相当的简单。且简单、易用、易上手,文档也比较丰富。

 

开发环境:

System:Windows

JavaEE Server:tomcat6

JavaSDK: jdk6+

IDE:eclipse、MyEclipse 6.6

 

开发依赖库:

JDK6、 JavaEE5、CXF-2.3.3、Spring 3.0.4

Email:

Blog:

 

下面我们就接着这篇文章,开始我们CXF RESTful WebService的旅程,enjoy~!^_*

 

准备工作

首先,你需要添加相关的jar包

其中,jsr331-api-1.1.1.jar是必须的,利用CXF发布REST服务得用到它,在cxf的lib库中可以找到这个jar。

下载地址:

其它的jar包都是非必须的!

JavaEntity

package com.hoo.entity;
 
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
 
/**
* function: MapBean 封装Map集合元素
* @author hoojo
* @createDate 2012-7-20 下午01:22:31
* @file MapBean.java
* @package com.hoo.entity
* @project CXFWebService
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@XmlRootElement
public class MapBean {
private Map
map;
 
//@XmlElement(type = User.class)
public Map
getMap() {
return map;
}
public void setMap(Map
map) {
this.map = map;
}
}

 

package com.hoo.entity;
 
import java.util.HashMap;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
 
/**
* function: Users Entity
* @author hoojo
* @createDate 2011-3-18 上午09:27:31
* @file Users.java
* @package com.hoo.entity
* @project CXFWebService
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@XmlRootElement(name = "UserInfos")
public class Users {
private List
users;
 
private User[] userArr;
 
private HashMap
maps;
 
 
// getter/setter
}
package com.hoo.entity;
 
import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;
 
/**
* function:User Entity
* @author hoojo
* @createDate Dec 16, 2010 10:20:02 PM
* @file User.java
* @package com.hoo.entity
* @project AxisWebService
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@XmlRootElement(name = "UserInfo")
public class User implements Serializable {
private static final long serialVersionUID = 677484458789332877L;
private int id;
private String name;
private String email;
private String address;
 
//getter/setter
 
@Override
public String toString() {
return this.id + "#" + this.name + "#" + this.email + "#" + this.address;
}
}

一、定义你的WebService的接口RESTSample.java,代码如下

package com.hoo.service;
 
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
 
import com.hoo.entity.MapBean;
import com.hoo.entity.User;
import com.hoo.entity.Users;
 
 
/*
注释(Annotation):在 javax.ws.rs.* 中定义,是 JAX-RS (JSR 311) 规范的一部分。
@Path:定义资源基 URI。由上下文根和主机名组成,资源标识符类似于 http://localhost:8080/RESTful/rest/hello。
@GET:这意味着以下方法可以响应 HTTP GET 方法。
@Produces:以纯文本方式定义响应内容 MIME 类型。
 
@Context: 使用该注释注入上下文对象,比如 Request、Response、UriInfo、ServletContext 等。
@Path("{contact}"):这是 @Path 注释,与根路径 “/contacts” 结合形成子资源的 URI。
@PathParam("contact"):该注释将参数注入方法参数的路径,在本例中就是联系人 id。其他可用的注释有 @FormParam、@QueryParam 等。
@Produces:响应支持多个 MIME 类型。在本例和上一个示例中,APPLICATION/XML 将是默认的 MIME 类型。
*/
/**
* function: CXF RESTful风格WebService
* @author hoojo
* @createDate 2012-7-20 下午01:23:04
* @file RESTSampleSource.java
* @package com.hoo.service
* @project CXFWebService
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@Path(value = "/sample")
public interface RESTSample {
 
@GET
@Produces(MediaType.TEXT_PLAIN)
public String doGet();
 
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/request/{param}")
public String doRequest(@PathParam("param") String param,
@Context HttpServletRequest servletRequest, @Context HttpServletResponse servletResponse);
 
@GET
@Path("/bean/{id}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public User getBean(@PathParam("id") int id);
 
@GET
@Path("/list")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Users getList();
 
@GET
@Path("/map")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public MapBean getMap();
 
/*
@Consumes:声明该方法使用 HTML FORM。
@FormParam:注入该方法的 HTML 属性确定的表单输入。
@Response.created(uri).build(): 构建新的 URI 用于新创建的联系人(/contacts/{id})并设置响应代码(201/created)。
您可以使用 http://localhost:8080/Jersey/rest/contacts/
访问新联系人
*/
@POST
@Path("/postData")
public User postData(User user) throws IOException;
 
@PUT
@Path("/putData/{id}")
@Consumes(MediaType.APPLICATION_XML)
public User putData(@PathParam("id") int id, User user);
 
@DELETE
@Path("/removeData/{id}")
public void deleteData(@PathParam("id") int id);
}

 

二、RESTSample接口的实现,这里我们只是简单的实现下,并不是涉及实际的具体业务

package com.hoo.service;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
import com.hoo.entity.MapBean;
import com.hoo.entity.User;
import com.hoo.entity.Users;
 
 
/*
注释(Annotation):在 javax.ws.rs.* 中定义,是 JAX-RS (JSR 311) 规范的一部分。
@Path:定义资源基 URI。由上下文根和主机名组成,资源标识符类似于 http://localhost:8080/RESTful/rest/hello。
@GET:这意味着以下方法可以响应 HTTP GET 方法。
@Produces:以纯文本方式定义响应内容 MIME 类型。
 
@Context: 使用该注释注入上下文对象,比如 Request、Response、UriInfo、ServletContext 等。
@Path("{contact}"):这是 @Path 注释,与根路径 “/contacts” 结合形成子资源的 URI。
@PathParam("contact"):该注释将参数注入方法参数的路径,在本例中就是联系人 id。其他可用的注释有 @FormParam、@QueryParam 等。
@Produces:响应支持多个 MIME 类型。在本例和上一个示例中,APPLICATION/XML 将是默认的 MIME 类型。
*/
/**
* function: CXF RESTful风格WebService
* @author hoojo
* @createDate 2012-7-20 下午01:23:04
* @file RESTSampleSource.java
* @package com.hoo.service
* @project CXFWebService
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@Path(value = "/sample")
public class RESTSampleSource implements RESTSample {
 
@Context
private UriInfo uriInfo;
 
@Context
private Request request;
 
 
@GET
@Produces(MediaType.TEXT_PLAIN)
public String doGet() {
return "this is get rest request";
}
 
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/request/{param}")
public String doRequest(@PathParam("param") String param,
@Context HttpServletRequest servletRequest, @Context HttpServletResponse servletResponse) {
System.out.println(servletRequest);
System.out.println(servletResponse);
System.out.println(servletRequest.getParameter("param"));
System.out.println(servletRequest.getContentType());
System.out.println(servletResponse.getCharacterEncoding());
System.out.println(servletResponse.getContentType());
return "success";
}
 
@GET
@Path("/bean/{id}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public User getBean(@PathParam("id") int id) {
System.out.println("####getBean#####");
System.out.println("id:" + id);
System.out.println("Method:" + request.getMethod());
System.out.println("uri:" + uriInfo.getPath());
System.out.println(uriInfo.getPathParameters());
 
User user = new User();
user.setId(id);
user.setName("JojO");
return user;
}
 
@GET
@Path("/list")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Users getList() {
System.out.println("####getList#####");
System.out.println("Method:" + request.getMethod());
System.out.println("uri:" + uriInfo.getPath());
System.out.println(uriInfo.getPathParameters());
 
List
list = new ArrayList
();
User user = null;
for (int i = 0; i < 4;i ++) {
user = new User();
user.setId(i);
user.setName("JojO-" + i);
list.add(user);
}
Users users = new Users();
users.setUsers(list);
return users;
}
 
@GET
@Path("/map")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public MapBean getMap() {
System.out.println("####getMap#####");
System.out.println("Method:" + request.getMethod());
System.out.println("uri:" + uriInfo.getPath());
System.out.println(uriInfo.getPathParameters());
 
Map
map = new HashMap
();
User user = null;
for (int i = 0; i < 4;i ++) {
user = new User();
user.setId(i);
user.setName("JojO-" + i);
map.put("key-" + i, user);
}
MapBean bean = new MapBean();
bean.setMap(map);
return bean;
}
 
/*
@Consumes:声明该方法使用 HTML FORM。
@FormParam:注入该方法的 HTML 属性确定的表单输入。
@Response.created(uri).build(): 构建新的 URI 用于新创建的联系人(/contacts/{id})并设置响应代码(201/created)。
您可以使用 http://localhost:8080/Jersey/rest/contacts/
访问新联系人
*/
@POST
@Path("/postData")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public User postData(User user) throws IOException {
System.out.println(user);
user.setName("jojo##12321321");
return user;
}
 
@PUT
@Path("/putData/{id}")
@Produces({ MediaType.APPLICATION_XML })
public User putData(@PathParam("id") int id, User user) {
System.out.println("#####putData#####");
System.out.println(user);
user.setId(id);
user.setAddress("hoojo#gz");
user.setEmail("hoojo_@126.com");
user.setName("hoojo");
System.out.println(user);
return user;
}
 
@DELETE
@Path("/removeData/{id}")
public void deleteData(@PathParam("id") int id) {
System.out.println("#######deleteData#######" + id);
}
}
三、配置我们的WebService,修改applicationContext-server.xml。这里主要是添加jaxrs标签的支持,修改头部文件如下:
 
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
特别注意上面加粗带下划线的部分,这是新增加的配置。我们发布restful WebService需要用到它。
然后在配置文件中添加如下配置
 
 
 
 

这样服务器端就完成了CXF RESTful WebService的发布,启动你的tomcat。然后在浏览器中服务地址: (其实这里请求的是CXFServlet,你可以看看上一篇Spring整合CXF文章的web.xml的配置)

你就可以看到我们这里刚刚发布的RESTSample rest的WebService

 

你也可以看看里面的xml,也就是WebService的wsdl文件内容。我们找一个GET方式的WebService的方法,在浏览器中调用一下试试

这个url对应到下面这个方法

@GET
@Path("/bean/{id}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public User getBean(@PathParam("id") int id)

结果如下

一篇xml文档内容。

 

四、编写客户端代码,调用RESTful WebService

package com.hoo.client;
 
import java.io.IOException;
import javax.ws.rs.core.MediaType;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hoo.entity.MapBean;
import com.hoo.entity.User;
import com.hoo.entity.Users;
import com.hoo.service.RESTSample;
 
/**
* function: RESTful风格WebService
* @author hoojo
* @createDate 2012-7-20 下午03:31:03
* @file RSETServiceClient.java
* @package com.hoo.client
* @project CXFWebService
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class RSETServiceClient {
 
private static WebClient client;
 
@Before
public void init() {
// 手动创建webClient对象,注意这里的地址是发布的那个/rest地址
//String url = "http://localhost:8000/CXFWebService/rest/";
//client = WebClient.create(url);
 
// 从Spring Ioc容器中拿webClient对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");
client = ctx.getBean("webClient", WebClient.class);
}
 
@After
public void destory(){
}
 
@Test
public void testGet() {
System.out.println(client.path("sample").accept(MediaType.TEXT_PLAIN).get(String.class));
}
 
@Test
public void testRequest() {
System.out.println(client.path("sample/request/234234").accept(MediaType.TEXT_PLAIN).get(String.class));
}
 
@Test
public void testBean() {
User user = client.path("sample/bean/{id}", 25).accept(MediaType.APPLICATION_XML).get(User.class);
System.out.println(user);
}
 
@Test
public void testList() {
System.out.println(client.path("sample/list").accept(MediaType.APPLICATION_XML).get(Users.class).getUsers());
}
 
@Test
public void testMap() {
System.out.println(client.path("sample/map").accept(MediaType.APPLICATION_XML).get(MapBean.class).getMap());
}
 
@Test
public void testDeleteData() {
client.path("sample/removeData/23").delete();
}
 
@Test
public void testPostData() {
User user = new User();
user.setId(21432134);
user.setAddress("hoojo#gz");
user.setEmail("hoojo_@126.com");
user.setName("hoojo");
System.out.println(client.path("sample/postData").accept(MediaType.APPLICATION_XML).post(user, User.class));
}
 
@Test
public void testPutData() {
User user = new User();
user.setId(21432134);
System.out.println(client.path("sample/putData/1").accept(MediaType.APPLICATION_XML).put(user).getEntity());
}
}
如果你喜欢用Spring的方式,还需要在applicationContext-client.xml中增加如下配置
 
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
 
 
 
 

这种是利用WebClient对象来调用WebService,还有一种方法也可以调用WebService,代码如下:

// 手动创建
//RESTSample sample = JAXRSClientFactory.create("http://localhost:8000/CXFWebService/rest", RESTSample.class);
 
// 从Spring Ioc容器中拿webClient对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");
RESTSample sample = ctx.getBean("restSampleBean", RESTSample.class);
 
System.out.println(sample);
 
System.out.println(sample.doGet());
//System.out.println(sample.doRequest("haha", null, null));
System.out.println(sample.getBean(22));
System.out.println(sample.getList());
System.out.println(sample.getMap().getMap());
User user = new User();
user.setId(21432134);
user.setAddress("hoojo#gz");
user.setEmail("hoojo_@126.com");
user.setName("hoojo");
System.out.println(sample.postData(user));
System.out.println(sample.putData(111, user));
sample.deleteData(2);

这种方式相对比WebClient要简单,直接使用接口中的方法即可。同样如果你要整合到Spring可以在applicationContext-client.xml中增加配置如下:

 

 

执行以上方法可以看到控制台打印结果如下:

client console
org.apache.cxf.jaxrs.client.ClientProxyImpl@1cf7491
this is get rest request
22#JojO#null#null
com.hoo.entity.Users@16eb6bc
{key-0=0#JojO-0#null#null, key-1=1#JojO-1#null#null, key-2=2#JojO-2#null#null, key-3=3#JojO-3#null#null}
21432134#jojo##12321321#hoojo_@126.com#hoojo#gz
111#hoojo#hoojo_@126.com#hoojo#gz
 
server console
####getBean#####
id:22
Method:GET
uri:sample/bean/22
{id=[22]}
####getList#####
Method:GET
uri:sample/list
{}
####getMap#####
Method:GET
uri:sample/map
{}
21432134#hoojo#hoojo_@126.com#hoojo#gz
#####putData#####
21432134#hoojo#hoojo_@126.com#hoojo#gz
111#hoojo#hoojo_@126.com#hoojo#gz
#######deleteData#######2

就这样,整合restful WebService成功。

 

****************************************************************************************************

<jaxrs:server id="restServiceContainer" address="/rest">
<jaxrs:serviceBeans>
<ref bean="restSample" />
</jaxrs:serviceBeans>
请问这里bean的值有什么特殊要求吗

 

就是spring容器中的Bean对象,并且相关的WebService方法和类需要添加对应的@annotated

你可能感兴趣的文章
浅谈Spring声明式事务管理ThreadLocal和JDKProxy
查看>>
初识xsd
查看>>
java 设计模式-职责型模式
查看>>
构造型模式
查看>>
svn out of date 无法更新到最新版本
查看>>
java杂记
查看>>
RunTime.getRuntime().exec()
查看>>
Oracle 分组排序函数
查看>>
删除weblogic 域
查看>>
VMware Workstation 14中文破解版下载(附密钥)(笔记)
查看>>
日志框架学习
查看>>
日志框架学习2
查看>>
SVN-无法查看log,提示Want to go offline,时间显示1970问题,error主要是 url中 有一层的中文进行了2次encode
查看>>
NGINX
查看>>
Qt文件夹选择对话框
查看>>
1062 Talent and Virtue (25 分)
查看>>
1061 Dating (20 分)
查看>>
1060 Are They Equal (25 分)
查看>>
83. Remove Duplicates from Sorted List(easy)
查看>>
88. Merge Sorted Array(easy)
查看>>