使用CXF暴露您的REST服务
1. 前言
现在互联网Open API流行,将您的Web应用也可以开放Open API给其他第三方使用。达到一种资源有效利用的目的。而Open API的暴露方式是多种多样的。有Web Service形式的,也有提供一个URI方式的,还有就是给客户端一个jar包,直接使用即可。个人认为,对于使用者来说,使用最简单的就是一个“jar包”+“一份使用文档了”,jar将具体的远程通讯细节、鉴权、握手、数据格式转换等等全部都屏蔽掉。不过这个方式仅仅针对于Java应用,如果用于其他技术,例如ASP.NET、PHP的客户端就不合适了。那么折中一下还是提供一个URI资源,客户端无论是什么技术,只要调用此URI资源就可以获取感兴趣的数据,数据格式和技术平台无关(比如JSON、XML)。REST是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。Web应用暴露出来的是URI资源,客户端可以对资源进行操作(CRUD),REST最重要一点就是无状态,这点实际上感觉是特地针对EJB的会话Bean的重量级说的。所以REST轻量得很,轻量就意味着事务性、稳定性、安全性并没有传统JavaEE应用要求得那么高。主要集中于互联网应用对于不同终端的接口。具体的Rest介绍可以参考:
http://baike.baidu.com/view/1077487.htm。
Apache的CXF不仅可以将您的Web系统暴露成为Web Service,还可以将您的应用暴露成REST资源供不同客户端调用。
2. 环境搭建
先从Apache站点下载CXF相关jar包。网址是:http://cxf.apache.org/download.html。
我下载的是apache-cxf-2.3.2,这个版本算是比较老了,能用就行。
下载后将项目lib下面的jar拷贝到自己web项目的lib中。CXF的samples下面有很多例子,都是支持Ant构建和Maven构建的。建议还是先使用传统方式构建项目,之后再迁移为Maven项目。这样依赖哪些东西心理有数,CXF是强依赖于Spring框架的。
3. 暴露REST服务
下面我们开始暴露自己的Web资源成为REST服务。我们先来看看web.xml的内容
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app>
- <!-- 配置Spring的配置文件 -->
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>WEB-INF/beans.xml</param-value>
- </context-param>
- <!-- 配置Spring的web Context监听器,将Spring与web工程集成在一起 -->
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
- <!-- 配置CXF -->
- <servlet>
- <servlet-name>CXFServlet</servlet-name>
- <display-name>CXF Servlet</display-name>
- <servlet-class>
- org.apache.cxf.transport.servlet.CXFServlet
- </servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>CXFServlet</servlet-name>
- <url-pattern>/service/*</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
bean.xml内容
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
- <!-- 引入CXF下面的配置文件 -->
- <import resource="classpath:META-INF/cxf/cxf.xml" />
- <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
- <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
- <!-- 将Bean托管给Spring -->
- <bean id="roomService" class="com.platform.restful.demo.RoomService">
- </bean>
- <bean id="userService" class="com.platform.restful.demo.UserService">
- </bean>
- <!-- 配置需要暴露的BeanService -->
- <jaxrs:server id="restContainer" address="/">
- <jaxrs:serviceBeans>
- <ref bean="roomService" />
- <ref bean="userService" />
- </jaxrs:serviceBeans>
- </jaxrs:server>
- </beans>
此配置文件需要注意几点,一个就是xml的beans声明,需要支持jaxrs:server标签,还有一个就是需要引入CXF自己的一些Spring配置项。该配置项全部在cxf-2.3.2.jar下面的META-INF下面。最后就是注意要暴露的Service类需要配置在jaxrs:server标签中,这样REST资源才能生效。我们就看一个服务吧,在看之前先说明一点,代码有问题,先这么写,根据爆出的问题,咱们再修改代码。
先建立值对象
- package com.platform.restful.demo;
- import javax.xml.bind.annotation.XmlRootElement;
- @XmlRootElement(name = "UserVO")
- public class UserVO {
- private int id;
- private String name;
- //省去setter和getter
- }
下面是DAO
- package com.platform.restful.demo;
- import java.util.HashMap;
- import java.util.Map;
- public class UserDAO {
- private static Map<String, UserVO> userVOs;
- static {
- userVOs = new HashMap<String, UserVO>();
- UserVO u1=new UserVO();
- u1.setId(1);
- u1.setName("liuyan");
- UserVO u2=new UserVO();
- u2.setId(2);
- u2.setName("yexiaochai");
- userVOs.put("1", u1);
- userVOs.put("2", u2);
- }
- public static Map<String,UserVO> getPersons(){
- return userVOs;
- }
- public static UserVO getPerson(){
- return userVOs.get("1");
- }
- }
下面就是爆出来的门面服务类了
- package com.platform.restful.demo;
- import java.util.Map;
- import javax.ws.rs.Consumes;
- import javax.ws.rs.GET;
- import javax.ws.rs.Path;
- import javax.ws.rs.Produces;
- @Path("/userservice")
- @Produces("application/json")
- public class UserService {
- @GET
- @Path("/getUsers")
- @Consumes("application/xml")
- public Map<String, UserVO> getUsers() {
- System.out.println("get users ");
- Map<String, UserVO> userVOs = UserDAO.getPersons();
- return userVOs;
- }
- @GET
- @Path("/getUser")
- @Consumes("application/xml")
- public UserVO getUser() {
- System.out.println("get user ");
- UserVO userVO = UserDAO.getPerson();
- return userVO;
- }
- }
我们将项目部署到Tomcat上,打开浏览器,输入URL
http://127.0.0.1:8080/cxfdemo/service/userservice/getUser
则输出了一段Json信息
- {"UserVO":{"id":1,"name":"liuyan"}}
那我们输入URL:
http://127.0.0.1:8080/cxfdemo/service/userservice/getUsers
会是什么效果呢,控制台报出如下错误
- 2011-6-15 13:52:47 org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor writeResponseErrorMessage
- 警告: No message body writer has been found for response class HashMap.
错误信息很明确了public Map<String, UserVO> getUsers()返回的是Map,ok,比较简单的办法就是再写一个复合值对象。具体可参考
http://blog.sina.com.cn/s/blog_4051f5dc0100ju0a.html
复合对象
- package com.platform.restful.demo;
- import java.util.Map;
- import javax.xml.bind.annotation.XmlRootElement;
- @XmlRootElement(name = "UserVOMap")
- public class UserVOMap {
- private Map<String, UserVO> userVOs;
- public Map<String, UserVO> getUserVOs() {
- return userVOs;
- }
- public void setUserVOs(Map<String, UserVO> userVOs) {
- this.userVOs = userVOs;
- }
- }
Service服务类修改如下
- @GET
- @Path("/getUsers")
- @Consumes("application/xml")
- public UserVOMap getUsers() {
- System.out.println("get users ");
- Map<String, UserVO> userVOs = UserDAO.getPersons();
- UserVOMap userVOMap = new UserVOMap();
- userVOMap.setUserVOs(userVOs);
- return userVOMap;
- }
之后再次访问http://127.0.0.1:8080/cxfdemo/service/userservice/getUsers
获得Json数据如下
- {"UserVOMap":{"userVOs":{"entry":[{"key":2,"value":{"id":2,"name":"yexiaochai"}},{"key":1,"value":{"id":1,"name":"liuyan"}}]}}}
另外共享一篇8366的文章和demo
http://8366.iteye.com/blog/952887
本文转自:http://suhuanzheng7784877.iteye.com/blog/1090370
使用CXF暴露您的REST服务的更多相关文章
- 使用CXF框架,发布webservice服务,并使用客户端远程访问webservice
使用CXF框架,发布webservice服务,并使用客户端远程访问webservice 1. CXF介绍 :soa的框架 * cxf 是 Celtrix (ESB框架)和 XFire(webs ...
- 怎样让 Web 项目暴露在外的服务坚不可摧?
Web 项目一般给特定人群使用,有些是局域网用户量不足1K的内部系统,也有些广域网用户上万的中型项目,当然还有用户上亿的大型项目. 这些大大小小的 Web 项目都会有用户登录的存在,登录后有特定的权限 ...
- 使用CXF和spring搭建webService服务
虽然下一个项目需要使用xfire,但是在查资料的过程中还是看到有不少地方都说cxf比xfire更好,cxf继承了xfire,但是不仅仅包含xfire,因此便也一起来尝试尝试.大概是有了xfire的经验 ...
- Apache cxf暴露接口以及客户端调用之WebService初步理解
在我们真实的项目中,经常会调用别人提供给我们的接口,或者在自己的团队中, restful风格的前后端分离也经常会提供一个后端接口暴露出去供app,或者.net/C/C++程序员去调用,此时就需要使用到 ...
- CXF创建webservice客户端和服务端
转 一.CXF的介绍 Apache CXF是一个开源的WebService框架,CXF大大简化了Webservice的创建,同时它继承了XFire的传统,一样可以和spring天然的进行无缝的集成.C ...
- cxf 生成客户端代码调用服务
cxf是另一种发布webservice的方式,与jdk提供的相比 jdk提供的是wsimport cxf 提供的是 wsdl2java- d 地址 根据http://www.cnblogs.com/f ...
- cxf整合spring发布rest服务 httpclient访问服务
1.创建maven web项目并添加依赖 pom.xml <properties> <webVersion>3.0</webVersion> <cxf.ver ...
- 使用CXF开发RESTFul服务
相信大家在阅读CXF官方文档(http://cxf.apache.org/docs/index.html)时,总是一知半解.这里向大家推荐一本PacktPub.Apache.CXF.Web.Servi ...
- WebService学习总结(四)--基于CXF的服务端开发
本节将实践目前最流行的第二种web service 发布和调试框架 CXF Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构.它允许创建高性能和可扩 ...
随机推荐
- 通过获取客户端Json数据字符串,反序列化为实体对象的一段代码
#region 保存候选人数据 /// <summary> /// 保存候选人数据 /// </summary> /// <param name="entity ...
- 用户登录密码RSA加密后传输的实现,非明文密码传输
在用户登录页面,用户输入密码后,在传送到服务器端时,为防止在密码传送过程中,被如360这种东东给拦截到, 需要在传送前对密码进行加密,然后再传送! 利用RSA加密,在客户端使用公钥对密码进行加密,在服 ...
- ASP.NET对HTML元素进行权限控制(一)
一个HTML页面有很多的元素比如<DIV>,<P>等.这些元素构成了HTML页面.在Web开发中权限控制是每个系统都要用到了.界面每个元素的权限也是需要控制的.比如一个查询用户 ...
- Linux C 文件与目录1 创建目录
linux C 创建目录 创建目录函数:mkdir 函数原型:int mkdir(char * pathname , mode_t mode); pathname字符指针是表示需要创建的目录路径 ...
- internet协议
internet协议入门 前言 劳于读书,逸于作文. 原文地址:internet协议入门 博主博客地址:Damonare的个人博客 博主之前写过一篇博客:网络协议分析,在这篇博客里通过抓包,具体的分析 ...
- SQL Server2008附加数据库之后显示为只读
SQL Server2008附加数据库之后显示为只读时解决方法 啰嗦的话就不多说了,直入主题吧! 方案一: 碰到这中情况一般是使用的sa账户登录的,只要改为Windows身份验证,再附加数据库即可搞定 ...
- 如何在64位的Windows中安裝PLSQLDEVELOPER 8
先到 Oracle 官網下載Oracle Database 11g Release 2 Client (11.2.0.1.0) for Microsoft Windows (x64) ,接者依照以下步 ...
- 对frameset、frame、iframe的js操作
框架编程概述一个HTML页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一个独立的HTML页面.这里所讲的框架编程包括框架的自我控制以及框架之间的互相访问,例如从一 ...
- 《C++Primer》复习——with C++11 [1]
1.头文件中不应包含using声明,因为头文件的内容会拷贝到所有引用到他的文件中去,如果头文件里有谋个using声明,那么每个使用了该头文件的文件就会有这个声明,由于不经意间包含了一些名字,反而可能产 ...
- svn: E155004: ..(path of resouce).. is already locked
svn: E155004: ..(path of resouce).. is already locked I'm getting an error when trying to commit a c ...