2010年1月4日 星期一

在Spring中利用XFire構建WebService

以往在建構Java的WebService時總是很偷懶的用Eclipse的Web Service工具,很直覺也很方便,但總是會自動生成一些很複雜也不太想看的代碼,這次碰到要在Spring中建構Web Service,便下定決心要好好研究一下如何建構Web Service。

講到建構WebService馬上想到Apache的Axis2,但是Axis對此次目標而言太過複雜,經過一番研究後決定使用XFire

XFire是与Axis 2并列的新一代WebService框架。之所以并称为新一代,因为它:

  • 支持一系列Web Service的新标准--JSR181、WSDL2.0 、JAXB2、WS-Security等 ;
  • 使用Stax解释XML,性能有了质的提高。XFire采用Woodstox 作Stax实现;
  • Easily Create Services from POJOs;
  • Spring的结合;
  • 灵活的Binding机制,包括默认的Aegis,xmlbeans,jaxb2,castor。
接下來說明如何在Spring中加入Web Service

首先建立xfire-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<import resource="classpath:org/codehaus/xfire/spring/xfire.xml" />


<bean id="xmlbeansTypeRegistry" class="org.codehaus.xfire.xmlbeans.XmlBeansTypeRegistry" />
<bean id="webAnnotations"
class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" />
<bean id="handlerMapping" class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping">
<property name="typeMappingRegistry" ref="xmlbeansTypeRegistry" />
<property name="xfire" ref="xfire" />
<property name="webAnnotations" ref="webAnnotations" />
</bean>


<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/">
<ref bean="handlerMapping" />
</entry>
</map>
</property>
</bean>
</beans>

再來是在web.xml中加入以下的片段


<context-param>
<param-name>contextConfigLocation</param-name>
<!--將xfire-servlet.xml加入-->
<param-value>
classpath:/beans.xml
/WEB-INF/xfire-servlet.xml
</param-value>
</context-param>

<servlet>
<servlet-name>xfire</servlet-name>
<servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class>
</servlet>
<!--任何經過/service/進入的都會被此Servlet攔下-->
<servlet-mapping>
<servlet-name>xfire</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

最後是在beans.xml中宣告service


<bean id="personService" class="com.foxconn.service.impl.PersonServiceImpl">
</bean>


在beans.xml中的宣告一如往昔,完全不用修改。

接下來即要進入程式的實現


package com.foxconn.service;

import javax.jws.WebService;

@WebService
public interface PersonService
{
public void add();
}


注意到了嗎?在inteface上方要用annotation宣告此interface為WebService。

再來是interface的實現

package com.foxconn.service.impl;

import javax.jws.WebService;

import com.foxconn.service.PersonService;

@WebService(serviceName = "person", endpointInterface = "com.foxconn.service.PersonService")
public class PersonServiceImpl implements PersonService {

@Override
public void add()
{
// TODO Auto-generated method stub
System.out.println("add....................");
}

}

在此實做類別的上方也要用annotation宣告。
serviceName指的是webservice的名稱。
endpointInterface指的是webservice的進入點。

完成後佈署啓動即可在瀏覽器輸入http://localhost:8080/XFireTest/services/person?wsdl
就可以看到動態生成的WSDL了(XFireTest是專案名稱也就是站點名稱囉)。

接下來要進行webService的測試。

我建立了一個很單純的Java Project,並寫了如下的code

package com.test;
import java.net.URL;

import org.codehaus.xfire.client.Client;


public class ClientTest {

/**
* @param args
*/
public static void main(String[] args)throws Exception
{
// TODO Auto-generated method stub
//利用XFire的Client建立WebService客戶端
Client c = new Client(new URL("http://localhost:8080/XFireTest/services/person?wsdl"));

//呼叫服務,服務的方法為add,一定要傳入引數,但這個service並沒有引數,所以就隨便傳
Object result[] = c.invoke("add",new Object[0]);

}

}

最後執行即可看到Console印出add....................了
在最後撰寫webservice Client端時我心血來潮將一個個要用到Jar放入並,整理如下:

沒有留言: