2009年4月14日 星期二

JAX-WS & Apache CXF 二三事(1) - Basic

最近因為工作上的需要,所以研究了目前Java對於SOAP Web Services的東西,最後選擇了Apache CXF作為JAX-WS的implementation.

基本上,因為JAX-WS運用了Annotation,所以在開發上算是簡化了許多,比較不需要使用大量的XML來定義。而且JAX-WS & Apache CXF預設會自動使用JAXB來做訊息格式的轉換,所以基本上只要不是複雜的JavaBean,都可以自動轉換,甚至也不會自己去定義JAXB的東西,算是相當方便。而Apache CXF本身也是支援Spring framework,所以在設定上也是遵照Spring 2.0的設定檔標準,倒是不用另外學習。

Apache CXF其實本身支援相當多的格式與標準,但是目前我只是使用JAX-WS的部份。基本入門可以參考:
Web Services Tutorial with Apache CXF A simple JAX-WS service

基本上就是在service class加上@WebService等適當的annotation,然後在spring的設定檔中加上以下內容:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<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" />
<jaxws:endpoint id="auth"
implementor="com.company.auth.service.AuthServiceImpl"
address="/swAuth"/>
</beans>

其中,前三行的import是必要的,用來載入CXF自己本身的一些預設設定。主要的Web service定義在<jaxws:endpoint/>裏面。其中的implementor是用來指定service implementation class,而address是指service對外公開的名稱,也就是被取用的名稱。spring會根據這個設定,將implementor所描述的class建立出instance,並設定成為JAX-WS的service。如果不想透過指定class name的方式而是想reuse已經存在的bean,則可以省略implementor,而改用<jaxws:implementor>的方式來reference到已定義好的bean

然後在web.xml中加上必要的listener跟servlet設定,如下:
<web-app>
<display-name>Auth Manager</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>

<param-value>classpath:com/company/auth/service/cxf.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>

</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>

</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

</web-app>


其中listener的設定是為了spring,而serlvet的部份才是為了CXF。
而client也可以透過spring來取得web service或是透過JaxWsProxyFactoryBean。

目前有幾點需要注意:
  1. 之前使用2.1.4版會有無法連線的問題,改用2.1.3版之後就正常;2.2.0版雖然release,但是還尚未測試
  2. 即使取得service object,但是並不表示連線就已經建立完成。真正的連線會等到method call進行時,才做連線。
  3. 預設的client的Connection timeout跟receive timeout分別是30s跟60s,所以如果需要等待較長的呼叫時,可能會出現連線中斷。可以透過在client的classpath中加入cxf.xml來覆蓋預設值。詳細的設定可以參考:Client HTTP Transport (including SSL support)

沒有留言: