用CXF建構RESTful services有兩種方式:
·CXF對JAX-RS的實作。
·使用JAX-WS Provider/Dispatch API。
官網上還有Http Bindings方式,他需要做一些繁瑣的工作去建立資源再映射到服務上,這種方式從2.6時已經被移除了。
剛好我這裡有幾個工程都是用第一種方式實作的,在這裡便主要記錄一下spring+CXF建構RESTful service。
首先列舉一下JAX-RS的一些常用注解。
·@Path:指定資源的URI。
·@Produces/@Consumes:指定請求/響應的媒體類型。當類和方法同時被标注時,方法标注會覆寫類标注。
·@GET,@POST,@PUT,@DELETE,@HEAD,@OPTIONS:指定請求的Http method。
·@QueryParam,@PathParam,@HeaderParam,@FormParam,@CookieParam:指定參數值的來源,可标注于類、方法、屬性。
符合以下規則的參數值可以被接收:
·原始類型
·擁有一個String參數的constructor
·有valueOf或者fromString靜态method
另外部分來源也支援SortedSet<T>、List<T>和Set<T>,T需要滿足上面的規則。
相關dependency:
現在我打算定義一個服務用來傳回一組使用者資訊。
當以get method通路users資源時将以XML表述:
接口實作我就簡單寫一下:
定義User時需要注意加上無參的constructor和@XmlRootElement
使用org.apache.cxf.jaxrs.JAXRSServerFactoryBean啟動服務:
通路http://localhost:8888/myRest/users,輸出:
用CXF+Spring方式建構RESTful service也非常友善,雖然也會帶來一些問題。
服務就繼續用上面定義的MyRestService,但是Service的部分屬性将定義在XML configration中,并将service放到容器裡。
(其實也可以non-Spring配置到容器裡,很難想象為什麼要用這種方式,但似乎可以明白點點什麼。)
spring配置,引入了一些不必要的namespace,但也沒什麼大問題:
在web.xml中加入CXFServlet,注意我寫的url pattern是/services/*:
通路,效果如下(還有一個是上一篇的JAX-WS服務):
通路,效果如下:
最後說一下lifecycle的問題。
像這個例子中用bean标簽定義一個服務,此時給他加上scope标簽不會有任何效果。
他始終是預設的——singleton。
jaxrs:server下還有一個子标簽叫jaxrs:serviceFactories,裡面可以存放org.apache.cxf.jaxrs.spring.SpringResourceFactory類型的Bean,SpringResourceFactory将會把服務的聲明周期委派給ApplicationContext來管理。
我可以做如下配置:
但這種方式有些麻煩,難道我就為了讓scope生效定義bean又定義SpringResourceFactory又設定serviceFactoris?
可以更簡便地配置,如下:
需要注意的是beanNames屬性中寫多個值時以space分隔。
别人辛苦建構了RESTful Service,總不能隻用浏覽器調用。
繼續說說Client端的API。
繼續使用上面的例子,這次加個參數,如下:
實作:
User類:
當然,某種程度上org.apache.commons.httpclient.HttpClient也可以調用。
但稍有複雜的情況就無法勝任。
基于代理的API主要是(和spring裡的那幾個ProxyFactoryBean不同,名字裡不帶Proxy)
·org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean
比如我可以這樣使用:
另外,<code>JAXRSClientFactoryBean</code>有一個工廠類:
·org.apache.cxf.jaxrs.client.JAXRSClientFactory
比如可以這樣使用:
讓人感覺很奇怪,提供了一個工廠類卻可以直接使用Bean,官網上沒找到答案,我也不糾結了吧。
上面代碼中使用的MyRestServiceImpl和Server端可以是沒有任何關系的,讓遠端調用變得透明也正是proxy的意義。
值得注意的是,有一個threadSafe屬性,同一個代理是否允許被多線程通路取決于此。
除了JAXRSClientFactoryBean,還有Http-centric web client:
·org.apache.cxf.jaxrs.client.WebClient
舉個例子:
本文出自 “” 部落格,請務必保留此出處