天天看點

【Apache CXF】CXF對JAX-RS的支援

用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

舉個例子:

本文出自 “” 部落格,請務必保留此出處

繼續閱讀