轉(zhuǎn)自http://cxshun.iteye.com/blog/1273147
最近公司最近需要將以前提供出去的接口統(tǒng)一用一個(gè)標(biāo)準(zhǔn)來實(shí)現(xiàn),考慮到webservice這個(gè)是標(biāo) 準(zhǔn),因此我花時(shí)間大概學(xué)習(xí)了一下webservice,也對(duì)JAVA的幾個(gè)webservice框架進(jìn)行了一些小例子的學(xué)習(xí)。
JAVA調(diào)用webservice,當(dāng)你剛開始接觸的時(shí)候你會(huì)覺得它是一個(gè)惡夢(mèng),特別是沒有一個(gè)統(tǒng)一的標(biāo)準(zhǔn)實(shí)現(xiàn),比起.net的那些幾步就可以完成的webservice實(shí)現(xiàn),我們看著JAVA的實(shí)現(xiàn)真是傷心啊。但就算是傷心,我們也還是要完成的。JAVA也不乏比較好的實(shí)現(xiàn),如xfire,jersey,CXF。有人會(huì)說axis2,那個(gè)東西,看著就傷心,它不包括在比較好里面,比較差里面反倒有它的一席之位。怎么差,這里先不說,我們慢慢地來看看這幾個(gè)框架的實(shí)現(xiàn)。
今天我們就先一起來看一下xfire的實(shí)現(xiàn),接下來的幾天我們會(huì)慢慢一起來學(xué)習(xí)另外的框架。
1)首先,當(dāng)然是要下包啦,這個(gè)普通人都知道。http://xfire.codehaus.org/Download可以到這里去下,可以下all也可以下distribution。但建議還是下all的,免得一堆奇怪的問題搞得你一點(diǎn)信心都沒了。
包弄下來了那么怎么辦呢?放進(jìn)項(xiàng)目里啊。貌似廢話,但很多人就是不知道下下來要干什么用。
建一個(gè)新項(xiàng)目,比較我的是xfireWebservice,這里當(dāng)然是建web項(xiàng)目啦。


我這里是把它所有的包都放到這里面了,畢竟我們寫例子,就沒必要挑三揀四了,隨便點(diǎn)吧,如果想看看異常信息的朋友可以不把全部放進(jìn)去,慢慢地加入,以后遇到錯(cuò)誤也好排除,但我們這里就不那么做了,畢竟一般缺少什么類那些的異常沒什么難看的,大家可以自己排除。
2)我們首先來了解一下xfire與其他webservice框架的不同,它最大的不同之處在于它需要一個(gè)接口,而且如果需要用xfire來調(diào)用相應(yīng)的webservice必須知道接口的定義,感覺這里有點(diǎn)限制了。但除了這點(diǎn),xfire調(diào)用webservice,那是相當(dāng)?shù)姆奖悖透{(diào)用本地方法一樣。我們直接來看例子:
首先是最重要的接口:
Java代碼

- public interface IReaderService {
- public Reader getReader(String name,String password);
- public List<Reader> getReaders();
- }
有接口,當(dāng)然也要有實(shí)現(xiàn)類,不然接口就沒什么意義了。
Java代碼

- public class ReaderService implements IReaderService{
- public Reader getReader(String name,String password) {
- return new Reader(name,password);
- }
-
- public List<Reader> getReaders(){
- List<Reader> readerList = new ArrayList<Reader>();
- readerList.add(new Reader("shun1","123"));
- readerList.add(new Reader("shun2","123"));
- return readerList;
- }
- }
也看一下JAVABEAN,Reader類:
Java代碼

- public class Reader{
- private static final long serialVersionUID = 1L;
- private String name;
- private String password;
-
- public Reader(){}
- public Reader(String name,String password) {
- this.name = name;
- this.password = password;
- }
- //Get/Set方法省略
- public String toString(){
- return "Name:"+name+",Password:"+password;
- }
-
- }
注意,我們這里的Reader類實(shí)現(xiàn)了Serializable接口,為什么呢?這里,首先我們需要了解webservice的原理,對(duì)于JAVA來講,如果我們需要在互聯(lián)網(wǎng)上傳對(duì)象,很多人當(dāng)然會(huì)想到序列化,對(duì)了,這里就是序列化,因?yàn)槲覀冃枰裷eader作為參數(shù)來傳遞。這在以前的版本中是需要強(qiáng)制實(shí)現(xiàn),否則會(huì)報(bào)錯(cuò),但現(xiàn)在的最新的版本(其實(shí)最新的也是07年的,因?yàn)閤fire已經(jīng)停止開發(fā),被apache合并為CXF項(xiàng)目,這個(gè)我們之后再講)已經(jīng)不需要了,至于是用什么方式實(shí)現(xiàn)的,我們這里暫時(shí)不深究,因?yàn)樗呀?jīng)被合并到CXF中,我們?nèi)绻钊雽W(xué)習(xí),應(yīng)該學(xué)習(xí)CXF較好。
3)當(dāng)我們完成上面的接口和JAVABEAN的編寫后,很多人會(huì)問,我看很多webservice都會(huì)有WSDL文件,那你這個(gè)怎么來的?在講這個(gè)之前,我們來討論一下什么是WSDL。也許很多公司提供的接口都還是只是一個(gè)HTTP地址,返回XML這樣的格式,我們的也是。這有一個(gè)好處,也有一個(gè)壞處。好處是我們開發(fā)的難度小了,而壞處是我們需要提供給用戶一堆說明文件,每個(gè)返回的XML標(biāo)簽是什么意思,這倒也沒啥,但就是比較煩而已。而webservice呢,壞處就是我們開發(fā)的東西稍微多了點(diǎn),而好處是我們不用再寫那么多說明文件,因?yàn)橛幸粋€(gè)統(tǒng)一的說明,叫WSDL,這個(gè)是webservice的說明文檔,是統(tǒng)一的,無論什么語言都一樣,所以不存在誰看不懂的問題。
而這里,當(dāng)我們部署完成xfire后,它就可以幫我們生成WSDL文件。
問題是怎么部署,這個(gè)其實(shí)也簡(jiǎn)單。我們?cè)趕rc目錄下新建一個(gè)文件夾META-INF,再建它的一個(gè)字文件夾xfire,里面建立文件services.xml。之后的結(jié)構(gòu)如下:

有人會(huì)問為什么要建到src目錄下,其實(shí)不是規(guī)定建到這里的,但因?yàn)槲覀冃枰岄_發(fā)工具幫我們自己部署這幾個(gè)文件,所以我們放到這里,eclipse就可以幫我們自己部署到tomcat或者其他的容器中。注意,這個(gè)文件所在文件夾層次是固定的,不可以修改。
我們直接看一下servics.xml:
Xml代碼

- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://xfire.codehaus.org/config/1.0">
- <service>
- <!-- webserviceq名稱,調(diào)用時(shí)需要指定這個(gè) -->
- <name>readerService</name>
- <!-- 這個(gè)一般是自己公司的網(wǎng)址,意義不大 -->
- <namespace>http://test/HelloService</namespace>
- <!-- 接口類 -->
- <serviceClass>com.xfire.servlet.IReaderService</serviceClass>
- <!-- 實(shí)現(xiàn)類 -->
- <implementationClass>com.xfire.servlet.ReaderService</implementationClass>
- </service>
- </beans>
看著注釋一般都沒問題的。
4)很多人以為這樣就行了,不,還沒行,你指定了這個(gè),那別人怎么訪問呢。怎么把相應(yīng)的請(qǐng)求轉(zhuǎn)發(fā)到xfire那里,讓它進(jìn)行處理呢。這里又需要修改web.xml了。
修改后如下:
Xml代碼

- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- id="WebApp_ID" version="3.0">
- <servlet>
- <servlet-name>XFireServlet</servlet-name>
- <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>XFireServlet</servlet-name>
- <url-pattern>/services/*</url-pattern>
- </servlet-mapping>
- </web-app>
其實(shí)也就是添加了一個(gè)servlet和對(duì)應(yīng)的mapping。接下來,我們?cè)跒g覽器上直接輸入:
http://localhost:8080/xfireWebService/services/readerService?wsdl
我們可以看到:

這里顯示的就是wsdl,它會(huì)顯示我們定義的方法,返回的類型,這個(gè)文件我們這里就不分析了,http://webservices.group.iteye.com/group/topic/11467這位朋友在這里寫得很清楚,想了解的朋友可以到這里看看。
5)上面四步完成后,我們就完成了webservice的部署了。別人就可以調(diào)用相應(yīng)的webservice來訪問我們的方法了。下面我們就用xfire提供的client來訪問一下我們剛才發(fā)布的webservice:
Java代碼

- public class ReaderClient {
- public static void main(String[] args) {
- //這里是創(chuàng)建一個(gè)service,需要傳入一個(gè)接口類,因?yàn)槲覀兒竺姹仨氄{(diào)用相應(yīng)的接口方法
- Service srcModel = new ObjectServiceFactory().create(IReaderService.class);
- //代理工廠,這里是為了后面創(chuàng)建相應(yīng)的接口類
- XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire());
- //webservice地址,不需要加wsdl
- String readerServiceUrl = "http://localhost:8080/xfireWebService/services/readerService";
-
- try {
- //利用工廠返回相應(yīng)的接口類
- IReaderService readerService = (IReaderService)factory.create(srcModel,readerServiceUrl);
-
- Reader reader = readerService.getReader("shun","123");
- System.out.println(reader);
- } catch (MalformedURLException e) {
- e.printStackTrace();
- }
- }
- }
這樣,我們看到輸出結(jié)果為:

很簡(jiǎn)單的調(diào)用,當(dāng)我們?nèi)〉媒涌诤螅磺芯透镜匾粯恿恕fire發(fā)布和調(diào)用webservice相對(duì)其他框架來說是簡(jiǎn)單很多的。接下來幾天,我們會(huì)繼續(xù)學(xué)習(xí)另外的幾個(gè)框架,CXF,axis2和jersey,axis2我們放到最后再講,因?yàn)橄鄬?duì)其他來說,它的靈活性比較差,而且比較麻煩。
另外問個(gè)小問題,有沒有朋友知道怎么修改博客字體大小,我修改完成后保存,它只會(huì)在代碼段那里加上<span>標(biāo)簽,但字體沒有改變,其他的也是一樣,有知道的朋友麻煩跟我說下。