根
據(jù)網(wǎng)上搜索到的一些例子做的時(shí)候碰到了挺多的問(wèn)題,經(jīng)過(guò)不懈的努力終于完成了這個(gè)webservice的例子,實(shí)際上axis的文檔上也寫(xiě)了一個(gè)例子,網(wǎng)
上的例子也大多都是照他上面所寫(xiě)的那樣,只是有些講的不算很詳細(xì),所以產(chǎn)生了不少錯(cuò)誤,小弟知識(shí)淺薄,如有寫(xiě)的不清楚地地方,還請(qǐng)見(jiàn)諒
所需軟件
tomcat :http://tomcat.apache.org/index.html
axis :http://ws.apache.org/axis/
jdk :http://java.sun.com/javase/downloads/index.jsp
jaf :http://java.sun.com/products/javabeans/jaf/downloads/index.html
xmlrpc :http://ws.apache.org/xmlrpc
XML解析器
Xalan :http://archive.apache.org/dist/xml/xalan-j/
Xerces :http://xml.apache.org/dist/xerces-j/
本例講解axis定制發(fā)布
本實(shí)例采用
j2sdk1.4.2_05,tomcat5.0.28,axis1.4,jbuilder X / Eclipse3.2
首先將axis解壓至相應(yīng)目錄,如d:\下,安裝tomcat至c:\tomcat5,安裝jdk至c:\ j2sdk1.4.2_05
然后將d:\axis\webapp目錄下的axis目錄copy至c:\tomcat5\webapps目錄下
設(shè)置axis的環(huán)境變量
AXIS_HOME=d:\axis
AXIS_LIB=%AXIS_HOME%\lib
AXISCLASSPATH=%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\activation.jar;%AXIS_LIB%\xmlrpc-2.0.jar
(xml-apis.jar, xercesImpl.jar屬于Xerces或Xalan, activation.jar屬于jaf, xmlrpc-2.0.jar屬于xmlrpc)
1. 配置完成后啟動(dòng)tomcat,在瀏覽器中鍵入http://localhost:8080/axis,將顯示如下畫(huà)面

2.在C:\Tomcat5\webapps\axis\WEB-INF目錄下建立一個(gè)src目錄,用于存放源程序
接著編寫(xiě)服務(wù)端程序server.AxisReturn
package server;
public class AxisReturn {
public String ReturnMsg(String servicesName) {
return "Axis Return: "+ servicesName;
}
}
★在
此我們利用了Jbuilder X作為我們java程序的開(kāi)發(fā)工具,利用Jbuilder新建工程中的Project for Existing
Code將C:\Tomcat5\webapps\axis\WEB-INF下的程序及目錄導(dǎo)入作為Jbuilder的一個(gè)工程來(lái)操作

編譯AxisReturn程序,Jbuilder將會(huì)把編譯后的class文件自存放在C:\Tomcat5\webapps\axis\WEB-INF\classes\server目錄下
3.編寫(xiě)wsdd文件,此處命名為deploy.wsdd,其內(nèi)容為
<deployment xmlns=http://xml.apache.org/axis/wsdd/
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="AxisReturn" provider="java:RPC">
<parameter name="className" value="server.AxisReturn"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
★每個(gè)service就代表服務(wù)端的一個(gè)程序,如有多個(gè)可繼續(xù)添加service,相關(guān)參數(shù)請(qǐng)查閱axis文檔
★此處的deployment代表發(fā)布服務(wù),如改為undeployment則為撤銷服務(wù)
4.發(fā)布服務(wù)
打開(kāi)windows的命令窗口,轉(zhuǎn)到wsdd文件的存放目錄下,此處為C:\Tomcat5\webapps\axis\WEB-INF\src\server
在命令窗口中鍵入
java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd
如果成功將顯示<Admin>Done processing</Admin>
★如失敗,則檢查AXISCLASSPATH是否設(shè)置正確,tomcat端口是否為默認(rèn)的8080
★在這里有一個(gè)問(wèn)題需注意,不管是在axis目錄下還是其他虛擬目錄下,如直接執(zhí)行這條命令,都將在axis的目錄下發(fā)布service,如果想發(fā)布在其他的目錄下,如pscsaxis,則應(yīng)執(zhí)行
java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient -lhttp://localhost:8080/pscsaxis/services/AdminService deploy.wsdd
-cp表示在AXISCLASSPATH環(huán)境變量中檢索org.apache.axis.client.AdminClient方法
5.生成client stub文件
★在命令窗口中將目錄轉(zhuǎn)至C:\Tomcat5\webapps\axis\WEB-INF\classes
然后執(zhí)行
java
-cp %AXISCLASSPATH% org.apache.axis.wsdl.Java2WSDL -oAxisReturn.wsdl
-lhttp://localhost:8080/axis/services/AxisReturn -nAxisReturn
server.AxisReturn
將會(huì)在C:\Tomcat5\webapps\pscsaxis\WEB-INF\classes下生成AxisReturn.wsdl文件
接著在執(zhí)行
java -cp %AXISCLASSPATH% org.apache.axis.wsdl.WSDL2Java AxisReturn.wsdl -p client
將會(huì)在C:\Tomcat5\webapps\axis\WEB-INF\classes\client目錄下生成四個(gè)java文件
AxisReturn_PortType.java
AxisReturnService.java
AxisReturnServiceLocator.java
AxisReturnSoapBindingStub.java
將這四個(gè)文件剪切至C:\Tomcat5\webapps\pscsaxis\WEB-INF\src\client目錄下,并編譯
6.編寫(xiě)客戶端
利用生成client stub文件編寫(xiě)
package client;
public class ClientAxisReturn {
public static void main(String args[]) {
try {
AxisReturnService service = new client.AxisReturnServiceLocator();
client.AxisReturn_PortType client = service.getAxisReturn();
String retValue = client.returnMsg("BaoSteel");
System.out.println(retValue);
}
catch (Exception e) {
System.err.println("Execution failed. Exception: " + e);
}
}
}
編寫(xiě)完后,編譯運(yùn)行即可得到返回結(jié)果
★如需傳入多個(gè)參數(shù),需在String retValue = client.returnMsg("BaoSteel");這句中增加參數(shù),如
String retValue = client.returnMsg("BaoSteel","PSCS_IMS");
★相應(yīng)的服務(wù)端也要更改,如
package server;
public class AxisReturn {
public String ReturnMsg(String servicesName,String serviceID) {
return "Axis Return: "+ servicesName+ serviceID;
}
}
利用發(fā)布服務(wù)的wsdl的URL編寫(xiě)
package client;
import org.apache.axis.AxisFault;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.encoding.XMLType;
public class ClientAxisReturnWsdl {
public static void main(String args[]) throws Exception{
String endPoint =
http://190.2.63.239:8080/pscsaxis/services/AxisReturn?wsdl;
Service service = new Service();
Call call = (Call) service.createCall();
Object result;
try {
call.setTargetEndpointAddress(new java.net.URL(endPoint));
call.setOperationName("ReturnMsg");
call.addParameter("OP1", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING);
result = (Object) call.invoke(new Object[] {"BaoSteel"});
}
catch (AxisFault fault) {
result = "Error is: " + fault.toString();
}
System.out.println(result);
}
}
編寫(xiě)完后,編譯運(yùn)行即可得到返回結(jié)果
★如許增加參數(shù),則需添加語(yǔ)句
call.addParameter("OP1", XMLType.XSD_STRING, ParameterMode.IN);
將參數(shù)名OP1改為其他,如OP2
在result = (Object) call.invoke(new Object[] {" BaoSteel "});這句中增加參數(shù),如
result = (Object) call.invoke(new Object[] {" BaoSteel "," PSCS_IMS "});
★相應(yīng)的服務(wù)端也要更改,如
package server;
public class AxisReturn {
public String ReturnMsg(String servicesName,String serviceID) {
return "Axis Return: "+ servicesName+ serviceID;
}
}
★在這里,我們的服務(wù)端只有一個(gè)方法供我們調(diào)用,如果我們需要調(diào)用多個(gè)服務(wù)端的方法,則可在服務(wù)端中加入其他方法,如我們?cè)谠黾右粋€(gè)xxMsg
package server;
public class AxisReturn {
public String ReturnMsg(String servicesName,String systemID) {
return "Axis Return: "+ str+servicesName+systemID;
}
public String xxMsg(String serviceName,String systemID) {
return "XX Return: "+ str+serviceName+systemID;
}
}
★修改完后將其編譯,并將其注銷后重新發(fā)布,反之需要重起tomcat,否則服務(wù)將不被更新
★利用生成client stub文件編寫(xiě)的客戶端程序,還需重新生成client stub文件,并將其編譯,在客戶端程序中調(diào)用其相應(yīng)得方法即可
SOAPMonitor的配置
發(fā)
布了Web服務(wù)以后,如何觀察請(qǐng)求和響應(yīng)數(shù)據(jù)呢?記錄運(yùn)行日志是一種傳統(tǒng)且有效的方法,但對(duì)于調(diào)試程序來(lái)講還不夠方便和直觀。值得欣慰的是,Axis為我
們提供了在客戶端觀察SOAP請(qǐng)求和響應(yīng)流數(shù)據(jù)的工具SoapMonitor,經(jīng)過(guò)適當(dāng)配置后,可以實(shí)時(shí)地觀察到Web服務(wù)的SOAP請(qǐng)求和響應(yīng)數(shù)據(jù)。
SoapMonitor是一個(gè)Java Applet程序,通過(guò)瀏覽器下載到客戶端運(yùn)行。下面就介紹SoapMonitor的配置和使用方法。
在C:\Tomcat5\webapps\axis的目錄下有一個(gè)SOAPMonitorApplet.java的程序,axis默認(rèn)沒(méi)有給我們編譯,我們需要自己進(jìn)行編譯
打開(kāi)windows命令窗口,轉(zhuǎn)到C:\Tomcat5\webapps\axis目錄下,執(zhí)行
javac -classpath %AXIS_HOME%\lib\axis.jar SOAPMonitorApplet.java
編譯完成后需要發(fā)布服務(wù),我們需要建立一個(gè)wsdd文件deploy-monitor.wsdd,內(nèi)容如下
<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>
★需要注意的是紅色的那句語(yǔ)句,如果是在我們自己的web應(yīng)用目錄下的話需改成自己的目錄。
建立完成后執(zhí)行命令進(jìn)行發(fā)布
java
-cp %AXISCLASSPATH% org.apache.axis.client.AdminClient
-lhttp://localhost:8080/axis/services/AdminService deploy-monitor.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)流的。以我們上面的程序?yàn)槔瑢eploy.wsdd修改為
<deployment xmlns=http://xml.apache.org/axis/wsdd/
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="AxisReturn" provider="java:RPC">
<requestFlow>
<handler type="soapmonitor"/>
</requestFlow>
<responseFlow>
<handler type="soapmonitor"/>
</responseFlow>
<parameter name="className" value="server.AxisReturn"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
增加了
<requestFlow>
<handler type="soapmonitor"/>
</requestFlow>
<responseFlow>
<handler type="soapmonitor"/>
</responseFlow>
這兩段
然后我們通過(guò)點(diǎn)擊http://localhost:8080/axis/主頁(yè)上的SOAPMonitor或直接訪問(wèn)http://localhost:8080/axis/SOAPMonitor,點(diǎn)擊start或stop啟動(dòng)或停止監(jiān)控,然后我們運(yùn)行客戶端程序,SOAPMonitor會(huì)監(jiān)控到請(qǐng)求和響應(yīng)流,如下圖

★在
這里,我們需要注意一個(gè)配置問(wèn)題,如果tomcat下有多個(gè)axis應(yīng)用,設(shè)置了多個(gè)SOAPmonitor,我們則需要更改SOAPmonitor的端
口(axis默認(rèn)配置的是5001),否則會(huì)產(chǎn)生沖突,運(yùn)行SOAPmonitor時(shí)會(huì)無(wú)法啟動(dòng),提示the soap monitor is
unable to communcate with the server,解決方法如下:
打開(kāi)C:\Tomcat5\webapps\axis\WEB-INF目錄下的web.xml,找到
<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>
這段,將其中的5001改成5002,依此類推
總結(jié):
盡量將發(fā)布websrrvice的文件夾和axis分開(kāi)放置
建立多個(gè)axis應(yīng)用時(shí),應(yīng)注意一些端口的設(shè)置,命令的參數(shù)設(shè)置以及一些命令執(zhí)行的路徑設(shè)置等,否則會(huì)產(chǎn)生一些錯(cuò)誤,如ClassNotFound,service發(fā)布錯(cuò)誤等的錯(cuò)誤
server-config.wsdd
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns:java="
xmlns:handler="
xmlns="
xmlns:xsi="
name="defaultClientConfig" xsi:type="deployment">
<globalConfiguration>
<parameter name="disablePrettyXML" value="true"/>
<parameter name="dotNetSoapEncFix" value="true"/>
<parameter name="enableNamespacePrefixOptimization" value="false"/>
<requestFlow>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="session"/>
</handler>
<handler type="java:org.apache.axis.handlers.JWSHandler">
<parameter name="scope" value="request"/>
<parameter name="extension" value=".jwr"/>
</handler>
</requestFlow>
</globalConfiguration>
<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
<handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
<handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
<service name="CallcenterWebServices" provider="java:RPC" style="rpc" use="encoded">
<parameter name="scope" value="Request"/>
<parameter name="className" value="com.isw2.ebay.callcenter.axis.CallcenterWebServices"/>
<parameter name="allowedMethods"
value="getStatus,getCsrBean,setStatus,createCase,showContactRecord,getWorkload"/>
<beanMapping qname="myNS:CsrBean" xmlns:myNS="urn:CsrBean"
languageSpecificType="java:com.isw2.ebay.callcenter.axis.CsrBean" />
<beanMapping qname="myNS:ContactRecordBean" xmlns:myNS="urn:ContactRecordBean"
languageSpecificType="java:com.isw2.ebay.callcenter.axis.ContactRecordBean" />
<beanMapping qname="myNS:DisputeContactRecord" xmlns:myNS="urn:DisputeContactRecord"
languageSpecificType="java:com.isw2.ebay.callcenter.axis.DisputeContactRecord" />
<beanMapping qname="myNS:WorkloadNumberBean" xmlns:myNS="urn:WorkloadNumberBean"
languageSpecificType="java:com.isw2.ebay.callcenter.axis.WorkloadNumberBean" />
</service>
<service name="AdminService" provider="java:MSG">
<parameter name="allowedMethods" value="AdminService"/>
<parameter name="enableRemoteAdmin" value="false"/>
<parameter name="className" value="org.apache.axis.utils.Admin"/>
<namespace>http://xml.apache.org/axis/wsdd/</namespace>
</service>
<service name="Version" provider="java:RPC">
<parameter name="allowedMethods" value="getVersion"/>
<parameter name="className" value="org.apache.axis.Version"/>
</service>
<transport name="http">
<parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
<parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
<parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
<requestFlow>
<handler type="URLMapper"/>
<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
</requestFlow>
</transport>
<transport name="local">
<responseFlow>
<handler type="LocalResponder"/>
</responseFlow>
</transport>
</deployment>