??xml version="1.0" encoding="utf-8" standalone="yes"?>
~少的jar文g请加在classpath中,注意查,classpath文g前面不要有空根{?br>
~少axis.jar
javax.xml.rpc.ServiceException: java.lang.ClassNotFoundException: org.apache.axis.client.ServiceFactory
at javax.xml.rpc.ServiceFactory.newInstance(ServiceFactory.java:69)
at com.company.project.remote.WebServiceClient.main(WebServiceClient.java:24)
~少saaj.jar
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/soap/SOAPException
at org.apache.axis.configuration.FileProvider.configureEngine(FileProvider.java:179)
at org.apache.axis.AxisEngine.init(AxisEngine.java:172)
at org.apache.axis.AxisEngine.
at org.apache.axis.client.AxisClient.
at org.apache.axis.client.Service.getAxisClient(Service.java:104)
at org.apache.axis.client.Service.
at org.apache.axis.client.ServiceFactory.createService(ServiceFactory.java:198)
at com.company.project.remote.WebServiceClient.main(WebServiceClient.java:26)
~少wsdl4j.jar
Exception in thread "main" java.lang.NoClassDefFoundError: javax/wsdl/extensions/mime/MIMEContent
at org.apache.axis.wsdl.gen.Parser.run(Parser.java:297)
at org.apache.axis.client.Service.initService(Service.java:243)
at org.apache.axis.client.Service.
at org.apache.axis.client.ServiceFactory.createService(ServiceFactory.java:198)
at com.company.project.remote.WebServiceClient.main(WebServiceClient.java:26)
错误的URL
javax.xml.rpc.ServiceException: Error processing WSDL document:
java.net.UnknownHostException: www.xmethods.com
at org.apache.axis.client.Service.initService(Service.java:250)
at org.apache.axis.client.Service.
at org.apache.axis.client.ServiceFactory.createService(ServiceFactory.java:198)
at com.company.project.remote.WebServiceClient.main(WebServiceClient.java:26)
~少用户名、密?br>javax.xml.rpc.ServiceException: Error processing WSDL document:
java.net.ProtocolException: Server redirected too many times (20)
at org.apache.axis.client.Service.initService(Service.java:250)
at org.apache.axis.client.Service.
at org.apache.axis.client.ServiceFactory.createService(ServiceFactory.java:198)
at com.company.project.remote.WebServiceClient.main(WebServiceClient.java:26)
对于webService 以前也接触过.但只是皮?q次可是来真格的.来就来吧,q轻是Z.一定得把握?q它一? ?在|上到处找找?在本地机器上左试?双试啊, 什么法子都用一遍。就不信搞不定它Q小P
|上的例子也比较散,比较易的Q达不我惌的业务水qI只能慢慢搜烦与摸索吧。。。。。。就q样天天想着q事Q也没什么心情来q里写写?/p>
q些天,也快回深圳了Q定在下周四动n吧。这边的工作也得告一节了。把我前一些日子,搞一个完整的Samples 攑ֈq里来,与大家共享。希望对有心人有些启发,也希望高人指点与点评。。。。。。。?/p>
****************************************************
*Axis开发Webservice传Bean对象q回String串的实例.rtf*
****************************************************
在ECLIPSE 里新Z工程Q其ơ徏包,再次建类Q?br>基本包:samples.userguide.example5
基本c: Order.java
内容Q?br> * Order.java *
*?*******************************
package samples.userguide.example5;
/**
* This is a JavaBean which represents an order for some products.
* Copyright: Copyright (c) 2007-1
* @author Black skin (blackskin@126.com)
* @version 1.0
*/
public class Order {
/** Who's ordering */
private String customerName;
/** Where do they live */
private String shippingAddress;
/** Which items do we want */
private String itemCodes[];
/** And how many */
private int quantities[];
// Bean accessors
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String name) {
customerName = name;
}
public String getShippingAddress() {
return shippingAddress;
}
public void setShippingAddress(String address) {
shippingAddress = address;
}
public String[] getItemCodes() {
return itemCodes;
}
public void setItemCodes(String[] items) {
itemCodes = items;
}
public int[] getQuantities() {
return quantities;
}
public void setQuantities(int[] quants) {
quantities = quants;
}
}
********************************?
L务包: samples.userguide.example5
L务类: BeanService.java
如下Q?br> * BeanService.java *
**?******************************
package samples.userguide.example5;
/**
* This is a JavaBean which represents an order for some products.
* Copyright: Copyright (c) 2007-1
* @author Black skin (blackskin@126.com)
* @version 1.0
*/
public class BeanService {
public String processOrder(Order order) {
String sep = System.getProperty("line.separator");
String response = "Hi, " + order.getCustomerName() + "!" + sep;
response += sep + "You seem to have ordered the following:" + sep;
String[] items = order.getItemCodes();
int[] quantities = order.getQuantities();
for (int i = 0; i < items.length; i++) {
response += sep + quantities[i] + " of item : " + items[i];
}
response += sep + sep + "If this had been a real order processing system, "
+ sep + "we'd probably have charged you about now.";
return response;
}
public static void main(String[] args) throws Exception{
/** Who's ordering */
String customerName = "Black Skin";
/** Where do they live */
String shippingAddress = "001 xingan Street, bayuquan, YK";
/** Which items do we want */
String[] items = new String[] { "apple", "160ml-Milk" };
/** And how many */
int[] quantities = new int[] { 2, 4 };
/** request class init() */
Order order = new Order();
order.setCustomerName(customerName);
order.setShippingAddress(shippingAddress);
order.setItemCodes(items);
order.setQuantities(quantities);
/** server class init() */
BeanService beanservice = new BeanService();
String result = beanservice.processOrder(order);
/** OutPut the result */
System.out.println(" " + result);
}
}
********************************?
BeanService.java里有个本地测试方?samples.userguide.example5.BeanService.main())Q来试此应用的可运行性;
到此Q服务端cd完了Q接着来把此类的方法发布成 WebService 接口
手写一个deploy.wsdd 文gQ可以参考下面的例子Q?br> *deploy.wsdd例子*
*?*******************************
<?xml version="1.0" encoding="utf-8"?>
<deployment xmlns="<parameter name="className" value="服务cL件的实际路径Q包括包的信息)"/>
<parameter name="allowedMethods" value="*Q即为所有方法都可访问,如要指定多个可用I格分隔开Q?/>
<parameter name="allowedRoles" value="user"/>
<parameter name="scope" value="Session"/>
<requestFlow>
<handler type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
</requestFlow>
</service>
</deployment>
********************************?
昄Q简单,造一个deploy.wsdd 信手捏来,如下Q?br> *deploy.wsdd*
*?*******************************
<deployment xmlns=" <parameter name="className" value="samples.userguide.example5.BeanService"/>
<parameter name="allowedMethods" value="processOrder"/>
<beanMapping qname="myNS:Order" xmlns:myNS="urn:BeanService" languageSpecificType="java:samples.userguide.example5.Order"/>
</service>
</deployment>
********************************?
有了deploy.wsdd文g了,接着通过它来生成 server-config.wsdd.
OK! 用命令直接生成就行;在deploy.wsdd 的文件夹下新Z?makeWsdd.bat.
其中的写法有下面的例子来参考:
* makeWsdd.bat 例子*
*?*******************************
set AXISCLASSPATH= “应用发布的\?#8221;
set AXIS_LIB= “AXIS框架的内部JAR包LIB路径”
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;
%AXIS_LIB%\saaj.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar
java -Djava.ext.dirs=%AXISCLASSPATH% org.apache.axis.client.AdminClient
-S服务名\services\AdminService -p端口P如果你的端口号不是默认的8080需要指定?br> 例如Q?899Qdeploy.wsdd
********************************?
如此Q我写了一“makeWsdd.bat”文g。如下:
* makeWsdd.bat*
*?*******************************
set AXISCLASSPATH=C:\Axis_webservice\Tomcat_4.1\webapps\axis
set AXIS_LIB=C:\axis-1_4\lib
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;
%AXIS_LIB%\saaj.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar
java -Djava.ext.dirs=%AXISCLASSPATH% org.apache.axis.client.AdminClient
-SBeanServer\services\AdminService -p 8080 deploy.wsdd
********************************?
保存好,接下来架设Webservice.
环境架设Q?br>首先Q安装JDK...Q略Q?..本例用JDK版本号V1.4.
其次Q安装Tomcat...Q略Q?..本例用Tomcat版本号V4.1.
再次QAXIS...Q略Q?..本例用AXIS版本号V1.4. 去AXIS官方|站Q?a >http://www.apache.org下蝲AXISQ解压后得,
|- axis-1_4
|- docs
|- ..Q略Q?..
|- lib
|- axis.jar
|- axis-ant.jar
|- commons-discovery-0.2.jar
|- commons-logging-1.0.4.jar
|- jaxrpc.jar
|- log4j-1.2.8.jar
|- log4j.properties
|- saaj.jar
|- wsdlj-1.5.1.jar
|- samples
|- ..Q略Q?..
|- webapps
|- axis
|- ..Q略Q?..
|- xmls
|- ..Q略Q?..
解压后QC:\axis-1_4\webapps 目录下的 axis 目录 Copy ?tomcat/webapps目录QC:\Axis_webservice\Tomcat_4_1\webappsQ下Q?/p>
架设AXISQ?br>首先Q将deploy.wsdd文gCopy?%AXISCLASSPATH%/WEB-INF 目录下;
其次Q将之前的类~译后,q\径一起Copy?%AXISCLASSPATH%/WEB-INF/classes目录下,
最后,tomcat?catalina 服务启动.
Q即QC:\Axis_webservice\Tomcat_4.1\bin,
[特别注意的是Q]
Q。tomcat务必启动?br> Q。在写如上的命o行时Q务必注意参数的写法?#8220;-D” ?“-S”与其值间不能有空根{切讎ͼ
C。各XX的\径里Q最好是不要有空|因ؓJAVA里对大小写与路径I格有校验?br>Q)
试Q?br>命o行启动方法;q行"cmd",在命令行里写Q?cd C:\Axis_webservice\Tomcat_4.1\bin",回RQ再写:" catalina run ",回RQOKQ?br>后台会报错:
"
- Unable to find config file. Creating new servlet engine config file: /WEB-INF/server-config.wsdd
2007-1-20 10:07:48 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on port 8080
"
说明Q在../WEB-INF/下没?server-config.wsdd",暂时忽略?br>在IE地址栏写Q?a href="http://localhost:8080/axis">http://localhost:8080/axis
可见Qaxis Ƣ迎首页Q点?"list" 便可看到默认情况下发布了两个服务下各有一个方法。一切准备工作已lOKQ?/p>
再回刎ͼ刚才我们写的那个批处理文Ӟ" makeWsdd.bat"Q?br>直接双击Q便可执行, 有一个警告,可以忽略的。执行完成后Q在相应?br>%AXISCLASSPATH%/WEB-INF下便有一“server-config.wsdd”文gQ如下:
*server-config.wsdd*
*?*******************************
********************************?
再去打开Q?http://localhost:8080/axis/servlet/AxisServlet",或者,再刷新?br>便可以看刎ͼ我们新发布的一个webservice接口服务Q其名ؓQ?OrderProcessor "
此服务下的个ҎQ其名ؓQ?processOrder "?/p>
点击服务对应?QWSDLQ?可见服务WSDL描述内容。在其中也可以得服务的访问地址Q?br>"http://localhost:8080/axis/services/OrderProcessor?wsdl"
服务器端的开发,搞定了!
-:) -:) -:)
接下来,准备开发,客户端的开发?/p>
* Client.java *
*?*******************************
package samples.userguide.example5;
/**
* This is a JavaBean which represents an order for some products.
* Copyright: Copyright (c) 2007-1
* @author Black skin (blackskin@126.com)
* @version 1.0
*/
import java.net.URL;
import org.apache.axis.AxisFault;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.utils.Options;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
public class Client {
public static void main(String[] args) throws Exception {
//Options options = new Options(args);
String urlWsdl = "http://localhost:8080/axis/services/OrderProcessor?wsdl";
Order order = new Order();
order.setCustomerName("Black Skin");
order.setShippingAddress("275 Grove Street, Newton, MA");
String[] items = new String[] { "apple", "160ml-Milk" };
int[] quantities = new int[] { 8, 4 };
order.setItemCodes(items);
order.setQuantities(quantities);
Service service = new Service();
Call call = (Call) service.createCall();
QName qn = new QName("urn:BeanService", "Order");
call.registerTypeMapping(Order.class, qn,
new org.apache.axis.encoding.ser.BeanSerializerFactory(
Order.class, qn),
new org.apache.axis.encoding.ser.BeanDeserializerFactory(
Order.class, qn));
String result;
try {
//call.setTargetEndpointAddress(new java.net.URL(options.getURL()));
call.setTargetEndpointAddress(new java.net.URL(urlWsdl));
call.setOperationName(new QName("OrderProcessor", "processOrder"));
call.addParameter("arg1", qn, ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);
result = (String) call.invoke(new Object[] { order });
} catch (AxisFault fault) {
result = "Error : " + fault.toString();
}
System.out.println(result);
}
}
********************************?
oK! 到此Q一个完整的Webservice例子搞定了?/p>
另外QAxis q提供了一些工P?" wsdl2java "? java2wsdl "
处理的方式与ҎQ?br> java2wsdl:
1. 以上ZQ在以上工程的class输出目录新徏一BAT文gQ名为:“java2wsdl.bat”
2. 其内容ؓQ?br> * java2wsdl.bat *
*?*******************************
set AXIS_LIB=C:\axis-1_4\lib
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar
java org.apache.axis.wsdl.Java2WSDL -o Order.wsdl -l"http://localhost:8080/axis/services/OrderProcessor" -n "urn:BeanService" -p"samples.userguide.example5.Order" "urn:Order" samples.userguide.example5.BeanService
********************************?
把AXIS_LIB设ؓ正确的本地包路径Q再q行“java2wsdl.bat”Q?br>便可以在目录下看C个文Ӟ“Order.wsdl”Q通过q个WSDL文gQ可以生成Webservice接口服务的框Ӟ
既可以是服务器端Q也可以是客L框架。其l节Q可以参考下一节?/p>
处理的方式与ҎQ?br> wsdl2java :
1. 以上ZQ把Order.wsdl拯q来Q在其目录下新徏一BAT文gQ名为:“wsdl2java.bat”
2. 其内容ؓQ?br> * wsdl2java.bat *
*?*******************************
set AXIS_LIB=C:\axis-1_4\lib
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar
java org.apache.axis.wsdl.WSDL2Java Order.wsdl
********************************?
或者有另外的作法:把服务端的应用启动,直接写成Q?br>“
java org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/services/OrderProcessor?wsdl
”
保存好后Q运行这个BAT文gQ?br>便会自动生成:
BeanService_pkg\
BeanService.java
BeanServiceService.java
BeanServiceServiceLocator.java
OrderProcessorSoapBindingStub.java
Order.java
ok.
2.下蝲 apache-ant-1.6.1 解压攑֜D:\softSetup\?bitsCN全力打造网学习^?/font>
3.环境变量讄:
JAVA_HOME=C:\jdk1.5.0_06
CATALINA_HOME=tomcat-5.5.15
ANT_HOME=D:\softSetup\apache-ant-1.6.1
AXISCLASSPATH=%AXIS_LIB%\activation.jar;%AXIS_LIB%\mail.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB% \wsdl4j.jar;%AXIS_LIB%\axis-ant.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%\xerces.jar;%AXIS_LIB%\junit.jar;%AXIS_LIB%\wsdl4j-1.5.1.jar
AXIS_HOME=D:\softSetup\axis-1_2_1
AXIS_LIB=%AXIS_HOME%\lib
CATALINA_HOME=D:\softSetup\jakarta-tomcat-5.0.24
classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%AXISCLASSPATH%
path=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;%CATALINA_HOME%\bin;%ANT_HOME%\bin so.bitsCN.com|管资料库Q你搜
4.在命令行 q行set 保新加的环境变量生?
bitsCN.com中国|管联盟
5.Ҏ合作伙伴l的wsdl地址 http://www.****.com/services/OrderService?wsdl保存下来到D:\project\test\wsdl\OrderService.wsdl 需要什么来搜一搜吧so.bitsCN.com
6.在命令行 切换?D:\project\test\wsdl\下运行axis的WSDL2Java 命o: java org.apache.axis.wsdl.WSDL2Java OrderService.wsdl 生成 bean 文g,***Service.java,***ServiceLocator.java,***ServiceSoapBindingStub.java {文?可以用Axis的wsdl2java生成web service的客LQwsdl2java生成的客L是stub方式的。它包括endpoint借口、实现该接口的stub?serviceLocator、可选的单元试代码。其中,serviceLocator中hard code了服务端地址.
so.bitsCN.com|管资料库Q你搜
7. 应用.写一个表单jsp,提交C面jsp文gq行处理(可以写在c里,此处单处? play.bitsCN.com累了吗玩一下吧
<%@ page contentType="text/html; charset=GBK"%>
<%@page import="org.apache.axis.client.Call"%>
<%@page import="javax.xml.namespace.QName"%>
<%@page import="java.net.MalformedURLException"%>
<%@page import="java.rmi.RemoteException"%>
<%@page import="java.util.*"%>
<%@page import="java.net.URL"%>
<%@page import="org.apache.axis.client.Service"%>
<%@page import="com.newSky.datainterface.beans.*"%>
<%!
dl.bitsCN.com|管软g下蝲
private final static String success = "试完成";
private final static String fail = "试p|:";
final static String endPoint = "http://www.***.com/services/OrderService";
final static String portName = "addNewOrder";
final static String nameSpace = "http://beans.datainterface.newSky.com";
%>
<html>
<head></head>
<body>
<%
try {
Call call = null;
URL url = null;
try {
//create new url
url = new URL(endPoint);
}
catch (MalformedURLException e) {
System.out.println(fail + e.getMessage());
e.printStackTrace();
}
//create new service
Service service = new Service();
try {
//create new call 需要什么来搜一搜吧so.bitsCN.com
call = (Call) service.createCall();
}
catch (Exception se) {
System.out.println(fail + se.getMessage());
se.printStackTrace();
}
//讄服务?br> call.setTargetEndpointAddress(url);
//讄端口
call.setOperationName(new QName(endPoint, portName));
//***********************
//注册c,开?br> try {
QName qn1 = new QName(nameSpace, "OrderUserData");
call.registerTypeMapping(OrderUserData.class, qn1,
new org.apache.axis.encoding.ser.BeanSerializerFactory(OrderUserData.class, qn1),
so.bitsCN.com|管资料库Q你搜
bbs.bitsCN.com国内最早的|管论坛
if(result.equals("-100")){
out.write("用户名密码错?);
}
else{
out.write("成功");
}
System.out.println("************* 试完成 ******************");
}
catch (RemoteException re) {
System.out.println(fail + re.getMessage());
//re.printStackTrace();
}
}
catch (Exception e) {
// e.printStackTrace();
}
%>
</body>
</html>
bitsCN全力打造网学习^?/p>
8. ok ^_^ bitsCN全力
来自:http://www.bitscn.com/java/webservice/200611/82110.html
Axis?/font>
Axis是Apachel织推出的SOAP引擎QAxis目是Apachel织著名的SOAP目的后l项目,目前最新版本是采用Java开发的1.1版本QC++的版本正在开发之中。Axis v1.1软g包可以从http://ws.apache.org/axis/dist/1_1/下蝲得到?/p>
Axis的安?/strong> Axis的配|?/strong> CATALINA_HOME Q此处应为Tomcat的安装位|,注意路径名中不要有空| 如果你不愿做q么J琐的类路径讄Q可以直接将axis软g包中“lib”目录下的所?jar文g加入到系l环境变量CLASSPATH中即可?/p>
Axis的测?/strong> 启动Tomcat服务?/u>Q在览器中讉Khttp://localhost:8080/axis/happyaxis.jspQ如果页面显C有错误Q则需要回头检查一下相关配|是否正,如果览面能正显C出pȝlg、属性等参数配置信息Q则表示安装成功Q如下图所C: 使用x发布 使用x发布首先需要一个实现服务功能的Java源文Ӟ其扩展名改?jwsQJava Web Service的羃写)Q然后将该文件放?#8220;……\webapps\axis”目录下即可?/p>
在此l出一个从英里到公里的长度单位转换的服务,其源码如下: 文gDistance.jws * @author 飞鹰 */ public class Distance { public double convertMile2Kilometre( double mile ) { //实现英里到公里的距离转换 return mile * 1.609; }//convertMile2Kilometre() }/* Distance */ 其攑ֈ“……\webapps\axis”目录Q通过讉Khttp://localhost:8080/axis/Distance.jws?wsdl可以看到q个服务的WSDL描述文gQ这说明Distance服务被成功发布了。如下图所C: 因此QAxis提供了另一U服务发布方式,q就是定制发布?/p>
在此l出一个从加仑到升的容U单位{换的服务Q其源码如下Q?/p>
文gCapacity.java /** * @author 飞鹰 */ public class Capacity { public double convertGallon2Litre( double gallon ) { //实现加仑到升的容U{?/p>
return gallon * 4.546; }//convertGallon2Litre() }/* Capacity */ 其~译?class文gQ放|到“……\webapps\axis\samples\capacity”目录下,卛_着手进行发布?/p>
定制发布不需要构?jws文gQ但必须创徏服务发布描述文gdeploy.wsddQWeb Service Deployment Descriptor的羃写)Q这个文件负责描q服务的名称、入口等信息Q其内容如下Q?/p>
文gdeploy.wsdd xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="Capacity" provider="java:RPC"> <parameter name="className" value="samples.capacity.Capacity"/> <parameter name="allowedMethods" value="*"/> </service> </deployment> 该文g也放?#8220;……\webapps\axis\samples\capacity”目录下,然后可以采用Axis提供的一个客L理工具——AdminClient来完成服务的定制发布?/p>
?#8220;……\webapps\axis\samples\capacity”目录下,q行Q?/p>
java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd 可以看到以下q行l果Q?/p>
Processing file deploy.wsdd <Admin>Doneprocessing</Admin> q表明Capacity服务定制发布完成?/p>
通过讉Khttp://localhost:8080/axis/services/Capacity?wsdl可以看到q个服务的WSDL描述文gQ这说明Capacity服务被成功发布了。如下图所C: 文gHelloWorld.jws * @author 飞鹰 */ public class HelloWorld { public String helloWorld() { //?a target=_blank>服务?/u>端打印输?/p>
System.out.println( "Hello World!" ); //q回相应字符?/p>
return "Hello World!"; }//helloWorld() }/* HelloWorld */ q个服务l出一个名?#8220;helloWorld”的无入口参数的操作,q回一个内容ؓ“Hello WorldQ的字符?#8221;Q同时在服务?/u>端打?#8220;Hello WorldQ?#8221;Q将该文件放?#8220;……\webapps\axis”目录下,卛_通过GETҎ直接讉K该服务,讉K的地址为http://localhost:8080/axis/HelloWorld.jws?method=helloWorldQ可以看到返回的SOAP信封消息Q同?a target=_blank>服务?/u>端给Z相应的显CZ?#8220;Hello WorldQ?#8221;q表明HelloWorld服务被成功访问了。如下图所C: 其中Qorg.apache.axis.client.Call和org.apache.axis.client.Service是两个比较常用的c,一般的客户端程序欲讉K一个Web ServiceӞ都要生成一个客L的Service对象和Call对象Q在讉K服务之前Q首先要对Call对象讄相应的参敎ͼ包括服务的位|、操作名、入口参数、返回值类型等Q最后调用Call对象的invokeҎ讉K服务?/p>
以下l出了一个客L讉KWeb服务的例E——AXISTest.javaQ?/p>
文gAXISTest.java import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import javax.xml.rpc.ParameterMode; /** * @author 飞鹰 */ public class AXISTest { public static void main( String[] args ) throws Exception { Service service = new Service(); Call call = ( Call ) service.createCall(); //////////讉Kx发布的Distance服务 //讄讉K?/p>
call.setTargetEndpointAddress( "http://localhost:8080/axis/Distance.jws" ); //讄操作?/p>
call.setOperationName( "convertMile2Kilometre" ); //讄入口参数 call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN ); call.setReturnType( XMLType.XSD_DOUBLE ); Double d1 = new Double( 190 ); //调用服务 System.out.println( d1 + " 英里相当?" + call.invoke( new Object[] {d1} ) + " 公里Q? ); //////////讉K定制发布的Capacity服务 call = ( Call ) service.createCall(); //讄讉K?/p>
call.setTargetEndpointAddress( "http://localhost:8080/axis/services/Capacity" ); //讄操作?/p>
call.setOperationName( "convertGallon2Litre" ); //讄入口参数 call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN ); call.setReturnType( XMLType.XSD_DOUBLE ); d1 = new Double( 10.00 ); //调用服务 System.out.println( d1 + " 加仑相当?" + call.invoke( new Object[] {d1} ) + " 升!" ); } //main() }/* AXISTest */ ~译q行后运行可以看C下的l果Q?/p>
190.0英里相当?05.71公里Q?/p>
10.0加仑相当?5.46升! GET方式的服务访?/p>
一般的SOAP消息都是采用POST方式实现传递,但也可以通过GET方式来访问。比如以下给出的一个服务—?#8220;HelloWorld”Q其源码如下Q? 文gHelloWorld.jws q个服务l出一个名?#8220;helloWorld”的无入口参数的操作,q回一个内容ؓ“Hello WorldQ的字符?#8221;Q同时在服务器端打印“Hello WorldQ?#8221;Q将该文件放?#8220;……\webapps\axis”目录下,卛_通过GETҎ直接讉K该服务,讉K的地址?a href="http://localhost:8080/axis/HelloWorld.jws?method=helloWorld">http://localhost:8080/axis/HelloWorld.jws?method=helloWorldQ可以看到返回的SOAP信封消息Q同时服务器端给Z相应的显CZ?#8220;Hello WorldQ?#8221;q表明HelloWorld服务被成功访问了Q生成的SOAP信封消息为: Axis提供了一套API来实现SOAPQ从http://localhost:8080/axis/docs/apiDocs/index.html可以看到Axis的API文档?/p>
其中Qorg.apache.axis.client.Call和org.apache.axis.client.Service是两个比较常用的c,一般的客户端程序欲讉K一个Web ServiceӞ都要生成一个客L的Service对象和Call对象Q在讉K服务之前Q首先要对Call对象讄相应的参敎ͼ包括服务的位|、操作名、入口参数、返回值类型等Q最后调用Call对象的invokeҎ讉K服务?/p>
以下l出了一个客L讉KWeb服务的例E——AXISTest.javaQ?/p>
文gAXISTest.java package axisexercise; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import javax.xml.rpc.ParameterMode; public class AXISTest Service service = new Service(); //讄讉K?br> call.setTargetEndpointAddress( "http://localhost:8080/axis/Distance.jws" ); //讄操作?br> call.setOperationName( "convertMile2Kilometre" ); //讄入口参数 //讄q回参数cd //调用服务Q在invokeҎ中传入的是包含调用参数的数组 //////////讉K定制发布的Capacity服务 //讄讉K?br> call.setTargetEndpointAddress( "http://localhost:8080/axis/services/Capacity" ); //讄操作?br> call.setOperationName( "convertGallon2Litre" ); //讄入口参数 //调用服务 } //main() }/* AXISTest */ ~译q行后运行可以看C下的l果Q?/p>
190.0英里相当?05.71公里Q?/p>
10.0加仑相当?5.46升! 1. RPC服务Q?br>PRC服务是AXIS中的默认服务Q当你通过<service ... provider="java:RPC"> or <service ... style="RPC">标签q行部v的时候,使用的就是RPC服务。RPC服务遵@SOAP RPC和其~码规范。AXIS可以XML反序列化成java对象Qƈ其传给服务的方法。ƈ且可以将服务的方法返回的JAVA对象序列化成XML?/p>
2.Document / Wrapped services Document和Wrapped服务都不使用SOAP~码数据Q这一Ҏ他们怼的地斏V他们仅仅用旧的XML模式。然而,在这两种服务中,AXIS捆lJava的表C到XML文档中,所以你最l处理的是java对象而不直接处理XML?/p>
下面是包含定单的一个简单的SOAP消息Q你可以看到Document ?Wrapped 服务的区别所在: 相应的XML模式如下Q?/p>
<schema targetNamespace="http://commerce.com/PO"> 对于Documentcd服务Q他映成下面的方法: 我们来看下面q段客户端程序的SOAP信封Q?br>(1) 客户端程序: (2) SOAP信封Q?br><?xml version="1.0" encoding="UTF-8"?> 2. 参数命名Q?br>在上面的代码中,AXIS自动在Soap消息中的函数调用参数命名为arg0,arg1{等Q如果你x照自己定义的参数名调用方法的话,很简单,在你调用invoke函数之前只要调用addParameter()函数卛_。如下所C: call.addParameter("testParam", 3. q回cd 所以也有这样一个相似的ҎQ允怽指定所期望q回的Java的类?br>call.setReturnClass(String.class); 作者用的软g环境如下? 操作pȝQRed Hat Linux 7.2 Web服务? Apache 1.3.27 应用服务器:Resin 2.1.8 ( http://www.caucho.com/ ) SOAP服务器:Apache Axis 1.1 XML解析器:Xerces 2.5.0QXalan 2.5.1 JDK版本QJDK 1.4.1
2.1 Axisq行需要哪些jar文g 对Axis解包后,axis-1_1/webapps/axis/WEB-INF/lib/目录下的jar文g复制?usr/local/apache/htdocs/WEB-INF/lib目录?Web应用E序的目?。应包括以下jar文g? 如果需要用axis提供的测试页面,q要axis-1_1/webapps/axis/目录下的文g复制?usr/local/apache/htdocs/axis/目录下。应包括以下募?
XML解析器选用不当Q经怼D使用Apache Axis时出C些莫名其妙的问题? ׃Apache Axis q未对Resin内置的xml解析器进行过试Q因此推荐读者用已通过试的Xerces xml解析器。可以从 http://xml.apache.org/xalan-j/index.html 处下载Xalan的Java版XSLT处理器,其中包含了Xerces的Java版XML解析器,不需要再单独下蝲xml解析器? Xalan 2.5.1解包后,bin/目录下的xercesImpl.jar、xml-apis.jar和xalan.jar复制到resin安装目录的lib/目录下,例如/usr/local/resin/lib? ~辑/etc/目录下的profile文gQ找到设|CLASSPATH环境变量的位|,在其后加入下面的内容(B shell)? 2.2.1 注意事项 2.3 如何在Resin中用Xerces的XML解析?/font>
通过修改resin.confresin的XmlParser|换为Xerces的XmlParser。在resin.conf对应的Web应用E序配置中加入以下设|? 配置完成后重新启动Resin?/p>
2.4.1 问题描述 使用http://test.com/axis查看已部|的服务时出现Axis内部错,昄有关WSDD配置的异怿息。如果把WEB-INF目录下的server-config.wsdd删除Q再查看正怺Q但只能看到AdminService和Version两个pȝ~省的服务,后来部v的服务都看不C? 2.4.2 原因分析 Axis会在WEB应用E序的WEB-INF/目录下自动生成一个名字ؓserver-config.wsdd的xml文gQ其中记录了已部|的WEB服务。每部v一个新的WEB服务ӞAxis都会新服务的描qC息加入到server-config.wsdd中? 故障站点使用的XmlParser是resin内置的XmlParserQAxisq未对其对进行过兼容性测试,查看WEB服务信息旉要从server-config.wsdd(q是一个xml文g)取得已部|的WEB服务描述信息Q当server-config.wsdd的内容较复杂Ӟresin内置的XmlParser因某U原因出现异常,DAxis内部错误。Server-config.wsdd中记录的Web服务描述信息较少时不会出现异常? 2.4.3 解决Ҏ 修改resin.confQ将resin的XmlParser|换为Xerces的XmlParser。置换方法参?.3节?/p>
2.4.4 结 如果Axis报告的错误中有关于xml解析器的错误Q徏议读者参照本节描述的方法更换应用服务器的xml解析器,会有助于问题的解决?
Axis是以Servlet的方式运行的Q而Resin的作用相当于Servlets容器(Container)Q因此只要配|得当,可以Axis在Resin环境中运行,q一点也适用于Resin以外的其它应用服务器。在Resin中配|Axis的方法如下? axis-1_1/webapps/axis/WEB-INF/web.xml中的Servlet配置复制到resin.conf中对应的Web应用E序配置中。通常应包括以下内宏V?
Apache Axis提供了WSDL2Java和Java2WSDL两个开发工兗? WSDL2Java利用已知的WSDL文g生成服务端和客户端代码。该WSDL文g可以是由合作伙伴提供的,也可以是利用Java2WSDL生成的。Java2WSDLҎ已有的JavacL件生成WSDL文gQJavacL件可以是接口cLӞq不需要实现细节? 此外Axisq提供了SoapMonitorApplet和TCPMon工具Q可用于监测Web服务?
2.7.1 生成或取得WSDL文g Java2WSDL是Axis提供的利用JavacL件得到WSDL文g的工兗类文g可以使用接口文g~译生成Q例如下面的接口文gSoftwarePrice.java? ~译SoftwarePrice.java? SoftwarePrice.class复制到正的package路径下? 执行下面的命? 各参数的含义如下? 最后面的类文g包含了Web服务的接口? 该命令执行后Q将生成sp.wsdl文g? 如果按CLASSPATH的设|找不到指定的类文gQAxis报告异常,如下所C? 如果出现上面的问题,h查是否已有关类文g复制到正的位置或CLASSPATH讄是否正确? 生成WSDL文g以后Q就可以利用Axis提供的WSDL2Java工具生成Web服务的服务端代码和客L代码了? 2.7.1.1 注意事项 WSDL文g也可以由合作伙伴提供。这U情况下合作伙伴往往是Web服务的提供者或标准接口的制定者,开发者只要按照既定的WSDL文g生成客户端或服务端代码就可以了? 2.7.2 生成客户端或服务端代? WSDL2Java工具用于从WSDL文g生成客户端存根(stubQ代码,服务端框ӞskeletonQ代码以及WSDL中的数据cd文g(生成与之对应的Java代码)。开发h员只需向框架代码中补充相关的业务逻辑代码卛_得到完整的Web服务代码Q因此该工具极大地减M开发h员的~码负担。WSDL2Java的用D例如下? 执行上述命o后将生成下列文g?
2.7.3 ~写Web服务客户端代?/p>
Web服务的客LE序完成对Web服务的调用,其程序结构如下? 试客户端程序是非常单的Q将客户端程序编译后Q执?java TestClient"卛_?/p>
向MyServiceSoapBindingImpl.javad相关的业务逻辑代码后,WSDL2Java生成的源E序~译Q打包成jar文gQ复制到/usr/local/apache/htdocs/WEB-INF/lib/目录下?
有了deploy.wsdd文gq准备好cL件后Q就可以发布MyService服务了。Axis在安装后自动发布了AdminServiceQ利用它可以发布新的Web服务。方法如下?
2.10.1 问题描述 执行WSDL2Java时报告下面的异常Q?/p>
2.10.2 原因分析 出现上述情况可能的原因有Q?/p>
cd未定义就被引用?/p>
使用了错误的名字I间? WSDL文g中存在输入错误? 2.10.3 解决Ҏ l过仔细查发现wsdl文g中的 的type=" s0:ArrayOfFailedRecord"中的s0:前面有一个空|空格删除后问题解决了?/p>
2.10.4 结 WSDL文g中出现的~辑错误有可能导致执行WSDL2Java时出?cd被引用但未定?错误?/p>
2.11 server-config.wsdd的作用是什?/font>
server-config.wsdd记录了axis已发布的Web服务的描qC息?/p>
2.12 发布Web服务时报?Exception:: (404)Not Found" 2.12.1 问题描述 Apache的access_log昄如下?/p>
2.12.2 原因分析 出现q个问题的比较简单的原因可能是端口不对,或URL路径不对(例如路径中多写了目录)QAxis的SoapMonitor服务按指定的端口或URL找不到AdminServiceQ需要检查正的端口号和URL路径? 比较深层ơ的原因复杂得多了?/p>
本文作者遇到的是下面的情况? AdminService是一个已发布的WEB服务? AdminClient使用soap协议同AdminService通信Q需要按指定的端口和URL定位AdminServiceQ而原来用的resin.conf中,有两个web-app配置,配置A的摘要如下所C? 配置B的摘要如下所C?/p>
Axis的有关配|在配置B中?/p>
Httpd.conf中的DocumentRoot?usr/local/apache/htdocs/?/p>
使用java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd发布WEB服务Ӟ需要按http协议解析url: //localhost:80/services/AdminService。由于htdocs/目录下ƈ没有services/目录(services是Axis在resin.conf中的servlet-mapping)Q因此应用服务器按resin.conf中的配置d位AdminService Q因为url的主机名为localhostQ因此resin不会?lt;host id='test.com'>(配置B)中去定位urlQ而是到配|A中去定位Q在配置A中ƈ没有Axis的配|,找不CAdminService相关的urlQ因此报告了前面描述的异常情c? 2.12.3 解决Ҏ 知道了原因后Q按如下Ҏ可以解决了?/p>
配|B中全部关于Axis的配|移到配|A中,注意相应地要改变/etc/profile中的CLASSPATH变量的倹{? 保存resin.conf后,重新d服务?使新的CLASSPATH生效)Q重新启动resin。再ơ发布WEB服务? 屏幕昄如下?/p>
WEB服务l于发布成功了? 在发布成功的情况下apache的access_log中会看到如下的logQ? 2.12.4 结 本小节描q的问题可能是读者遇到的出现最多的异常Q但原因q不是唯一的。遇到该问题Ӟ读者冷静分析出现问题的可能原因Q多实验几种解决ҎQ最l一定可以成功!
2.13.1 引言 发布了Web服务以后Q如何观察请求和响应数据呢?记录q行日志是一U传l且有效的方法,但对于调试程序来讲还不够方便和直观。值得ƣ慰的是QAxis为我们提供了在客L观察SOAPh和响应流数据的工具SoapMonitorQ经q适当配置后,可以实时地观察到Web服务的SOAPh和响应数据。SoapMonitor是一个Java AppletE序Q通过览器下载到客户端运行。下面就介绍SoapMonitor的配|和使用Ҏ? 2.13.2 准备SOAPMonitor 应用程?/p>
在Axis 1.1中,没有为我们编译SOAPMonitor.javaE序Q但我们可以在axis-1_1/webapps/axis/目录下找到名字ؓSOAPMonitorApplet.java的源E序文gQ自p行编译。该E序~译后,会生成如下的cLӞ 读者需要把上述cL件复制到自己的Web应用E序目录下,本例中是/usr/local/apache/htdocs/目录? 在浏览器地址样中输入SOAPMonitor的地址Q例?http://test.com/SOAPMonitor Q浏览器会提C用h在下载AppletE序Q下载完毕后Q读者可以在览器窗口中看到如图4-1所C的用户界面。如果上q类文g的位|不正确Q浏览器会报?找不到类"的错误。此时应查是否已上q类文g复制到正的目录下? ?2-1 SOAPMonitor的界?/strong> 2.13.3 发布SOAPMonitor服务 ?-1所C的SOAPMonitor界面出现后,q不意味着可以观察到Web服务的SOAPh与响应了Q首先需要发布SOAPMonitorService。该Web服务是由Axis提供的,但需要由用户自己q行发布Q方法如下? 获得SOAPMonitor服务的WSDD文gdeploy.wsddQ内容如?也可?http://www.sosnoski.com/presents/java-xml/axis/axis-monitor.html 复制该文?Q? 发布SOAPMonitor服务Q?/p>
2.13.4 修改deploy.wsdd 发布SOAPMonitor服务后,q要对被监测的Web服务q行配置。方法是先注销该Web服务Q然后修改该服务对应的WSDD文gQ在其中增加h和响应的配置Q否则是观测不到SOAPh和响应流的? 注销Web服务的方法如下? q入该Web服务的undeploy.wsdd文g所在的目录Q执? 修改WSDD文g的方法如下? 以Axis提供的MyServiceZQ对MyService的WSDD文g做如下修攏V? 修改? 修改? (有下划线的行是新加入的内? 修改WSDD文g后,重新发布MyService服务Q?/p>
2.13.5 启动SOAPMonitor应用程?/p>
?.13.2节介l的Ҏ启动SOAPMonitor应用程序?/p>
使用客户端程序测试MyService服务Q? 注意Q一定要先启动SOAPMonitor应用程序,后调用Web服务才能观察到SOAPh和响应流?/p>
2.13.6 观察SOAPh和响应流 q时在SoapMonitorApplet的窗口中可以观察到SOAP和请求和响应消息Q如?-2所C? ?-2 MyService的Soaph和响应流 2.14 使用客户端程序测试Web服务时报?Exception:: (404)Not Found"
2.14.1 问题描述 WEB服务接口~写完成q发布后Q客L试E序收不到WEB服务的返回结果,Apache或Resin的log中也看不到访问记录。但试E序q回l果?(成功)Q在没有部v该WEB服务的情况下Q也是这个结果,因此怀疑调用的是WSDL文g的提供者自己测试用的WEB服务接口Q可能与另一Ҏ供的WSDL文g有关? 2.14.2 原因分析 合作伙伴调用WEB服务p够成功,从WEB服务L自己的客L调用接收不到数据,估计与合作伙伴提供的WSDL文g有关Q该WSDL文g影响了WSDL2Java生成的客Lstub代码。检查stub代码Q发现其soapAction都指向了合作伙伴的测试地址? 2.14.3 解决Ҏ 修改stub代码中的soapActionQ改为sp(Service Provider)自己的WEB服务URL。重新编译程序ƈ发布Web服务Q问题解冟? _call.setSOAPActionURI("sp自己的Web服务地址"); 2.14.4 结 本小节描q的问题出现于Web服务提供Ҏ合作伙伴l一提供的WSDL文g生成客户端代码的情况。遇到这c问题,读者可直接查WSDL2Java自动生成的代码的有关部分? 在WSDL文g中可以看C下列内容怼的设|?/p>
其中 http://test.com/services/SPInterfaceSoap即ؓ已发布的WEB服务的URLQ供客户端调用?
使用下面的命令: 实际上该命o的输出就是server-config.wsdd文g的内宏V?
2.16.1 问题描述 在部|WEB服务时报告:java.lang.reflect.InvocationTargetException异常? 2.16.2 原因分析 在WSDL文g中自定义的名字空间与Axis的services名字I间冲突? 2.16.3 解决Ҏ 修改WSDL文gQ将services改ؓ别的名字? 2.17 WSDL文g中的targetNamespace的作用是什?/font>
TargetNamespace指明目标名字I间Q用于验证xml文档? 在WSDL文g中,<definitions>中的targetNamespace?lt;types>中的targetNamespace应保持一致?
2.19 客户端程序找不到可用的Web服务 2.19.1 问题描述 时显C?lt;Admin>Done processing</Admin>Q却查不到新的服务,在WEB-INF/目录下的server-config.wsdd文g中也看不到相应的配置V? 2.19.2 原因分析 新的WEB服务的类文g没有重新~译q复制到正确的位|? 2.19.3 解决Ҏ WEB服务的类文g可以打包为jar文g。在CLASSPATH环境变量中正设|jar文g的\径。例如: SPInterfaceSoap.jar复制到WEB-INF/lib/目录下,重新发布WEB服务?
有时Q在对WEB服务执行客户端测试时会出现慕名其妙的错误。ؓ保证环境是正的Q可以按下面的步骤排除原因不明的错误? 1. Undeploy被测试的服务 2. 重新启动resin: /usr/local/resin/bin/httpd.sh restart(如果是其它的应用服务器,h相应的方法重新启? 3. 重新发布WEB服务 4. q行试 姓名Q刘U涛 SOAP是一个基于XML的用于应用程序之间通信数据~码的传输协议。最初由微Y和Userland Software提出Q随着不断地完善和改进QSOAP很快被业界广泛应用,目前完全发布版本?.1。在其发展过E中QW3C XML标准工作组U极促成SOAP成ؓ一个真正的开放标准。在写作此文档之ӞSOAP1.2草案已经发布Q?.2?.1中相Ҏq部分做了改进?br>SOAP被广泛作为新一代跨q_、跨语言分布计算Web Services的重要部分?/p>
Axis是Apachel织推出的SOAP引擎QAxis目是Apachel织著名的SOAP目的后l项目,目前最新版本是采用Java开发的1.1版本QC++的版本正在开发之中。Axis v1.1软g包可以从http://ws.apache.org/axis/dist/1_1/下蝲得到?br>但是Axis不仅仅是一个SOAP引擎Q它q包括: 应用Axis开发Web ServicesQ你需要安装如下YӞ 当安装好Tomcat之后Q只需下载的Axis软g包解压羃Q将其中?#8220;webapps”目录下的“axis”目录整个拯到Tomcat安装目录下的“webapps”目录下即可?/p>
三、Axis的配|?/p>
AxisZJava开发,可以部v于多U操作系l,使用前需要配|一pd的系l变量,在此假定你已l在本机上装好了Tomcat 4.0以上的版本,需要配|的pȝ变量如下表所C: CATALINA_HOME Q此处应为Tomcat的安装位|,注意路径名中不要有空| AXIS_HOME AXIS_LIB AXISCLASSPATH CLASSPATH 中加入: 四、Axis的测?/p>
安装配置完毕后,应测试一下是否Axis可以正确q行了?/p>
启动Tomcat服务器,在浏览器中访?a href="http://localhost:8080/axis/happyaxis.jsp">http://localhost:8080/axis/happyaxis.jspQ如果页面显C有错误Q则需要回头检查一下相关配|是否正,如果览面能正显C出pȝlg、属性等参数配置信息Q则表示安装成功。现在可以开始开发你的Web Services应用了?/p>
五、服务的发布 1. 使用x发布 Java Web Service(JWS) 对即时发布的支持是Axis的特色之一Q用即时发布用户只需有提供服务的Javacȝ源代码,卛_其q速发布成Web服务。每当用戯用这cL务的时候,Axis会自动进行编译,即服务器重启了也不必对其做M处理Q用非常简单快捗?/p>
使用x发布首先需要一个实现服务功能的Java源文Ӟ其扩展名改?jwsQJava Web Service的羃写)Q然后将该文件放?#8220;……\webapps\axis”目录下即可?br> 在此l出一个从英里到公里的长度单位转换的服务,其源码如下: 文gDistance.jws public class Distance 其攑ֈ“……\webapps\axis”目录Q通过讉Khttp://localhost:8080/axis/Distance.jws?wsdl可以看到q个服务的WSDL描述文gQ这说明Distance服务被成功发布了。描q的WDSL代码如下Q?br><?xml version="1.0" encoding="UTF-8" ?> 需要注意的是:JWS的web服务发布是一个很单的Web服务发布方式Q在面中你不能使用包,而且׃代码是在q行期被~译的,所以在部v之后Q你也很难找到错误所在?/p>
2. 使用定制发布 Web Service Deployment Descriptor(WSDD) x发布是一o人激动的技术,它Web服务的开发变得如此简单;然而即时发布ƈ不L最好的选择Q比如有些应用系l是W三Ҏ供的Q我们没有购买源代码Q只?class文gQ但我们又希望将q个应用pȝ的一些功能对外发布成Web服务Q其能够在更大范围内生作用,q个时候即时发布技术就无能为力了。此外,x发布技术ƈ不灵z,无法q行更多的服务配|,q得它q不能满一些特定系l的需求?/p>
因此QAxis提供了另一U服务发布方式,q就是定制发布?/p>
在此l出一个从加仑到升的容U单位{换的服务Q其源码如下Q?/p>
文gCapacity.java }/* Capacity */ <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> 在这里服务的提供者是“java:RPC”Q它被内建在Axis中,而且指明了一个JAVA RPC服务Q做q个处理的类是org.apache.axis.providers.java.RPCProvider?br> 我们是通过一?lt;parameter>标签告诉RPC服务应该调用的类Q而另外一?lt;parameter>标签则告诉引擎,它可以调用这个类中的M的PublicҎ。你也可以指定通过使用名字I间或者一些可以调用的Ҏ列表Q来指明那些Ҏ可以被调用?/p>
该文g也放?#8220;……\webapps\axis\samples\capacity”目录下,然后可以采用Axis提供的一个客L理工具——AdminClient来完成服务的定制发布?br> ?#8220;……\webapps\axis\samples\capacity”目录下,q行Q?/p>
java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd 如果q行时说没有扑ֈc,那么可能是类路径没有配置好,所有的与axis相关的jar都写到classpath中去。这样只要运? java org.apache.axis.client.AdminClient deploy.wsdd Processing file deploy.wsdd q表明Capacity服务定制发布完成?br> 你也可以调用Q?br> java org.apache.axis.client.AdminClient list 来获得所有的已经部v的服务的列表。在q里你会看到services, handlers, transports{等Q注意这个调用只是列ZWEB-INF\server-config.wsdd的文件内宏V?/p>
一定要注意Q编译后的class文g要拷贝到web-inf/classes的目录中Q如果该文g中有包存在的话,别忘了还要在classes目录下创建包的目?br> 通过讉Khttp://localhost:8080/axis/services/Capacity?wsdl可以看到q个服务的WSDL描述文gQ这说明Capacity服务被成功发布了?br> 你也可以通过讉Khttp://localhost:8080/axis/servlet/AxisServlet查看所有定制发布的服务?br> WDSL如下Q?br> <?xml version="1.0" encoding="UTF-8" ?> WSDD 的高U功能: W一D|明了一个名为track的handlerQ它是samples.userguide.example4.LogHandlercȝ实例。另外还指定了一个参数filenameQ用于指定日志文件名U?br> 下面的那D|明了一个RPC服务Q和我们在上面的例子中看到的一P所不同的是在service标签中的<requestFlow>标签Q它指定了一些在调用服务前应该被调用的handler集。也是׃我们在部|中插入了这?track"的引用,所以我们确定每ơ调用服务的时候都被记录到日志文件中厅R?br> Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=35550 一.首先下蝲安装软gQ?br>1.axis-src-1_2_1,(自己M?地址忘记? ?安装 ? 2.然后到axis-1_2_1目录?扑ֈlib文g?拯其中的activation.jar文g,?br>Tomcat\webapps\axis\WEB-INF\lib,和上面的8个jar文g在一POK了?br> .;%JAVA_HOME%\lib\dt.jar; ?试 javax/wsdl/OperationType 六调试AXIS import java.util.*; Service here"卌?Web Service 服务端程序安装完? import org.apache.axis.client.Call; "http://localhost:8080/axis/wsTestService.jws"; java.net.URL(strUri)); 一下,q里׃再描qC?br>C:\>cd \
应用Axis开发Web ServicesQ你需要有一个支持Servlet?a target=_blank>服务?/u>引擎Q比如广Zh知的TomcatQTomcat也是由Apachel织所提供的,目前的最新版本ؓ4.1.24Q?a target=_blank>下蝲地址为http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.1.24/Q。在此之前当然你机器必须已经装好了JDK1.3以上的版本,当安装好Tomcat之后Q只需?a target=_blank>下蝲的Axis软g包解压羃Q将其中?#8220;webapps”目录下的“axis”目录整个拯到Tomcat安装目录下的“webapps”目录下即可?/p>
AxisZJava开发,可以部v于多U?a target=_blank>操作pȝQ用前需要配|一pd的系l变量,在此假定你已l在本机上装好了Tomcat 4.0以上的版本,需要配|的pȝ变量如下表所C:
C:\Tomcat_4_1
AXIS_HOME
%CATALINA_HOME%\webapps\axis
AXIS_LIB
%AXIS_HOME%\lib
AXISCLASSPATH
%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging.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可以正确q行了?/p>
现在可以开始开发你的Web Services应用了?/p>
Axis提供了两U服务发布方式,一U是x发布QInstant DeploymentQ,一U是定制发布QCustom DeploymentQ?
对即时发布的支持是Axis的特色之一Q用即时发布用户只需有提供服务的Javacȝ源代码,卛_其q速发布成Web服务。每当用戯用这cL务的时候,Axis会自动进行编译,即服务?/u>重启了也不必对其做Q何处理,使用非常单快捗?/p>
/**
使用定制发布
x发布是一o人激动的技术,它Web服务的开发变得如此简单;然而即时发布ƈ不L最好的选择Q比如有些应用系l是W三Ҏ供的Q我们没有购买源代码Q只?class文gQ但我们又希望将q个应用pȝ的一些功能对外发布成Web服务Q其能够在更大范围内生作用,q个时候即时发布技术就无能为力了。此外,x发布技术ƈ不灵z,无法q行更多的服务配|,q得它q不能满一些特定系l的需求?/p>
package samples.capacity;
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
GET方式的服务访?/strong>
一般的SOAP消息都是采用POST方式实现传递,但也可以通过GET方式来访问。比如以下给出的一个服务—?#8220;HelloWorld”Q其源码如下Q?
/**
客户端服务访问编E?/strong>
Axis提供了一套API来实现SOAPQ从http://localhost:8080/axis/docs/apiDocs/index.html可以看到Axis的API文档?/p>
package axisexercise;
注意E序在访问即时发布的Distance服务和定制发布的Capacity服务时的不同Q前者的服务讉K点地址为http://localhost:8080/axis/HelloWorld.jwsQ而后者的则ؓhttp://localhost:8080/axis/services/Capacity?br>
来自Q?a >http://hi.baidu.com/zxhcloth/blog/item/bb8637dbf28e0b67d0164ea5.html
]]>
public class HelloWorld
{
public String helloWorld()
{
System.out.println( "Hello World!" );//在服务器端打印输?nbsp;
return "Hello World!";//q回相应字符?br> }
}
<?xml version="1.0" encoding="UTF-8" ?>
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
- <helloWorldResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<helloWorldReturn xsi:type="xsd:string">Hello World!</helloWorldReturn>
</helloWorldResponse>
</soapenv:Body>
</soapenv:Envelope>
七、客L服务讉K~程
{
public static void main( String[] args ) throws Exception
{
创徏service和call对象Q这些对象是标准的JAX-RPC对象Q这些对象用于存储服务调用的数据QmetadataQ?/p>
Call call = ( Call ) service.createCall();
//////////讉Kx发布的Distance服务
call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );
call.setReturnType( XMLType.XSD_DOUBLE );
Double d1 = new Double( 190 );
System.out.println( d1 + " 英里相当?" +
call.invoke( new Object[] {d1} ) + " 公里Q? );
call = ( Call ) service.createCall();
call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );
call.setReturnType( XMLType.XSD_DOUBLE );
d1 = new Double( 10.00 );
System.out.println( d1 + " 加仑相当?" +
call.invoke( new Object[] {d1} ) + " 升!" );
注意E序在访问即时发布的Distance服务和定制发布的Capacity服务时的不同Q前者的服务讉K点地址?a href="http://localhost:8080/axis/HelloWorld.jws">http://localhost:8080/axis/HelloWorld.jwsQ而后者的则ؓhttp://localhost:8080/axis/services/Capacity?/p>
八、服务类型:RPC, Document, Wrapped, and Message
在Axis中,有四U服务类型:
Document services and wrapped services are similar in that neither uses the SOAP encoding for data; it's just plain old XML schema. In both cases, however, Axis still "binds" Java representations to the XML (see the databinding section for more), so you end up dealing with Java objects, not directly with XML constructs.
<soap:Envelope xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<soap:Body>
<myNS:PurchaseOrder xmlns:myNS="http://commerce.com/PO">
<item>SK001</item>
<quantity>1</quantity>
<description>Sushi Knife</description>
</myNS:PurchaseOrder>
</soap:Body>
</soap:Envelope>
<complexType name="POType">
<sequence>
<element name="item" type="xsd:string"/>
<element name="quantity" type="xsd:int"/>
<element name="description" type="xsd:string"/>
</sequence>
</complexType>
<element name="PurchaseOrder" type="POType"/>
</deployment>
public void method(PurchaseOrder po)
八、soap envolop(soap信封)
1. soap信封
在客L发出服务h以及服务端返回请求结果的时候,在网l中传输的是SOAP信封。首先客LE序请求参数及h的方法序列到XML的文件中QSOAP信封Q,q将SOAP信封传送到服务器端。服务器端接受到SOAP信封后,解析这个SOAP信封q反序列化调用参数及Ҏq将该方法的调用l果装成SOAP信封Q序列到XML的文件中Q返回给客户端,客户端同样将SOAP信封中封装的q回l果反序列化为想要得到的l果?/p>
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
public class TestClient
{
public static void main(String [] args)
{
try
{
String endpoint = "http://nagoya.apache.org:5049/axis/services/echo";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName(new QName("http://soapinterop.org/", "echoString"));
String ret = (String) call.invoke( new Object[] { "Hello!" } );
System.out.println("Sent 'Hello!', got '" + ret + "'");
}
catch (Exception e)
{
System.err.println(e.toString());
}
}
}
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:echoString xmlns:ns1="http://soapinterop.org/">
<arg0 xsi:type="xsd:string">Hello!</arg0>
</ns1:echoString>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
org.apache.axis.Constants.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
testParam定义用函数的W一个参敎ͼq里也只有一个参敎ͼQ这里也可以同时定义该参数的cd以及该参数是输入、输是输入输出类型。在q里它是一个输入类型,现在当你q行E序Q你得C面的消息Q?br><?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:echoString xmlns:ns1="http://soapinterop.org/">
<testParam xsi:type="xsd:string">Hello!</testParam>
</ns1:echoString>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
在上面的代码中我们知道echoString函数返回一个String对象Q而且我们也希望通过客户端的调用能够q回预期的String对象。下面是一个典型的通过调用echoString函数后获得的Soap信封Q消息)?br><?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:echoStringResponse xmlns:ns1="http://soapinterop.org/">
<result xsi:type="xsd:string">Hello!</result>
</ns1:echoStringResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我们可以看到q里已经声明了返回类型(<result xsi:type="xsd:string">Q是一个String对象。这样Axis可以将q回l果反序列化成我们想要的String对象了?br>很多工具都会这U确定的cd信息攑ֈXML文g中,以生成消息的“自我描述部分”Q另一斚wQ还有一些工h象下面这栯回响应的Q?Many toolkits put this kind of explicit typing information in the XML to make the message "self-describing". On the other hand, some toolkits return responses that look like this:)
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:echoStringResponse xmlns:ns1="http://soapinterop.org/">
<result>Hello, I'm a string!</result>
</ns1:echoStringResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
在这里ƈ没有q回cdQ那么我们怎么知道应该返回结果反序列化成什么类型的l果呢?{案是metadataQ在q种情况下,我们需要一个描q来指明我们期望的返回类型,下面q行代码说明了在客户端应该如何去做:
call.setReturnType( org.apache.axis.Constants.XSD_STRING );
q个Ҏ会告诉Axis客户端,如果q回的结果没有指明类型的话,那么Axis会把返回类型指明ؓxsi:type属性所预定义的SOAPcdQ在q里XSD_STRING属性所指明的是Stringcd?/p>
http://blog.csdn.net/tenwang1977/archive/2004/09/06/95991.aspx
]]>
1 引言
随着Web服务技术的发展和成熟,其方便性和易用性已逐渐被h们所接受Q越来越多的合作伙伴之间开始利用Web服务来实现合作方之间的数据接口。用Apache Axis和Linuxq_是一U低成本的Web服务解决ҎQ但Apache Axis文档的FAQ对开发者来说内容还不够丰富Q本文作者将自己使用Axis旉到的问题和解x法整理成文,奉献lWeb服务的开发h员和Ҏ感兴的读者朋友,旨在帮助大家节约一些宝늚旉。有关Web服务的基知识Q读者可以阅d考文献中推荐的文档。作者未在文中介lApache和Resin的安装方法,读者可以参考相关网站的说明文档?
回页?/font>
axis-ant.jar
axis.jar
commons-discovery.jar
commons-logging.jar
jaxrpc.jar
log4j-1.2.8.jar
name.txt
saaj.jar
wsdl4j.jar
EchoHeaders.jws
fingerprint.jsp
happyaxis.jsp
index.html
XMLPARSER=$RESIN_HOME/lib/xalan.jar:$RESIN_HOME/lib/xercesImpl.jar:$RESIN_HOME/lib/xml-apis.jar
export CLASSPATH=$XMLPARSER:$CLASSPATH
如果CLASSPATH中包含其它的XML解析器设|,应将其从CLASSPATH环境变量的设|中LQ以免发生冲H?
<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"/>
<!-- 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 -->
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);
javac SoftwarePrice.java
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
-oQ指定输出的WSDL文g的文件名?
-lQ指定服务的位置?
-nQWSDL文g的目标名字空间?
-pQ指定从package到名字空间的映射Q这里可以有多个映射?
java.lang.ClassNotFoundException: samples.userguide.example6.SoftwarePrice
at java.net.URLClassLoader$1.run(URLClassLoader.java:198)
at java.security.AccessController.doPrivileged(Native Method)
……
java org.apache.axis.wsdl.WSDL2Java --server-side --skeletonDeploy true MyService.wsdl
No.
文g
用?/td>
1.
deploy.wsdd
MyService服务的部|描q文?/td>
2.
MyService.java
MyService服务的接口文?/td>
3.
MyServiceService.java
获得MyService服务的接口文?/td>
4.
MyServiceServiceLocator.java
实现MyServiceService接口
5.
MyServiceSoapBindingImpl.java
实现MyService接口Q应向其中补充业务逻辑
6.
MyServiceSoapBindingSkeleton.java
MyService服务的服务端框架代码,实现MyService, org.apache.axis.wsdl.Skeleton接口
7.
MyServiceSoapBindingStub.java
MyService服务的客L存根代码,实现MyService接口
8.
undeploy.wsdd
注销MyService服务的部|描q文?/td>
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();//获得一个locator对象
locator.setMaintainSession(true);
com.chinavnet.zx.service.v1_0.SPInterfaceForVNetSoap service = locator.getSPInterfaceForVNetSoap();//获得服务对象
com.chinavnet.zx.service.v1_0.DetailLedgerFeedbackResult feedbackRes = null;
//初始化Web服务中定义的数据cd
try {
feedbackRes = service.generalLedgerFeedback();//调用Web服务的方法ƈ取得q回?
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
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
上面的命令执行后Q有如下提示?
Processing file deploy.wsdd
<Admin>Done processing</Admin>
java.io.IOException: Type {http://schemas.xmlsoap.org/wsdl/} ArrayOfFailedRecord is referenced but not defined.
<s:element minOccurs="0" maxOccurs="1" name="FailedRecords" type="s0:ArrayOfFailedRecord" />
执行java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd命o发布WEB服务时报告如下内宏V?
Processing file deploy.wsdd
Exception:: (404)Not Found
127.0.0.1 - - [17/Sep/2003:15:56:33 +0800] "POST /services/AdminService HTTP/1.0" 404 293
<host id=' '>
<app-dir>/usr/local/apache/htdocs/</app-dir>
<host id='test.com'>
<app-dir>/usr/local/apache/htdocs/esales/</app-dir>
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
Processing file deploy.wsdd
<Admin>Done processing</Admin>
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"
SOAPMonitorApplet.class
SOAPMonitorApplet$ServiceFilterPanel.class
SOAPMonitorApplet$SOAPMonitorData.class
SOAPMonitorApplet$SOAPMonitorFilter.class
SOAPMonitorApplet$SOAPMonitorPage.class
SOAPMonitorApplet$SOAPMonitorTableModel.class
SOAPMonitorApplet$SOAPMonitorTextArea.class
<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>
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
Java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService undeploy.wsdd
...
<service name="MyService" provider="java:RPC">
<parameter name="className" value="samples.userguide.example3.MyService"/>
<parameter name="allowedMethods" value="*"/>
...
...
<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="*"/>
...
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
# java samples.userguide.example3.Client -lhttp://vnet.sohu.com/services/MyService "test"
l果为:You typed : test
<wsdl:service name="SPInterfaceForVNet">
<wsdl:port binding="impl:SPInterfaceSoapSoapBinding" name="SPInterfaceForVNetSoap">
<wsdlsoap:address location="http://test.com/services/SPInterfaceSoap" />
</wsdl:port>
</wsdl:service>
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/ list
执行
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
jar cvf SPInterfaceSoap.jar com/zx/service/v1_0/*.class
java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService undeploy.wsdd
回页?/font>
目前有很多可以用的应用服务器和Web服务q_软gQ本文仅以Apache Axis和ResinZ介绍了在部vWeb服务的过E中可能遇到的问题及其解x法,其中q未讨论Web服务的安全性问题。对于如何高效地开发和部vWeb服务以及如何保Web服务的安全性,q希望对此感兴趣的读者共同参与讨论,对于文中存在的错误和不之处也希望读者朋友们能够不吝批评指正?
电子邮g: redwaveht@hotmail.com
办公电话Q?86(010)87717788?645
Ud电话Q?3910662615
专长Q电子邮件系l,计费pȝQRadius协议,Web服务?
兴趣QJ2EE
研究方向QWeb服务和数据挖?
]]>
1. 什么是SOAP
2. 什么是Axis
一个独立运行的SOAP服务?br> 一个servlet引擎的插Ӟq个servlet引擎可以是Tomcat
对WSDL的扩展支?br> 一个将WSDL的描q生成JAVAcȝ工具
一些示例代?br> q有一个监控TCP/IP包的工具
二、Axis的安?/p>
1.JDK1.4.2
2.一个支持Servlet的服务器引擎Q比如广Zh知的Tomcat?/p>
C:\Tomcat_4_1
%CATALINA_HOME%\webapps\axis
%AXIS_HOME%\lib
%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging.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%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging.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提供了两U服务发布方式,一U是x发布QInstant DeploymentQ,一U是定制发布QCustom DeploymentQ?/p>
{
public double convertMile2Kilometre( double mile )
{
return mile * 1.609; //实现英里到公里的距离转换
}
}
- <wsdl:definitions targetNamespace="http://192.168.0.26:8080/axis/Distance.jws" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://192.168.0.26:8080/axis/Distance.jws" xmlns:intf="http://192.168.0.26:8080/axis/Distance.jws" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <wsdl:message name="convertMile2KilometreRequest">
<wsdl:part name="mile" type="xsd:double" />
</wsdl:message>
- <wsdl:message name="convertMile2KilometreResponse">
<wsdl:part name="convertMile2KilometreReturn" type="xsd:double" />
</wsdl:message>
- <wsdl:portType name="Distance">
- <wsdl:operation name="convertMile2Kilometre" parameterOrder="mile">
<wsdl:input message="impl:convertMile2KilometreRequest" name="convertMile2KilometreRequest" />
<wsdl:output message="impl:convertMile2KilometreResponse" name="convertMile2KilometreResponse" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:binding name="DistanceSoapBinding" type="impl:Distance">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="convertMile2Kilometre">
<wsdlsoap:operation soapAction="" />
- <wsdl:input name="convertMile2KilometreRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://DefaultNamespace" use="encoded" />
</wsdl:input>
- <wsdl:output name="convertMile2KilometreResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://192.168.0.26:8080/axis/Distance.jws" use="encoded" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name="DistanceService">
- <wsdl:port binding="impl:DistanceSoapBinding" name="Distance">
<wsdlsoap:address location="http://192.168.0.26:8080/axis/Distance.jws" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
package samples.capacity;
public class Capacity
{
public double convertGallon2Litre( double gallon )
{
return gallon * 4.546;//实现加仑到升的容U{?br> }//convertGallon2Litre()
其~译?class文gQ放|到“……\webapps\axis\samples\capacity”目录下,卛_着手进行发布?br> 定制发布不需要构?jws文gQ但必须创徏服务发布描述文gdeploy.wsddQWeb Service Deployment Descriptor的羃写)Q这个文件负责描q服务的名称、入口等信息Q其内容如下Q?br> 文gdeploy.wsdd
<service name="Capacity" provider="java:RPC">
<parameter name="className" value="samples.capacity.Capacity"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
可以看到以下q行l果Q?/p>
<Admin>Doneprocessing</Admin>
你也可以调用Q?br> java org.apache.axis.client.AdminClient undeploy.wsdd 来取消部|Ӏ?/p>
- <wsdl:definitions targetNamespace="http://localhost:8080/axis/services/Capacity" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://localhost:8080/axis/services/Capacity" xmlns:intf="http://localhost:8080/axis/services/Capacity" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <wsdl:message name="convertGallon2LitreResponse">
<wsdl:part name="convertGallon2LitreReturn" type="xsd:double" />
</wsdl:message>
- <wsdl:message name="convertGallon2LitreRequest">
<wsdl:part name="in0" type="xsd:double" />
</wsdl:message>
- <wsdl:portType name="Capacity">
- <wsdl:operation name="convertGallon2Litre" parameterOrder="in0">
<wsdl:input message="impl:convertGallon2LitreRequest" name="convertGallon2LitreRequest" />
<wsdl:output message="impl:convertGallon2LitreResponse" name="convertGallon2LitreResponse" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:binding name="CapacitySoapBinding" type="impl:Capacity">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="convertGallon2Litre">
<wsdlsoap:operation soapAction="" />
- <wsdl:input name="convertGallon2LitreRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://capacity.samples" use="encoded" />
</wsdl:input>
- <wsdl:output name="convertGallon2LitreResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/services/Capacity" use="encoded" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name="CapacityService">
- <wsdl:port binding="impl:CapacitySoapBinding" name="Capacity">
<wsdlsoap:address location="http://localhost:8080/axis/services/Capacity" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
(1) AXIS支持三种对象范围Q?br> "request"范围Q这是默认的情况Q每一ơSoaph的时候都创建新的对象?br> "application"范围Q将会ؓ所有的h生成一个单独的׃n的对象?br> "session"范围Qؓ每一个session期的客户端请求创Z个对象?br> 指定Ҏ如下Q?br> <service name="MyService"...>
<parameter name="scope" value="value"/>
...
</service>
(2) 更多部v内容QHandlers and Chains
让我们来深入挖掘一下Axis引擎的更强大的特性。如果我们想跟踪我们的服务被调用了多次Q那么我们只需要包含一个简单的handlerQ它存放在samples/log目录下。要使用q个handlerQ你首先应该部|这个handlerQ然后用在部v服务时给它指定的名字。下面是一个wsdd文g的例子:
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<!-- define the logging handler configuration -->
<handler name="track" type="java:samples.userguide.example4.LogHandler">
<parameter name="filename" value="MyService.log"/>
</handler>
<!-- define the service, using the log handler we just defined -->
<service name="LogTestService" provider="java:RPC">
<requestFlow>
<handler type="track"/>
</requestFlow>
<parameter name="className" value="samples.userguide.example4.Service"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
(3)q程理Q?br> <service name="AdminService" provider="java:MSG">
<parameter name="className" value="org.apache.axis.util.Admin"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="enableRemoteAdmin" value="true"/>
</service>
WARNING: enabling remote administration may give unauthorized parties access to your machine. If you do this, please make sure to add security to your configuration!
所以远E管理涉及到安全问题Q不采用?/p>
http://blog.csdn.net/tenwang1977/archive/2004/07/06/35550.aspx
]]>
web service׃工作中需要用刎ͼ所以那天从|上GOOGLE一?查看如何制作自己的第一个WEB SERVICE。首?web service的原理我׃多讲?再怎么讲也不如人家讲的?况且都是从别人那里拷贝的。还是整点实际的吧。马上徏立自qWEB SERVICE的程序?/p>
2.jakarta-tomcat-5.0.18.exe(q个是安装版?从别的地Ҏ贝也可以?
最也要有q两个包
自己安装吧。挺单的。TOMCAT安装最好改一下名字比如:TOMCAT
1.axis-src-1_2_1q个包解压后Q将axis-1_2_1\webapps下axis的所有东西拷贝到你刚刚徏立的TOMCAT的webapps下。目录结构如下:
tomcat-webapps-axis
然后查看一下你的axis的WEB-INF的lib?.jar文g是否全,应该??br>axis.jar
axis-ant.jar
commons-discovery-0.2.jar
commons-logging-1.0.4.jar
jaxrpc.jar
log4j-1.2.8.jar
saaj.jar
wsdl4j-1.5.1.jar
(一定看好各个文件的文g名,一会将配置CLASSPATH)
?配置classpath
我的电脑-右键属?高-环境变量
1.建立变量:AXIS_HOME=D:\Tomcat\webapps\axis(你自q实际TOMCAT目录)
2.建立变量:AXIS_LIB=%AXIS_HOME%\WEB-INF\lib
建立q两个环境变?br>3.classpath(怿q个变量里面肯定有?TOMCAT安装的时候配|过)
%JAVA_HOME%\lib\tools.jar;
%TOMCAT_HOME%\lib;(以上三个都是安装TOMCAT配置?下面是axis?
%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%\wsdl4j-1.5.1.jar;
%AXIS_LIB%\activation.jar;
%AXIS_LIB%\mail.jar
拯到classpath里面可以了Q然后点ȝ定?/p>
q步很重?我自p?因ؓ如果你不知道CLASSPATH是否配置齐全,所以应该测试一?有些文章没有试直接往下走?但是出现问题了,我就出现了问?是jar包没有导入造成?错误信息如这P
Exception in thread "main" java.lang.NoClassDefFoundError:
at org.apache.axis.description.OperationDesc.<clinit>(OperationDesc.java
:58)
at org.apache.axis.client.Call.addParameter(Call.java:948)
at org.apache.axis.client.Call.addParameter(Call.java:983)
at BankClient.main(BankClient.java:29)
q就是没有导入造成的错误?br>其实你先看一下classpathp避免错误?br>点击开?q行-cmd-打开命o行窗?敲入set classpath,好了你配|的classpath完全昄了,你可以仔l的查看了?/p>
启动TOMCAT,输入|址 http://localhost:8080/axis, 出现 "Hello! Welcome to Apache-Axis." Ƣ迎? 点击链接 Validate 来验?Axis 所需?.jar 包是否齐?(Needed Components).
?开发一?Web Service 服务端程?br>(代码是{?谢谢!)
我的q个例子是?Web Service q回一个请求字D늚?
public class wsTestService
{
String strName = "Ryun";
int intAge = 21;
List items = new ArrayList();
public String getName() {
return strName;
}
public int getAge() {
return intAge;
}
public List getItems() {
return items;
}
}此文g命名?wsTestService.jws 存放?br>d:\tomcat\webapp\axis\?br>讉K http://localhost:8080/axis/wsTestService.jws, 出现 "There is a Web
开发一?Web Service 客户端程?br>建立客户端程序wsTestClient.java
以下是客L的源E序, 用于?Web Service Server 提交服务h:
import org.apache.axis.client.Service;
public class wsTestClient {
public static void main(String args[]) {
System.out.println("Start invoking...");
try {
String strUri =
Service service = new Service();
Call call = (Call)
service.createCall();
call.setTargetEndpointAddress(new
call.setOperationName("getName");
String ret = "" + call.invoke(new Object[] {});
System.out.println("I am " + ret + ".");
}
catch (Exception e) {
System.err.println(e.toString());
}
System.out.println("Finished the invoking.");
}
}
然后~译q行Q如果出现问题,那可能是环境变量path,classpath配置的问?自己查看
C:\>javac wsTestClient.java
C:\>java wsTestClient
Start invoking...
I am Ryun.
Finished the invoking.
完成Q再d习,E后ȝ
来自:
http://www.cnweblog.com/battleseagull/articles/20130.html
]]>