Spring整合CXF,釋出RSETful 風格WebService
這篇文章是承接之前CXF整合Spring的這個專案示例的延伸,所以有很大一部分都是一樣的。關於釋出CXF WebServer和Spring整合CXF這裡就不再多加贅述了。如果你對Spring整合CXF WebService不瞭解,具體你可以參看這兩篇文章:
http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html
http://www.cnblogs.com/hoojo/archive/2012/07/13/2590593.html
如果你不瞭解restful風格的WebService,你可以參考:
http://www.oracle.com/technetwork/articles/javase/index-137171.html
SpringMVC對RESTful的支援:
http://www.cnblogs.com/hoojo/archive/2011/06/10/2077422.html
使用 Jersey框架,搭建RESTful WebService(這個也比較簡單)
http://www.ibm.com/developerworks/cn/web/wa-aj-tomcat/
官方文件:http://jersey.java.net/nonav/documentation/latest/user-guide.html#d4e8
其中,比較常用的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:hoojo_@126.com
下面我們就接著http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html這篇文章,開始我們CXF RESTful WebService的旅程,enjoy~!^_*
準備工作
首先,你需要新增相關的jar包
其中,jsr331-api-1.1.1.jar是必須的,利用CXF釋出REST服務得用到它,在cxf的lib庫中可以找到這個jar。
下載地址:http://www.apache.org/dyn/closer.cgi?path=/cxf/2.3.11/apache-cxf-2.3.11.zip
其它的jar包都是非必須的!
JavaEntity
package com.hoo.entity;
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
/**
* <b>function:</b> 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
*/
@XmlRootElementpublic class MapBean {private Map<String, User> map;
//@XmlElement(type = User.class)
public Map<String, User> getMap() {
return map;
}public void setMap(Map<String, User> map) {this.map = map;
}}
package com.hoo.entity;
import java.util.HashMap;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
/**
* <b>function:</b> 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<User> users;
private User[] userArr;
private HashMap<String, User> maps;
// getter/setter
}package com.hoo.entity;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;
/**
* <b>function:</b>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
@Overridepublic 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 型別。
*/
/**
* <b>function:</b> 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/<id> 訪問新聯絡人
*/
@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 型別。
*/
/**
* <b>function:</b> 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<User> list = new ArrayList<User>();
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<String, User> map = new HashMap<String, User>();
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/<id> 訪問新聯絡人
*/
@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);
}
}
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsdhttp://cxf.apache.org/jaxrshttp://cxf.apache.org/schemas/jaxrs.xsd">
特別注意上面加粗帶下劃線的部分,這是新增加的配置。我們釋出restful WebService需要用到它。然後在配置檔案中新增如下配置<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 id="restSample" class="com.hoo.service.RESTSampleSource"/><!-- 這裡的地址很重要,客戶端需要通過這個地址來訪問WebService -->
<jaxrs:server id="restServiceContainer" address="/rest"><jaxrs:serviceBeans><ref bean="restSample" /></jaxrs:serviceBeans><jaxrs:extensionMappings><entry key="json" value="application/json" /><entry key="xml" value="application/xml" /></jaxrs:extensionMappings><jaxrs:languageMappings><entry key="en" value="en-gb"/></jaxrs:languageMappings></jaxrs:server>這樣伺服器端就完成了CXF RESTful WebService的釋出,啟動你的tomcat。然後在瀏覽器中服務地址:http://localhost:8000/CXFWebService/ (其實這裡請求的是CXFServlet,你可以看看上一篇Spring整合CXF文章的web.xml的配置)
你就可以看到我們這裡剛剛釋出的RESTSample rest的WebService
你也可以看看裡面的xml,也就是WebService的wsdl檔案內容。我們找一個GET方式的WebService的方法,在瀏覽器中呼叫一下試試
http://localhost:8000/CXFWebService/rest/sample/bean/123
這個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;
/**
* <b>function:</b> 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;@Beforepublic 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);}@Afterpublic void destory(){}@Testpublic void testGet() {System.out.println(client.path("sample").accept(MediaType.TEXT_PLAIN).get(String.class));}@Testpublic void testRequest() {System.out.println(client.path("sample/request/234234").accept(MediaType.TEXT_PLAIN).get(String.class));}@Testpublic void testBean() {User user = client.path("sample/bean/{id}", 25).accept(MediaType.APPLICATION_XML).get(User.class);System.out.println(user);}@Testpublic void testList() {System.out.println(client.path("sample/list").accept(MediaType.APPLICATION_XML).get(Users.class).getUsers());}@Testpublic void testMap() {System.out.println(client.path("sample/map").accept(MediaType.APPLICATION_XML).get(MapBean.class).getMap());}@Testpublic void testDeleteData() {client.path("sample/removeData/23").delete();
}@Testpublic 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));}@Testpublic 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中增加如下配置<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd">
<bean id="webClient" class="org.apache.cxf.jaxrs.client.WebClient" factory-method="create"><constructor-arg type="java.lang.String" value="http://localhost:8000/CXFWebService/rest/" /></bean></beans>這種是利用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中增加配置如下:
<bean id="restSampleBean" class="org.apache.cxf.jaxrs.client.JAXRSClientFactory" factory-method="create"><constructor-arg type="java.lang.String" value="http://localhost:8000/CXFWebService/rest/" /><constructor-arg type="java.lang.Class" value="com.hoo.service.RESTSample" /></bean>
執行以上方法可以看到控制檯列印結果如下:
client consoleorg.apache.cxf.jaxrs.client.ClientProxyImpl@1cf7491this is get rest request
22#JojO#null#nullcom.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#gz111#hoojo#hoojo_@126.com#hoojo#gzserver console####getBean#####id:22Method:GETuri:sample/bean/22{id=[22]}####getList#####Method:GETuri:sample/list{}####getMap#####Method:GETuri:sample/map{}21432134#hoojo#hoojo_@126.com#hoojo#gz#####putData#####21432134#hoojo#hoojo_@126.com#hoojo#gz111#hoojo#hoojo_@126.com#hoojo#gz#######deleteData#######2就這樣,整合restful WebService成功。
相關文章
- WebService之Spring+CXF整合示例WebSpring
- 使用CXF與Spring整合實現RESTFul WebServiceSpringRESTWeb
- apache cxf-2.4.3 +spring-3.0.5釋出SOAP協議WebService服務ApacheSpring協議Web
- Cxf - Spring整合Cxf暴露WebServicesSpringWeb
- CXF--整合SpringSpring
- Cxf - Spring整合呼叫WebServicesSpringWeb
- maven+CXF+Spring+tomcat 開發webserviceMavenSpringTomcatWeb
- xfire+spring整合webserviceSpringWeb
- 用cxf編寫基於spring的webservice之下篇SpringWeb
- 基於Maven的Spring整合CXFMavenSpring
- Spring3.2 + cxf1.7.3整合Spring
- 使用 CXF 整合 Spring 開發 Web ServiceSpringWeb
- Apache CXF 與 Spring 整合簡單例子ApacheSpring單例
- CXF實現webService服務(一)Web
- CXF開發及與Spring整合開發Spring
- C#釋出WebServiceC#Web
- cxf設定代理訪問webservice介面Web
- cxf WebService設定wsdl中soapAction的值Web
- CXF建立webservice客戶端和服務端Web客戶端服務端
- CXF入門教程(1) -- 第一個webServiceWeb
- Spring和cxf3的整合,以maven的方式SpringMaven
- 實踐基於REST風格的Webservice(PHP,C#)RESTWebPHPC#
- CXF入門教程(5) -- webService非同步呼叫模式Web非同步模式
- Spring+xfire和Spring+CXF在Weblogic上釋出服務遇到的問題SpringWeb
- 【原創】WebService大講堂之Axis2(7):將Spring的裝配JavaBean釋出成WebServiceWebSpringJavaBean
- Spring Boot整合Spring Cloud Release進行版本釋出管理Spring BootCloud
- WebService框架大比較(Axis,axis2,Xfire以及cxf)Web框架
- 京東科技風格 NutUI 釋出了UI
- axis2 WebService的釋出與呼叫Web
- 使用services.xml檔案釋出WebServiceXMLWeb
- 如何將多個SessionBean釋出為WebServiceSessionBeanWeb
- 使用瀏覽器位址列呼叫CXF Webservice的寫法瀏覽器Web
- 開發:隨筆記錄之 CXF 動態呼叫Webservice筆記Web
- Pycharm 程式碼註釋風格模板PyCharm
- 華為Nova/Nova Plus正式釋出:兩者設計風格迥異
- 米家新電水壺釋出:標準米家風格定價99元
- 批量匯出 CSDN 部落格並轉為 hexo 部落格風格Hexo
- SpringBoot整合Apache-CXF實踐Spring BootApache