使用Apache Axis部署 Web服務(wù)時(shí)的常見問題及其解決方法
來自: http://www.ibm.com/developerworks/cn/webservices/ws-axisfaq/
1 引言
隨著Web服務(wù)技術(shù)的發(fā)展和成熟,其方便性和易用性已逐漸被人們所接受,越來越多的合作伙伴之間開始利用Web服務(wù)來實(shí)現(xiàn)合作方之間的數(shù)據(jù)接口。使用Apache Axis和Linux平臺(tái)是一種低成本的Web服務(wù)解決方案,但Apache Axis文檔的FAQ對(duì)開發(fā)者來說內(nèi)容還不夠豐富,本文作者將自己使用Axis時(shí)遇到的問題和解決方法整理成文,奉獻(xiàn)給Web服務(wù)的開發(fā)人員和對(duì)此感興趣的讀者朋友,旨在幫助大家節(jié)約一些寶貴的時(shí)間。有關(guān)Web服務(wù)的基礎(chǔ)知識(shí),讀者可以閱讀參考文獻(xiàn)中推薦的文檔。作者未在文中介紹Apache和Resin的安裝方法,讀者可以參考相關(guān)網(wǎng)站的說明文檔。
作者使用的軟件環(huán)境如下。
操作系統(tǒng):Red Hat Linux 7.2
Web服務(wù)器: Apache 1.3.27
應(yīng)用服務(wù)器:Resin 2.1.8 ( http://www.caucho.com/ )
SOAP服務(wù)器:Apache Axis 1.1
XML解析器:Xerces 2.5.0,Xalan 2.5.1
JDK版本:JDK 1.4.1
![]() ![]() |
![]()
|
2.1 Axis運(yùn)行需要哪些jar文件
對(duì)Axis解包后,將axis-1_1/webapps/axis/WEB-INF/lib/目錄下的jar文件復(fù)制到/usr/local/apache/htdocs/WEB-INF/lib目錄下(Web應(yīng)用程序的目錄)。應(yīng)包括以下jar文件。
axis-ant.jar axis.jar commons-discovery.jar commons-logging.jar jaxrpc.jar log4j-1.2.8.jar name.txt saaj.jar wsdl4j.jar |
如果需要使用axis提供的測(cè)試頁(yè)面,還要將axis-1_1/webapps/axis/目錄下的文件復(fù)制到/usr/local/apache/htdocs/axis/目錄下。應(yīng)包括以下募?
EchoHeaders.jws fingerprint.jsp happyaxis.jsp index.html |
XML解析器選用不當(dāng),經(jīng)常會(huì)導(dǎo)致使用Apache Axis時(shí)出現(xiàn)一些莫名其妙的問題。
由于Apache Axis 并未對(duì)Resin內(nèi)置的xml解析器進(jìn)行過測(cè)試,因此推薦讀者使用已通過測(cè)試的Xerces xml解析器??梢詮?http://xml.apache.org/xalan-j/index.html 處下載Xalan的Java版XSLT處理器,其中包含了Xerces的Java版XML解析器,不需要再單獨(dú)下載xml解析器。
Xalan 2.5.1解包后,將bin/目錄下的xercesImpl.jar、xml-apis.jar和xalan.jar復(fù)制到resin安裝目錄的lib/目錄下,例如/usr/local/resin/lib。
編輯/etc/目錄下的profile文件,找到設(shè)置CLASSPATH環(huán)境變量的位置,在其后加入下面的內(nèi)容(B shell)。
XMLPARSER=$RESIN_HOME/lib/xalan.jar:$RESIN_HOME/lib/xercesImpl.jar:$RESIN_HOME/lib/xml-apis.jar export CLASSPATH=$XMLPARSER:$CLASSPATH |
2.2.1 注意事項(xiàng)
如果CLASSPATH中包含其它的XML解析器設(shè)置,應(yīng)將其從CLASSPATH環(huán)境變量的設(shè)置中去掉,以免發(fā)生沖突。
通過修改resin.conf將resin的XmlParser置換為Xerces的XmlParser。在resin.conf對(duì)應(yīng)的Web應(yīng)用程序配置中加入以下設(shè)置。
<system-property javax.xml.transform.TransformerFactory="org.apache.xalan.processor.TransformerFactoryImpl"/> <system-property javax.xml.parsers.DocumentBuilderFactory="org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"/> <system-property javax.xml.parsers.SAXParserFactory="org.apache.xerces.jaxp.SAXParserFactoryImpl"/> <system-property org.xml.sax.driver="org.apache.xerces.parsers.SAXParser"/> |
配置完成后重新啟動(dòng)Resin。
2.4.1 問題描述
使用http://test.com/axis查看已部署的服務(wù)時(shí)出現(xiàn)Axis內(nèi)部錯(cuò),顯示有關(guān)WSDD配置的異常信息。如果把WEB-INF目錄下的server-config.wsdd刪除,再查看就正常了,但只能看到AdminService和Version兩個(gè)系統(tǒng)缺省的服務(wù),后來部署的服務(wù)都看不到了。
2.4.2 原因分析
Axis會(huì)在WEB應(yīng)用程序的WEB-INF/目錄下自動(dòng)生成一個(gè)名字為server-config.wsdd的xml文件,其中記錄了已部署的WEB服務(wù)。每部署一個(gè)新的WEB服務(wù)時(shí),Axis都會(huì)將新服務(wù)的描述信息加入到server-config.wsdd中。
故障站點(diǎn)使用的XmlParser是resin內(nèi)置的XmlParser,Axis并未對(duì)其對(duì)進(jìn)行過兼容性測(cè)試,查看WEB服務(wù)信息時(shí)需要從server-config.wsdd(這是一個(gè)xml文件)取得已部署的WEB服務(wù)描述信息,當(dāng)server-config.wsdd的內(nèi)容較復(fù)雜時(shí),resin內(nèi)置的XmlParser因某種原因出現(xiàn)異常,導(dǎo)致Axis內(nèi)部錯(cuò)誤。Server-config.wsdd中記錄的Web服務(wù)描述信息較少時(shí)不會(huì)出現(xiàn)異常。
2.4.3 解決方法
修改resin.conf,將resin的XmlParser置換為Xerces的XmlParser。置換方法參見2.3節(jié)。
2.4.4 小結(jié)
如果Axis報(bào)告的錯(cuò)誤中有關(guān)于xml解析器的錯(cuò)誤,建議讀者參照本小節(jié)描述的方法更換應(yīng)用服務(wù)器的xml解析器,將會(huì)有助于問題的解決。
2.5 如何將Axis集成到Resin或其它應(yīng)用服務(wù)器
Axis是以Servlet的方式運(yùn)行的,而Resin的作用相當(dāng)于Servlets容器(Container),因此只要配置得當(dāng),就可以使Axis在Resin環(huán)境中運(yùn)行,這一點(diǎn)也適用于Resin以外的其它應(yīng)用服務(wù)器。在Resin中配置Axis的方法如下。
將axis-1_1/webapps/axis/WEB-INF/web.xml中的Servlet配置項(xiàng)復(fù)制到resin.conf中對(duì)應(yīng)的Web應(yīng)用程序配置中。通常應(yīng)包括以下內(nèi)容。
<!-- Axis Web-Service Configuration Start --> <servlet> <servlet-name>AxisServlet</servlet-name> <display-name>Apache-Axis Servlet</display-name> <servlet-class> org.apache.axis.transport.http.AxisServlet </servlet-class> </servlet> <servlet> <servlet-name>AdminServlet</servlet-name> <display-name>Axis Admin Servlet</display-name> <servlet-class> org.apache.axis.transport.http.AdminServlet </servlet-class> <load-on-startup>100</load-on-startup> </servlet> <servlet> <servlet-name>SOAPMonitorService</servlet-name> <display-name>SOAPMonitorService</display-name> <servlet-class> org.apache.axis.monitor.SOAPMonitorService </servlet-class> <init-param> <param-name>SOAPMonitorPort</param-name> <param-value>5001</param-value> </init-param> <load-on-startup>100</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/axis/servlet/AxisServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>SOAPMonitorService</servlet-name> <url-pattern>/SOAPMonitor</url-pattern> </servlet-mapping> <!-- uncomment this if you want the admin servlet --> <!-- <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/axis/servlet/AdminServlet</url-pattern> </servlet-mapping> --> <!-- currently the W3C havent settled on a media type for WSDL; http://www.w3.org/TR/2003/WD-wsdl12-20030303/#ietf-draft for now we go with the basic 'it's XML' response --> <mime-mapping> <extension>wsdl</extension> <mime-type>text/xml</mime-type> </mime-mapping> <mime-mapping> <extension>xsd</extension> <mime-type>text/xml</mime-type> </mime-mapping> <!-- Axis Web-Service Configuration End --> |
Apache Axis提供了WSDL2Java和Java2WSDL兩個(gè)開發(fā)工具。
WSDL2Java利用已知的WSDL文件生成服務(wù)端和客戶端代碼。該WSDL文件可以是由合作伙伴提供的,也可以是利用Java2WSDL生成的。Java2WSDL根據(jù)已有的Java類文件生成WSDL文件,Java類文件可以是接口類文件,并不需要實(shí)現(xiàn)細(xì)節(jié)。
此外Axis還提供了SoapMonitorApplet和TCPMon工具,可用于監(jiān)測(cè)Web服務(wù)。
2.7 如何生成Web服務(wù)的服務(wù)端和客戶端代碼
2.7.1 生成或取得WSDL文件
Java2WSDL是Axis提供的利用Java類文件得到WSDL文件的工具。類文件可以使用接口文件編譯生成,例如下面的接口文件SoftwarePrice.java。
package samples.userguide.example6; /** * Interface describing a web service to set and get software prices. **/ public interface SoftwarePrice { public void setWidgetPrice(String softWareName, String price); public String getWidgetPrice(String softWareName); |
編譯SoftwarePrice.java。
javac SoftwarePrice.java |
將SoftwarePrice.class復(fù)制到正確的package路徑下。
執(zhí)行下面的命令:
java org.apache.axis.wsdl.Java2WSDL -o sp.wsdl -l"http://test.com:80/services/SoftwarePrice" -n "urn:SoftwarePrice" -p"samples.userguide.example6" "urn:Example6" samples.userguide.example6.SoftwarePrice |
各參數(shù)的含義如下。
-o:指定輸出的WSDL文件的文件名。 |
最后面的類文件包含了Web服務(wù)的接口。
該命令執(zhí)行后,將生成sp.wsdl文件。
如果按CLASSPATH的設(shè)置找不到指定的類文件,Axis將報(bào)告異常,如下所示。
java.lang.ClassNotFoundException: samples.userguide.example6.SoftwarePrice at java.net.URLClassLoader$1.run(URLClassLoader.java:198) at java.security.AccessController.doPrivileged(Native Method) …… |
如果出現(xiàn)上面的問題,請(qǐng)檢查是否已將有關(guān)類文件復(fù)制到正確的位置或CLASSPATH設(shè)置是否正確。
生成WSDL文件以后,就可以利用Axis提供的WSDL2Java工具生成Web服務(wù)的服務(wù)端代碼和客戶端代碼了。
2.7.1.1 注意事項(xiàng)
WSDL文件也可以由合作伙伴提供。這種情況下合作伙伴往往是Web服務(wù)的提供者或標(biāo)準(zhǔn)接口的制定者,開發(fā)者只要按照既定的WSDL文件生成客戶端或服務(wù)端代碼就可以了。
2.7.2 生成客戶端或服務(wù)端代碼
WSDL2Java工具用于從WSDL文件生成客戶端存根(stub)代碼,服務(wù)端框架(skeleton)代碼以及WSDL中的數(shù)據(jù)類型文件(生成與之對(duì)應(yīng)的Java代碼)。開發(fā)人員只需向框架代碼中補(bǔ)充相關(guān)的業(yè)務(wù)邏輯代碼即可得到完整的Web服務(wù)代碼,因此該工具極大地減輕了開發(fā)人員的編碼負(fù)擔(dān)。WSDL2Java的使用舉例如下。
java org.apache.axis.wsdl.WSDL2Java --server-side --skeletonDeploy true MyService.wsdl |
執(zhí)行上述命令后將生成下列文件。
No. | 文件 | 用途 |
1. | deploy.wsdd | MyService服務(wù)的部署描述文件 |
2. | MyService.java | MyService服務(wù)的接口文件 |
3. | MyServiceService.java | 獲得MyService服務(wù)的接口文件 |
4. | MyServiceServiceLocator.java | 實(shí)現(xiàn)MyServiceService接口 |
5. | MyServiceSoapBindingImpl.java | 實(shí)現(xiàn)MyService接口,應(yīng)向其中補(bǔ)充業(yè)務(wù)邏輯 |
6. | MyServiceSoapBindingSkeleton.java | MyService服務(wù)的服務(wù)端框架代碼,實(shí)現(xiàn)MyService, org.apache.axis.wsdl.Skeleton接口 |
7. | MyServiceSoapBindingStub.java | MyService服務(wù)的客戶端存根代碼,實(shí)現(xiàn)MyService接口 |
8. | undeploy.wsdd | 注銷MyService服務(wù)的部署描述文件 |
2.7.3 編寫Web服務(wù)客戶端代碼
Web服務(wù)的客戶端程序完成對(duì)Web服務(wù)的調(diào)用,其程序結(jié)構(gòu)如下。
import com.chinavnet.zx.service.v1_0.*;// WSDL2Java生成的package的名字空間; public class TestClient { public static void main (String[] args) throws Exception { com.chinavnet.zx.service.v1_0.SPInterfaceForVNetLocator locator = new SPInterfaceForVNetLocator();//獲得一個(gè)locator對(duì)象 locator.setMaintainSession(true); com.chinavnet.zx.service.v1_0.SPInterfaceForVNetSoap service = locator.getSPInterfaceForVNetSoap();//獲得服務(wù)對(duì)象 com.chinavnet.zx.service.v1_0.DetailLedgerFeedbackResult feedbackRes = null; //初始化Web服務(wù)中定義的數(shù)據(jù)類型 try { feedbackRes = service.generalLedgerFeedback();//調(diào)用Web服務(wù)的方法并取得返回值 System.out.println("FeedbackResult :"); if(feedbackRes != null) { System.out.println("SPID: " +feedbackRes.getSPID()); System.out.println("errorDesc: " +feedbackRes.getErrorDescription()); System.out.println("result: " +feedbackRes.getResult()); }else { System.out.println("feedbackRes is null!"); } } catch (java.rmi.RemoteException re) { // throw new junit.framework.AssertionFailedError("Remote Exception caught: " + re ); re.printStackTrace(); } }//End of main() }//End of TestClient class |
測(cè)試客戶端程序是非常簡(jiǎn)單的,將客戶端程序編譯后,執(zhí)行"java TestClient"即可。
向MyServiceSoapBindingImpl.java添加相關(guān)的業(yè)務(wù)邏輯代碼后,將WSDL2Java生成的源程序編譯,打包成jar文件,復(fù)制到/usr/local/apache/htdocs/WEB-INF/lib/目錄下。
有了deploy.wsdd文件并準(zhǔn)備好類文件后,就可以發(fā)布MyService服務(wù)了。Axis在安裝后自動(dòng)發(fā)布了AdminService,利用它可以發(fā)布新的Web服務(wù)。方法如下。
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd 上面的命令執(zhí)行后,有如下提示。 Processing file deploy.wsdd <Admin>Done processing</Admin> |
2.10 執(zhí)行WSDL2Java時(shí)報(bào)告" 類型被引用但未定義"
2.10.1 問題描述
執(zhí)行WSDL2Java時(shí)報(bào)告下面的異常:
java.io.IOException: Type {http://schemas.xmlsoap.org/wsdl/} ArrayOfFailedRecord is referenced but not defined. |
2.10.2 原因分析
出現(xiàn)上述情況可能的原因有:
類型未定義就被引用。
使用了錯(cuò)誤的名字空間。
WSDL文件中存在輸入錯(cuò)誤。
2.10.3 解決方法
經(jīng)過仔細(xì)檢查發(fā)現(xiàn)wsdl文件中的
<s:element minOccurs="0" maxOccurs="1" name="FailedRecords" type="s0:ArrayOfFailedRecord" /> |
的type=" s0:ArrayOfFailedRecord"中的s0:前面有一個(gè)空格,將空格刪除后問題解決了。
2.10.4 小結(jié)
WSDL文件中出現(xiàn)的編輯錯(cuò)誤有可能導(dǎo)致執(zhí)行WSDL2Java時(shí)出現(xiàn)"類型被引用但未定義"錯(cuò)誤。
server-config.wsdd記錄了axis已發(fā)布的Web服務(wù)的描述信息。
2.12 發(fā)布Web服務(wù)時(shí)報(bào)告"Exception:: (404)Not Found"
2.12.1 問題描述
執(zhí)行java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd命令發(fā)布WEB服務(wù)時(shí)報(bào)告如下內(nèi)容。 Processing file deploy.wsdd Exception:: (404)Not Found |
Apache的access_log顯示如下。
127.0.0.1 - - [17/Sep/2003:15:56:33 +0800] "POST /services/AdminService HTTP/1.0" 404 293 |
2.12.2 原因分析
出現(xiàn)這個(gè)問題的比較簡(jiǎn)單的原因可能是端口不對(duì),或URL路徑不對(duì)(例如路徑中多寫了目錄),Axis的SoapMonitor服務(wù)按指定的端口或URL找不到AdminService,需要檢查正確的端口號(hào)和URL路徑。
比較深層次的原因就復(fù)雜得多了。
本文作者遇到的是下面的情況。
AdminService是一個(gè)已發(fā)布的WEB服務(wù)。
AdminClient使用soap協(xié)議同AdminService通信,需要按指定的端口和URL定位AdminService,而原來使用的resin.conf中,有兩個(gè)web-app配置項(xiàng),配置A的摘要如下所示。
<host id=' '> <app-dir>/usr/local/apache/htdocs/</app-dir> |
配置B的摘要如下所示。
<host id='test.com'> <app-dir>/usr/local/apache/htdocs/esales/</app-dir> |
Axis的有關(guān)配置在配置B中。
Httpd.conf中的DocumentRoot是/usr/local/apache/htdocs/。
使用java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd發(fā)布WEB服務(wù)時(shí),需要按http協(xié)議解析url: //localhost:80/services/AdminService。由于htdocs/目錄下并沒有services/目錄(services是Axis在resin.conf中的servlet-mapping),因此應(yīng)用服務(wù)器按resin.conf中的配置去定位AdminService ,因?yàn)閡rl的主機(jī)名為localhost,因此resin不會(huì)到<host id='test.com'>(配置B)中去定位url,而是到配置A中去定位,在配置A中并沒有Axis的配置,找不到與AdminService相關(guān)的url,因此報(bào)告了前面描述的異常情況。
2.12.3 解決方法
知道了原因后,按如下方法就可以解決了。
將配置B中全部關(guān)于Axis的配置移到配置A中,注意相應(yīng)地要改變/etc/profile中的CLASSPATH變量的值。
保存resin.conf后,重新登錄服務(wù)器(使新的CLASSPATH生效),重新啟動(dòng)resin。再次發(fā)布WEB服務(wù)。
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd |
屏幕顯示如下。
Processing file deploy.wsdd <Admin>Done processing</Admin> |
WEB服務(wù)終于發(fā)布成功了。
在發(fā)布成功的情況下apache的access_log中會(huì)看到如下的log:
tail -f access_log|grep vice 127.0.0.1 - - [17/Sep/2003:16:05:00 +0800] "POST /services/AdminService HTTP/1.0" 200 296 "-" "Axis/1.1" |
2.12.4 小結(jié)
本小節(jié)描述的問題可能是讀者遇到的出現(xiàn)最多的異常,但原因并不是唯一的。遇到該問題時(shí),建議讀者冷靜分析出現(xiàn)問題的可能原因,多實(shí)驗(yàn)幾種解決方法,最終一定可以成功!
2.13 如何監(jiān)測(cè)SOAP請(qǐng)求和響應(yīng)流
2.13.1 引言
發(fā)布了Web服務(wù)以后,如何觀察請(qǐng)求和響應(yīng)數(shù)據(jù)呢?記錄運(yùn)行日志是一種傳統(tǒng)且有效的方法,但對(duì)于調(diào)試程序來講還不夠方便和直觀。值得欣慰的是,Axis為我們提供了在客戶端觀察SOAP請(qǐng)求和響應(yīng)流數(shù)據(jù)的工具SoapMonitor,經(jīng)過適當(dāng)配置后,可以實(shí)時(shí)地觀察到Web服務(wù)的SOAP請(qǐng)求和響應(yīng)數(shù)據(jù)。SoapMonitor是一個(gè)Java Applet程序,通過瀏覽器下載到客戶端運(yùn)行。下面就介紹SoapMonitor的配置和使用方法。
2.13.2 準(zhǔn)備SOAPMonitor 小應(yīng)用程序
在Axis 1.1中,沒有為我們編譯SOAPMonitor.java程序,但我們可以在axis-1_1/webapps/axis/目錄下找到名字為SOAPMonitorApplet.java的源程序文件,自己進(jìn)行編譯。該程序編譯后,會(huì)生成如下的類文件:
SOAPMonitorApplet.class SOAPMonitorApplet$ServiceFilterPanel.class SOAPMonitorApplet$SOAPMonitorData.class SOAPMonitorApplet$SOAPMonitorFilter.class SOAPMonitorApplet$SOAPMonitorPage.class SOAPMonitorApplet$SOAPMonitorTableModel.class SOAPMonitorApplet$SOAPMonitorTextArea.class |
讀者需要把上述類文件復(fù)制到自己的Web應(yīng)用程序目錄下,本例中是/usr/local/apache/htdocs/目錄。
在瀏覽器地址樣中輸入SOAPMonitor的地址,例如 http://test.com/SOAPMonitor ,瀏覽器會(huì)提示用戶正在下載Applet程序,下載完畢后,讀者可以在瀏覽器窗口中看到如圖4-1所示的用戶界面。如果上述類文件的位置不正確,瀏覽器會(huì)報(bào)告"找不到類"的錯(cuò)誤。此時(shí)應(yīng)檢查是否已將上述類文件復(fù)制到正確的目錄下。

圖 2-1 SOAPMonitor的界面
2.13.3 發(fā)布SOAPMonitor服務(wù)
圖2-1所示的SOAPMonitor界面出現(xiàn)后,并不意味著就可以觀察到Web服務(wù)的SOAP請(qǐng)求流與響應(yīng)流了,首先需要發(fā)布SOAPMonitorService。該Web服務(wù)是由Axis提供的,但需要由用戶自己進(jìn)行發(fā)布,方法如下。
獲得SOAPMonitor服務(wù)的WSDD文件deploy.wsdd,內(nèi)容如下(也可到 http://www.sosnoski.com/presents/java-xml/axis/axis-monitor.html 復(fù)制該文件):
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <handler name="soapmonitor" type="java:org.apache.axis.handlers.SOAPMonitorHandler"> <parameter name="wsdlURL" value="/axis/SOAPMonitorService-impl.wsdl"/> <parameter name="namespace" value="http://tempuri.org/wsdl/2001/12/SOAPMonitorService-impl.wsdl"/> <parameter name="serviceName" value="SOAPMonitorService"/> <parameter name="portName" value="Demo"/> </handler> <service name="SOAPMonitorService" provider="java:RPC"> <parameter name="allowedMethods" value="publishMessage"/> <parameter name="className" value="org.apache.axis.monitor.SOAPMonitorService"/> <parameter name="scope" value="Application"/> </service> </deployment> |
發(fā)布SOAPMonitor服務(wù):
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd |
2.13.4 修改deploy.wsdd
發(fā)布SOAPMonitor服務(wù)后,還要對(duì)被監(jiān)測(cè)的Web服務(wù)進(jìn)行配置。方法是先注銷該Web服務(wù),然后修改該服務(wù)對(duì)應(yīng)的WSDD文件,在其中增加請(qǐng)求流和響應(yīng)流的配置,否則是觀測(cè)不到SOAP請(qǐng)求和響應(yīng)流的。
注銷Web服務(wù)的方法如下。
進(jìn)入該Web服務(wù)的undeploy.wsdd文件所在的目錄,執(zhí)行
Java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService undeploy.wsdd |
修改WSDD文件的方法如下。
以Axis提供的MyService為例,對(duì)MyService的WSDD文件做如下修改。
修改前:
... <service name="MyService" provider="java:RPC"> <parameter name="className" value="samples.userguide.example3.MyService"/> <parameter name="allowedMethods" value="*"/> ... |
修改后: (有下劃線的行是新加入的內(nèi)容)
... <service name="MyService" provider="java:RPC"> <requestFlow> <handler type="soapmonitor"/> </requestFlow> <responseFlow> <handler type="soapmonitor"/> </responseFlow> <parameter name="className" value="samples.userguide.example3.MyService"/> <parameter name="allowedMethods" value="*"/> ... |
修改WSDD文件后,重新發(fā)布MyService服務(wù):
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd |
2.13.5 啟動(dòng)SOAPMonitor小應(yīng)用程序
按2.13.2節(jié)介紹的方法啟動(dòng)SOAPMonitor小應(yīng)用程序。
使用客戶端程序測(cè)試MyService服務(wù):
# java samples.userguide.example3.Client -lhttp://vnet.sohu.com/services/MyService "test" 結(jié)果為:You typed : test |
注意,一定要先啟動(dòng)SOAPMonitor小應(yīng)用程序,后調(diào)用Web服務(wù)才能觀察到SOAP請(qǐng)求和響應(yīng)流。
2.13.6 觀察SOAP請(qǐng)求和響應(yīng)流
這時(shí)在SoapMonitorApplet的窗口中可以觀察到SOAP和請(qǐng)求和響應(yīng)消息,如圖2-2所示。

圖2-2 MyService的Soap請(qǐng)求和響應(yīng)流
2.14 使用客戶端程序測(cè)試Web服務(wù)時(shí)報(bào)告"Exception:: (404)Not Found"
2.14.1 問題描述
WEB服務(wù)接口編寫完成并發(fā)布后,客戶端測(cè)試程序收不到WEB服務(wù)的返回結(jié)果,Apache或Resin的log中也看不到訪問記錄。但測(cè)試程序返回結(jié)果為0(成功),在沒有部署該WEB服務(wù)的情況下,也是這個(gè)結(jié)果,因此懷疑調(diào)用的是WSDL文件的提供者自己測(cè)試用的WEB服務(wù)接口,可能與另一方提供的WSDL文件有關(guān)。
2.14.2 原因分析
合作伙伴調(diào)用WEB服務(wù)就能夠成功,從WEB服務(wù)主機(jī)自己的客戶端調(diào)用就接收不到數(shù)據(jù),估計(jì)與合作伙伴提供的WSDL文件有關(guān),該WSDL文件影響了WSDL2Java生成的客戶端stub代碼。檢查stub代碼,發(fā)現(xiàn)其soapAction都指向了合作伙伴的測(cè)試地址。
2.14.3 解決方法
修改stub代碼中的soapAction,改為sp(Service Provider)自己的WEB服務(wù)URL。重新編譯程序并發(fā)布Web服務(wù),問題解決。
_call.setSOAPActionURI("sp自己的Web服務(wù)地址");
2.14.4 小結(jié)
本小節(jié)描述的問題出現(xiàn)于Web服務(wù)提供方按合作伙伴統(tǒng)一提供的WSDL文件生成客戶端代碼的情況。遇到這類問題,讀者可直接檢查WSDL2Java自動(dòng)生成的代碼的有關(guān)部分。
在WSDL文件中可以看到與下列內(nèi)容相似的設(shè)置。
<wsdl:service name="SPInterfaceForVNet"> <wsdl:port binding="impl:SPInterfaceSoapSoapBinding" name="SPInterfaceForVNetSoap"> <wsdlsoap:address location="http://test.com/services/SPInterfaceSoap" /> </wsdl:port> </wsdl:service> |
其中 http://test.com/services/SPInterfaceSoap即為已發(fā)布的WEB服務(wù)的URL,供客戶端調(diào)用。
使用下面的命令:
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/ list |
實(shí)際上該命令的輸出就是server-config.wsdd文件的內(nèi)容。
2.16 發(fā)布Web服務(wù)時(shí)報(bào)告"調(diào)用目標(biāo)異常"
2.16.1 問題描述
在部署WEB服務(wù)時(shí)報(bào)告:java.lang.reflect.InvocationTargetException異常。
2.16.2 原因分析
在WSDL文件中自定義的名字空間與Axis的services名字空間沖突。
2.16.3 解決方法
修改WSDL文件,將services改為別的名字。
2.17 WSDL文件中的targetNamespace的作用是什么
TargetNamespace指明目標(biāo)名字空間,用于驗(yàn)證xml文檔。
在WSDL文件中,<definitions>中的targetNamespace與<types>中的targetNamespace應(yīng)保持一致。
2.19 客戶端程序找不到可用的Web服務(wù)
2.19.1 問題描述
執(zhí)行 java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd |
時(shí)顯示<Admin>Done processing</Admin>,卻檢查不到新的服務(wù),在WEB-INF/目錄下的server-config.wsdd文件中也看不到相應(yīng)的配置項(xiàng)。
2.19.2 原因分析
新的WEB服務(wù)的類文件沒有重新編譯并復(fù)制到正確的位置。
2.19.3 解決方法
WEB服務(wù)的類文件可以打包為jar文件。在CLASSPATH環(huán)境變量中正確設(shè)置jar文件的路徑。例如:
jar cvf SPInterfaceSoap.jar com/zx/service/v1_0/*.class |
將SPInterfaceSoap.jar復(fù)制到WEB-INF/lib/目錄下,重新發(fā)布WEB服務(wù)。
有時(shí),在對(duì)WEB服務(wù)執(zhí)行客戶端測(cè)試時(shí)會(huì)出現(xiàn)慕名其妙的錯(cuò)誤。為保證環(huán)境是正確的,可以按下面的步驟排除原因不明的錯(cuò)誤。
1. Undeploy被測(cè)試的服務(wù)
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService undeploy.wsdd |
2. 重新啟動(dòng)resin: /usr/local/resin/bin/httpd.sh restart(如果是其它的應(yīng)用服務(wù)器,請(qǐng)按相應(yīng)的方法重新啟動(dòng))
3. 重新發(fā)布WEB服務(wù)
4. 進(jìn)行測(cè)試
![]() ![]() |
![]()
|
目前有很多可以使用的應(yīng)用服務(wù)器和Web服務(wù)平臺(tái)軟件,本文僅以Apache Axis和Resin為例介紹了在部署Web服務(wù)的過程中可能遇到的問題及其解決方法,其中并未討論Web服務(wù)的安全性問題。對(duì)于如何高效地開發(fā)和部署Web服務(wù)以及如何確保Web服務(wù)的安全性,還希望對(duì)此感興趣的讀者共同參與討論,對(duì)于文中存在的錯(cuò)誤和不足之處也希望讀者朋友們能夠不吝批評(píng)指正。
- http://xml.apache.org/xerces2-j/index.html
- http://xml.apache.org/xalan-j/index.html
- http://ws.apache.org/axis/
- http://www.w3.org/TR/SOAP/
- http://www.w3c.org/TR/wsdl.html
- http://www.caucho.com/
![]() |
||
|
![]() |
姓名:劉紅濤 |
posted on 2007-06-21 16:02 狼愛上貍 閱讀(842) 評(píng)論(0) 編輯 收藏 所屬分類: AXIS