zoukankan      html  css  js  c++  java
  • 在web项目中使用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-3.1.12。

    下载后将项目lib下面的jar拷贝到自己web项目的lib中。CXF的samples下面有很多例子,都是支持Ant构建和Maven构建的。建议还是先使用传统方式构建项目,之后再迁移为Maven项目。这样依赖哪些东西心理有数,CXF是强依赖于Spring框架的。

    3.  暴露REST服务

    下面我们开始暴露自己的Web资源成为REST服务。我们先来看看web.xml的内容

    Java代码 
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <web-app>  
    3.     <!-- 配置Spring的配置文件 -->  
    4.     <context-param>  
    5.         <param-name>contextConfigLocation</param-name>  
    6.         <param-value>/WEB-INF/beans.xml</param-value>  
    7.     </context-param>  
    8.       
    9.     <!-- 配置Spring的web Context监听器,将Spring与web工程集成在一起 -->  
    10.     <listener>  
    11.         <listener-class>  
    12.             org.springframework.web.context.ContextLoaderListener  
    13.         </listener-class>  
    14.     </listener>  
    15.       
    16.     <!-- 配置CXF -->  
    17.     <servlet>  
    18.         <servlet-name>CXFServlet</servlet-name>  
    19.         <display-name>CXF Servlet</display-name>  
    20.         <servlet-class>  
    21.             org.apache.cxf.transport.servlet.CXFServlet  
    22.         </servlet-class>  
    23.         <load-on-startup>1</load-on-startup>  
    24.     </servlet>  
    25.   
    26.     <servlet-mapping>  
    27.         <servlet-name>CXFServlet</servlet-name>  
    28.         <url-pattern>/service/*</url-pattern>  
    29.     </servlet-mapping>  
    30.     <welcome-file-list>  
    31.         <welcome-file>index.jsp</welcome-file>  
    32.     </welcome-file-list>  
    33. </web-app>  

     bean.xml内容

    Java代码  
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"  
    4.     xmlns:context="http://www.springframework.org/schema/context"  
    5.     xsi:schemaLocation="   
    6.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
    7.        http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd   
    8.        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
    9.       
    10.     <!-- 引入CXF下面的配置文件 -->  
    11.     <import resource="classpath:META-INF/cxf/cxf.xml" />  
    12.    <!-- <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> --> 
    13.     <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  
    14.   
    15.     <!-- 将Bean托管给Spring -->  
    16.     <!-- <bean id="roomService" class="com.platform.restful.demo.RoomService"> --> 
    17.     </bean>  
    18.   
    19.     <bean id="userService" class="com.platform.restful.demo.UserService">  
    20.     </bean>  
    21.       
    22.     <!-- 配置需要暴露的BeanService -->  
    23.     <jaxrs:server id="restContainer" address="/">  
    24.         <jaxrs:serviceBeans>  
    25.            <!--  <ref bean="roomService" /> -->  
    26.             <ref bean="userService" />  
    27.         </jaxrs:serviceBeans>  
    28.     </jaxrs:server>  
    29. </beans>  

     此配置文件需要注意几点,一个就是xml的beans声明,需要支持jaxrs:server标签,还有一个就是需要引入CXF自己的一些Spring配置项。cxf.xml在cxf-3.1.12.core.jar下面的META-INF下面,cxf-servlet.xml is 在 cxf-rt-transports-http jar下面的META-INF下面。最后就是注意要暴露的Service类需要配置在jaxrs:server标签中,这样REST资源才能生效。我们就看一个服务吧,在看之前先说明一点,代码有问题,先这么写,根据爆出的问题,咱们再修改代码。

    先建立值对象

    Java代码  
    1. package com.platform.restful.demo;  
    2.   
    3. import javax.xml.bind.annotation.XmlRootElement;  
    4.   
    5. @XmlRootElement(name = "UserVO")  
    6. public class UserVO {  
    7.   
    8.     private int id;  
    9.     private String name;  
    10.   
    11. //省去setter和getter  
    12. }  

     下面是DAO

    Java代码  
    1. package com.platform.restful.demo;  
    2.   
    3. import java.util.HashMap;  
    4. import java.util.Map;  
    5.   
    6. public class UserDAO {  
    7.       
    8.     private static Map<String, UserVO> userVOs;  
    9.       
    10.     static {  
    11.         userVOs = new HashMap<String, UserVO>();  
    12.       
    13.         UserVO u1=new UserVO();  
    14.         u1.setId(1);  
    15.         u1.setName("liuyan");  
    16.           
    17.         UserVO u2=new UserVO();  
    18.         u2.setId(2);  
    19.         u2.setName("yexiaochai");  
    20.           
    21.         userVOs.put("1", u1);  
    22.         userVOs.put("2", u2);  
    23.     }  
    24.       
    25.     public static Map<String,UserVO> getPersons(){  
    26.         return userVOs;  
    27.     }  
    28.       
    29.     public static UserVO getPerson(){  
    30.         return userVOs.get("1");  
    31.     }  
    32.   
    33. }  

     下面就是爆出来的门面服务类了

    Java代码  
    1. package com.platform.restful.demo;  
    2.   
    3. import java.util.Map;  
    4.   
    5. import javax.ws.rs.Consumes;  
    6. import javax.ws.rs.GET;  
    7. import javax.ws.rs.Path;  
    8. import javax.ws.rs.Produces;  
    9.   
    10. @Path("/userservice")  
    11. @Produces("application/json")  
    12. public class UserService {  
    13.       
    14.     @GET  
    15.     @Path("/getUsers")  
    16.     @Consumes("application/xml")  
    17.     public Map<String, UserVO> getUsers() {  
    18.         System.out.println("get users ");  
    19.         Map<String, UserVO> userVOs = UserDAO.getPersons();  
    20.         return userVOs;  
    21.     }  
    22.       
    23.     @GET  
    24.     @Path("/getUser")  
    25.     @Consumes("application/xml")  
    26.     public UserVO getUser() {  
    27.         System.out.println("get user ");  
    28.         UserVO userVO = UserDAO.getPerson();  
    29.         return userVO;  
    30.     }  
    31.   
    32. }  

     我们将项目部署到Tomcat上,打开浏览器,输入URL

    http://127.0.0.1:8080/cxfdemo/service/userservice/getUser

    则输出了一段Json信息

    Java代码  
    1. {"UserVO":{"id":1,"name":"liuyan"}}  

     那我们输入URL:

    http://127.0.0.1:8080/cxfdemo/service/userservice/getUsers

    会是什么效果呢,控制台报出如下错误

    Java代码  
    1. 2011-6-15 13:52:47 org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor writeResponseErrorMessage  
    2. 警告: 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

    复合对象

    Java代码  
    1. package com.platform.restful.demo;  
    2.   
    3. import java.util.Map;  
    4. import javax.xml.bind.annotation.XmlRootElement;  
    5.   
    6. @XmlRootElement(name = "UserVOMap")  
    7. public class UserVOMap {  
    8.   
    9.     private Map<String, UserVO> userVOs;  
    10.   
    11.     public Map<String, UserVO> getUserVOs() {  
    12.         return userVOs;  
    13.     }  
    14.   
    15.     public void setUserVOs(Map<String, UserVO> userVOs) {  
    16.         this.userVOs = userVOs;  
    17.     }  
    18.   
    19. }  

     Service服务类修改如下

    Java代码  
    1. @GET  
    2. @Path("/getUsers")  
    3. @Consumes("application/xml")  
    4. public UserVOMap getUsers() {  
    5.     System.out.println("get users ");  
    6.     Map<String, UserVO> userVOs = UserDAO.getPersons();  
    7.     UserVOMap userVOMap = new UserVOMap();  
    8.     userVOMap.setUserVOs(userVOs);  
    9.     return userVOMap;  
    10. }  

     之后再次访问http://127.0.0.1:8080/cxfdemo/service/userservice/getUsers

    获得Json数据如下

    Java代码  
    1. {"UserVOMap":{"userVOs":{"entry":[{"key":2,"value":{"id":2,"name":"yexiaochai"}},{"key":1,"value":{"id":1,"name":"liuyan"}}]}}}  
  • 相关阅读:
    buuctf—web—高明的黑客
    buuctf—web—Easy Calc
    buuctf刷题之旅—web—EasySQL
    buuctf刷题之旅—web—随便注
    buuctf刷题之旅—web—WarmUp
    Dao
    Spring AOP配置
    分布式
    tomcat配置
    JVM知识
  • 原文地址:https://www.cnblogs.com/baorantHome/p/7381599.html
Copyright © 2011-2022 走看看