完整版見https://jadyer.github.io/
XFire與Spring的內建方式,我所測試過的,有兩種
①取道org.springframework.web.servlet.DispatcherServlet
②取道org.codehaus.xfire.spring.XFireSpringServlet
本文示範的是XFire與Spring內建的第一種方式
有關第二種方式的資料,請參閱我的下一篇博文——XFire與Spring內建的第二種方式
首先是web.xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml,/WEB-INF/myxfire-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>myxfire</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myxfire</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
<!-- 依據Spring規範,此時應建立一個名為myxfire-servlet的XML檔案 -->
<!-- 其中myxfire是這裡配置的DispatcherServlet的名稱 -->
<!-- 此時就不需要service.xml了,因為Web服務的定義在myxfire-servlet.xml中可以找到 -->
接着是applicationContext.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.5.xsd">
<!-- 配置對應的bean -->
<bean id="HelloServiceBean" class="com.jadyer.server.HelloServiceImpl" />
</beans>
然後是重頭戲myxfire-servlet.xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 引入XFire預配置資訊 -->
<!-- 在XFire核心JAR包中擁有一個預定義的Spring配置檔案,即xfire.xml檔案 -->
<!-- 它定義了XFire在Spring中必須用到的一些Bean和資源 -->
<import resource="classpath:org/codehaus/xfire/spring/xfire.xml"/>
<!-- 定義通路的URL -->
<!-- 注意:在Spring2.5中,此時需要額外引入spring-webmvc.jar -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<!-- 定義WebService的通路路徑,有幾個路徑就需要配置幾個<entry>資訊 -->
<!-- 本例中,WSDL通路位址為http://127.0.0.1:8080/XFire_Spring_02/XFireServer.ws?wsdl -->
<entry key="/XFireServer.ws">
<ref bean="HelloService"/>
</entry>
</map>
</property>
</bean>
<!-- 使用XFire導出器 -->
<!-- XFire為Spring提供了友善易用的導出器XFireExporter -->
<!-- 借助XFireExporter的支援,我們可以在Spring容器中将一個業務類導出為WebService -->
<!-- 并且,按照标準的配置,對于任何導出器,都需要引入XFire環境,即serviceFactory和xfire屬性 -->
<!-- 其中ServiceFactory是XFire的核心類,它可以将一個POJO生成為一個WebService -->
<!-- 本例中,這裡通過定義一個baseWebService,其餘的WebService配置可以将該bean作為父bean -->
<!-- 這樣可以簡化Spring的配置,不需要多次引入serviceFactory和xfire屬性 -->
<bean id="baseWebService" class="org.codehaus.xfire.spring.remoting.XFireExporter" lazy-init="false" abstract="true">
<!-- 引用xfire.xml中定義的工廠 -->
<property name="serviceFactory" ref="xfire.serviceFactory"/>
<!-- 引用xfire.xml中的xfire執行個體 -->
<property name="xfire" ref="xfire"/>
</bean>
<!-- 定義暴露的WebService -->
<bean id="HelloService" parent="baseWebService">
<!-- 業務服務bean -->
<property name="serviceBean" ref="HelloServiceBean"/>
<!-- 業務服務bean的窄接口類 -->
<!-- 實際應用中,當某個類有很多的方法時,如果其中有幾個方法不需要開放為WebService時 -->
<!-- 那麼此時我們可以定義一個窄接口,該接口中隻需定義那些開放為WebService的業務方法 -->
<!-- 窄接口中的方法在真實的系統中可能需要引用其它的業務類或DAO擷取資料庫中的真實資料 -->
<!-- 其實,将一個業務類所有需要開放為WebService的方法通過一個窄接口來描述是值得推薦的 -->
<!-- 這會讓WebService的接口顯得很幹淨 -->
<!-- 并且XFire的導出器也需要服務接口的支援,因為它采用了基于接口的動态代理技術 -->
<property name="serviceClass" value="com.jadyer.server.HelloService"/>
</bean>
</beans>
接下來我再将Web服務相應的接口和實作類粘貼出來
其實這裡用到的接口和實作類等,與我之前的文章使用XFire開發WebServices服務端裡用到的,都是一樣的
package com.jadyer.server;
import java.util.List;
import com.jadyer.model.Person;
import com.jadyer.model.User;
/**
* 暴露成web服務的接口類
*/
public interface HelloService {
public String sayHello(String name); //簡單對象的傳遞
public Person getPerson(User u); //對象的傳遞
public List<Person> getPersonList(Integer age, String name); //List的傳遞
}
然後是接口的實作類
package com.jadyer.server;
import java.util.ArrayList;
import java.util.List;
import com.jadyer.model.Person;
import com.jadyer.model.User;
/**
* 暴露成web服務的接口的實作類
* @see 該類必須顯式或隐式的提供一個public的無參的【即預設的】構造函數
* @see 否則XFire将無法初始化該類
*/
public class HelloServiceImpl implements HelloService {
//Default constructor
public HelloServiceImpl(){}
public String sayHello(String name) {
if(null==name){
return "Hello,World";
}else{
return "Hello," + name;
}
}
public Person getPerson(User u) {
Person p = new Person();
p.setAge(24);
p.setName(u.getName());
return p;
}
public List<Person> getPersonList(Integer age, String name) {
Person p = new Person();
p.setAge(age);
p.setName(name);
List<Person> list = new ArrayList<Person>();
list.add(p);
return list;
}
}
最後是接口中用到的兩個VO類
package com.jadyer.model;
public class User {
private String name;
/*--getter和setter略--*/
}
/**
* 暴露成Web服務的接口用到的兩個VO類
*/
package com.jadyer.model;
public class Person {
private Integer age;
private String name;
/*--getter和setter略--*/
}
最後通路http://127.0.0.1:8080/項目名/XFireServer.ws?wsdl即可檢視到WSDL資訊了