[CXF REST標準實戰系列] 二、Spring4.0 整合 CXF3.0,實現測試接口(轉)
轉自:[CXF REST標準實戰系列] 二、Spring4.0 整合 CXF3.0,實現測試接口
文章Points:
1、介紹RESTful架構風格
2、Spring配置CXF
3、三層初設計,實現WebService接口層
4、撰寫HTTPClient 客戶端,並實現簡單調用
介紹RESTful架構風格
REST是REST之父Roy Thomas創造的,當時提出來了REST的6個特點:客戶端-服務器的、無狀態的、可緩存的、統一接口、分層系統和按需編碼。其具有跨語言和跨平臺的優勢。
REST是一種架構風格。其描述性的狀態包括資源數據的內容和表達格式(XML,JSON等)。請求其中一個資源:方為一個指定性和描述性的URI,經由HTTP將資源的表達從服務器轉移到客戶端,或者相反方向。
REST不是一種技術,也不是一個標準或者協議,它擁有標準:HTTP+URI+XML(JSON),來實現其要求的架構風格。
泥瓦匠的記憶宮殿:“REST其實就像萬能規則一樣。如果你遵循它的規則的話,就能得她提供給你的資源數據。”
Spring配置CXF
泥瓦匠用的是Spring4.0.x和CXF3.0.x版本。有兄長說過讓我用其他的輕量級的Web Service框架,我最後考慮了下還是用CXF。
1、第一步配置所需的依賴包jars
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
< dependency >
< groupId >org.apache.cxf</ groupId >
< artifactId >cxf-rt-frontend-jaxws</ artifactId >
< version >3.0.3</ version >
</ dependency >
< dependency >
< groupId >org.apache.cxf</ groupId >
< artifactId >cxf-rt-transports-http</ artifactId >
< version >3.0.3</ version >
</ dependency >
< dependency >
< groupId >org.apache.cxf</ groupId >
< artifactId >cxf-rt-frontend-jaxrs</ artifactId >
< version >3.0.3</ version >
</ dependency >
|
在以前2.x的CXF上,bug和配置上很復雜。3.0以後很方便,用了MAVEN後,就是直接拷貝下上面的代碼放到pom.xml即可。
2、配置Spring文件
首先配置CXF所需的XSD地址,表死我們引用了這個結構定義。
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
< beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:context = "http://www.springframework.org/schema/context"
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-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">
//...配置cxf
</ beans >
|
然後泥瓦匠用配置核心的配置。在<beans></beans>直接加入所需要的cxf配置。
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
< bean id = "regUser" class = "com.xidian.wq.imaopay.controller.webservice.UserInfoController" ></ bean >
<!-- CXF 攔截器 <ref bean="tokenInterceptor" />
<bean id="tokenInterceptor" class="com.xidian.wq.imaopay.interceptor.cxf.TokenInterceptor" />
-->
<!-- address-請求路徑 -->
< jaxrs:server id = "imaoPayService" address = "/ipservice" >
<!-- 輸入攔截器設置 -->
< jaxrs:inInterceptors >
</ jaxrs:inInterceptors >
<!-- 輸出攔截器設置 -->
< jaxrs:outInterceptors >
</ jaxrs:outInterceptors >
<!-- serviceBeans-暴露的WebService服務類 -->
< jaxrs:serviceBeans >
< ref bean = "regUser" />
</ 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 >
|
根據代碼的備註,泥瓦匠想讓大家記住幾點重要性的點。
address="/ipservice" 表示我們以後用此地址訪問所提供的地址。
<jaxrs:serviceBeans><jaxrs:serviceBeans/> 之間加入我們要暴露出去的服務類。這裏泥瓦匠以一個簡單的註冊類來提供。
jaxrs:extensionMappings 是表示我們需要支持的協議。
3、UserInfoController是我們需要完成的暴露服務類。下面泥瓦匠說一下初設計(這點請大家指點指點)。
三層初設計,實現WebService接口層
初設計:
按著原來的SpringMVC的三層架構,我這邊把原來的Controller層轉為暴露在出來的接口服務類。自然View層也就沒了。
UserInfoController的代碼如下:
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Path("/user")// 訪問路徑
@Produces("*/*")
public class UserInfoController
{
@POST
@Path("/doTest")// 訪問路徑
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})// 響應內容 MIME 類型
public String doTest(String requestXml)//@QueryParam("regRequestXml")
{
System.out.println("服務端獲取到客戶端的報文如下:\n"+requestXml);
/* 構造響應報文 */
String responseXml = "響應的報文內容";//構造報文 XML 格式的字符串
return responseXml;
}
}
|
暴露的接口層,也可以用inteface類加實現類來完成。泥瓦匠覺得多此一舉,興許我大言不慚。
泥瓦匠總結如下:
@POST 表示HTTP的訪問模式
@Path 表示訪問路徑
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) 響應內容 MIME 類型
泥瓦匠還在上一篇寫過了對報文的處理:JAXB xml與javaBean的轉換。具體請查閱。
HTTPClient 客戶端,並實現簡單調用
“實踐出真理。”拿出來遛一遛即可。泥瓦匠簡單的用HTTPClient訪問
核心代碼如下:
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
/**
* 註冊報文發送案例
*/
private void doRegXml() throws Exception
{
/** 構造測試報文頭對象 */
String randNum = RandomStringUtils.randomNumeric(8);//八位
String timeStr = TimeUtil.getTimeSimple();
DataBean dataBean = new DataBean();
dataBean.setBatch_no("N20150204");
dataBean.setData_type("000001");
dataBean.setVersion("v1.0");
dataBean.setUser_name("13957706713");
dataBean.setMsg_sign("未知");
dataBean.setRd_num(randNum);
dataBean.setRd_time(timeStr);
dataBean.setK_sign(TokenCheckUtil.getSignature(null, timeStr, randNum));
/** 構造測試報文體對象 */
RegBean regBean = new RegBean();
regBean.setReg_sn("REG20150204");
regBean.setUser_id(15);
regBean.setReg_no("33");
regBean.setReg_way("pc");
regBean.setSet_time(TimeUtil.getTimeAll());
regBean.setRet_url("未知");
regBean.setRemarks("無備註");
RegBean regBean2 = new RegBean();
regBean2.setReg_sn("REG20150203");
regBean2.setUser_id(13);
regBean2.setReg_no("44");
regBean2.setReg_way("mobile");
regBean2.setSet_time(TimeUtil.getTimeAll());
regBean2.setRet_url("未知");
regBean2.setRemarks("無備註");
List< RegBean > regBeans = new ArrayList< RegBean >();
regBeans.add(regBean);
regBeans.add(regBean2);
MsgRegBean msgRegBean = new MsgRegBean();
msgRegBean.setDataBean(dataBean);
msgRegBean.setRegBeans(regBeans);
String regRequestXml = JaxbObjectAndXmlUtil.object2Xml(msgRegBean);//構造報文 XML 格式的字符串
System.out.println("\n 請求報文XML: \n"+regRequestXml);
/** 獲取的Result報文,然後客戶端處理業務。 */
String resultString = HttpUtil.doPost("http://localhost:8080/imaopay/pay/ipservice/user/doTest",regRequestXml);
System.out.println("\n 獲取的Result報文: \n"+resultString);
}
|
運行後,控制臺打印出如下結果:
客戶端打印如下:
服務端獲取結果如下:
[CXF REST標準實戰系列] 二、Spring4.0 整合 CXF3.0,實現測試接口(轉)