分享
 
 
 

向Web Service进军--Axis+Tomcat模拟一个银行存取款服务

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

下载Apache Axis用来实现SOAP(简单对象访问协议)。http://ws.apache.org/axis/

目前最稳定的版本是1.1

SOAP是用于在分散的或者分布式的环境中交换信息的一个轻量级协议。SOAP基于XML,由三部分组成:一个必须的SOAP封装,一个可选的SOAP头和一个必须的SOAP体。

通常情况下,SOAP = HTTP + RPC + XML。 即:SOAP以HTTP作为底层通信协议,以RPC作为交互方式,以XML作为数据传送的格式。

Web Service开发所需要掌握的技能:

JAVA,线程,同步,Classloader,错误排除,知道NPE(NullPointerException)和其他一些常见的错误,并能够处理,Servlet,如何发布Web 应用到应用服务器(Tomcat等)

TCP/IP,socket API,XML...多得吓人啊!要学习啊:(

1 安装配置Axis

~~安装Tomcat 4.X以上版本(4.X后的版本都带XML的解析器)

~~解压Axis1.1.zip包,找到webapps目录下的axis文件夹,拷贝axis文件夹到Tomcat中的webapps文件夹下。

~~将Tomcat中的axis目录下的WEB-INF\lib中的所有的文件copy到Tomcat的common\lib目录中。(以后凡是要在axis的lib中添加jar文件,都要copy一份到Tomcat的common\lib目录下)。

~~我的电脑->属性->高级->环境变量->系统变量中添加:

AXIS_HOME

%TOMCAT_HOME%\webapps\axis(TOMCAT的目录)

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

修改CLASSPATH ,在末尾加上:

%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

注意检查CLASSPATH是否正确:(有些软件会在用户变量区设置一个classpath,会有影响,如:XMLSPY)

在DOS方式下

输命令:Echo %CLASSPATH%

~~检查配置:

启动Tomcat,访问http://localhost:8080/axis/

验证axis的是否工作:http://localhost:8080/axis/happyaxis.jsp如果正常显示表示正常。

上图中 倒数第3行字“The core axis libra….”,要保证core axis libraries are present,如果有任何core library is missing,就到其提供的相应的链接上找到对应的jar文件,并copy到tomcat目录里面的axis文件夹WEB-INF\lib中,别忘了Tomcat自己的common\lib也copy一份。

直到所有的core library are present.

好啦基本上都配置好了。现在我们开始做一个有点模样的web Service的例子啦。一步一步来:)

目标:模拟一个银行存取款系统,存取款的具体实现作为服务来提供

Axis提供了两种服务发布方式,一种是即时发布(Instant Deployment),一种是定制发布(Custom Deployment)。

1. 使用即时发布 Java Web Service(JWS)

“对即时发布的支持是Axis的特色之一,使用即时发布使用户只需有提供服务的Java类的源代码,即可将其迅速发布成Web服务。每当用户调用这类服务的时候,Axis会自动进行编译,即使服务器重启了也不必对其做任何处理,使用非常简单快捷。”

使用即时发布首先需要一个实现服务功能的Java源文件,将其扩展名改为.jws(Java Web Service的缩写),然后将该文件放到Tomcat下面的webapps\axis目录下即可。但是JWS的web服务发布是一个很简单的Web服务发布方式,在页面中你不能使用包,而且由于代码是在运行期被编译的,所以在部署之后,你也很难找到错误所在。

就是不好罗,但是我们还是来看一个例子:大家在Tomcat的webapps\axis下找到Calculate.jws文件,然后打开看看。不用编译的。

发布吧:http://localhost:8080/axis/Distance.jws?wsdl 如果你看到下面的WSDL描述表示你已经发布成功啦:

怎么使用这个服务呢?大家到

Tomcat 5.0\webapps\axis\WEB-INF\classes\samples\userguide\example2

里面是不是看到一个CalcClient.class的文件啊?这个文件就是对应的axis提供的calculate的客户端的例子。在dos方式,到Tomcat 5.0\webapps\axis\WEB-INF\classes\目录下:

java samples.userguide.example2.CalcClient add 3 4

是不是得到7了啊?如果出现NoDefClass的错误的话就用echo检查各个环境变量吧。一般都错在这里。

Calculator对应的源代码在下载的axis.zip里面的samples\userguide\example2里面。

2. 使用定制发布 Web Service Deployment Descriptor(WSDD)

“即时发布是一项令人激动的技术,它使Web服务的开发变得如此简单;然而即时发布并不总是最好的选择,比如有些应用系统是第三方提供的,我们没有购买源代码,只有.class文件,但我们又希望将这个应用系统的一些功能对外发布成Web服务,使其能够在更大范围内产生作用,这个时候即时发布技术就无能为力了。此外,即时发布技术并不灵活,无法进行更多的服务配置,这使得它并不能满足一些特定系统的需求。”

好啦 到我们啦,我先不说定制发布有什么好,大家先往下看,自然会有体会的:)

首先给出我们的模拟银行存取款的java文件:

Account.java

package com.duckur;

public class? Account

{

/*************************************************************

/*从随机数中获取帐户(一次性有效)*/

public static int fund = (int)(java.lang.Math.random()*10000);

//模拟,大家可以从文件中读取数据,或者从数据库中取出这个fund值

/*************************************************************

/*检查输入的有效性*/

public boolean checkInput(int money)//只能取整数

{

if(money > fund)

{

return false;

}

else

{

return true;

}

}

/*************************************************************

/*存款*/

public int deposit(int money)

{

fund? = fund + money;

return fund;

}

/*************************************************************

/*取款*/

public int withdraw(int money)

{

if(checkInput(money))

{

fund = fund - money;

}

return fund;

}

/*************************************************************

/*获取当前的帐户值*/

public int getAccount()

{

return fund;

}

}

然后编译,通过后生成的class文件应该放在Tomcat下的webapps\axis\WEB-INF\com\duckur\下面。

下面发布:

在Tomcat下的webapps\axis\WEB-INF\com\duckur\目录下新建一个deploy.wsdd文件描述服务的名称、入口等信息:

wsdd文件的显示有问题[url=http://listenstyle.com/blog/towardaxis/1.rar]下载吧

其中service项重的名称为该服务的名称即Account,java:RPC指明了一个JAVA RPC服务,做这个处理的类是org.apache.axis.providers.java.RPCProvider。

“我们是通过一个标签告诉RPC服务应该调用的类,而另外一个标签则告诉引擎,它可以调用这个类中的任何的Public方法。你也可以指定通过使用名字空间或者一些可以调用的方法列表,来指明那些方法可以被调用。”

当然也可以用Axis提供的一个客户端管理工具——AdminClient来完成服务的定制发布。这里不说:)

然后在DOS下到该目录下,

java org.apache.axis.client.AdminClient deploy.wsdd

如果出现:

Processing file deploy.wsdd

Doneprocessing

这表明Capacity服务定制发布完成。

好现在你就可以通过http://localhost:8080/axis/services/Account?wsdl来查看WSDL描述了。

Web Service发布好了现在调用它吧.

这里说一个最基本的调用需要用的类和方法:

(取出当前的金额)

...

//新建一个服务对象

Service service = new Service();??

//调用服务对象的createCall()方法返回一个命令

Call call = (Call) service.createCall();??

// Sets the address of the target service endpoint.

call.setTargetEndpointAddress(new java.net.URL("http://localhost:8080/axis/services/LxAccount"));

//?Sets the name of the operation to be invoked using this Call instance

call.setOperationName(“getAccount”);

//Convenience method to invoke a //method with a default (empty) namespace

Integer myFund = (Integer) call.invoke(new Object[] {});

...

详细函数可以参考开发API在下载的axis.zip中的docs里面。

下面是详细的代码:

编译后执行就可以。

LxClient.java

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

import org.apache.axis.encoding.XMLType;

import org.apache.axis.utils.Options;

import javax.xml.rpc.ParameterMode;

import javax.xml.namespace.QName;

public class LxClient

extends JFrame {

JTextField jTextField1 = new JTextField();

JLabel jLabel3 = new JLabel();

JLabel jLabel1 = new JLabel();

JButton jButton1 = new JButton();

JButton jButton2 = new JButton();

JButton jButton3 = new JButton();

JLabel jLabel2 = new JLabel();

JTextField jTextField2 = new JTextField();

public LxClient() {

try {

jbInit();

}

catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String args[]){

LxClient myframe=new LxClient();

myframe.setSize(400,200);

myframe.setVisible(true);

}

private void jbInit() throws Exception {

this.getContentPane().setLayout(null);

jTextField1.setText("");

jTextField1.setBounds(new Rectangle(131, 51, 80, 24));

jLabel3.setText("A0317286 李迅");

jLabel3.setBounds(new Rectangle(102, 15, 108, 17));

jLabel1.setText("填入金额:");

jLabel1.setBounds(new Rectangle(64, 54, 55, 21));

jButton1.setBounds(new Rectangle(50, 96, 58, 23));

jButton1.setText("存款");

jButton1.addActionListener(new LxClient_jButton1_actionAdapter(this));

jButton2.setBounds(new Rectangle(126, 96, 63, 23));

jButton2.setText("取款");

jButton2.addActionListener(new LxClient_jButton2_actionAdapter(this));

jButton3.setBounds(new Rectangle(205, 94, 81, 24));

jButton3.setText("查看金额");

jButton3.addActionListener(new LxClient_jButton3_actionAdapter(this));

jLabel2.setText("当前的金额:");

jLabel2.setBounds(new Rectangle(59, 136, 74, 21));

jTextField2.setEditable(false);

jTextField2.setText("");

jTextField2.setBounds(new Rectangle(127, 133, 85, 25));

this.getContentPane().add(jTextField1, null);

this.getContentPane().add(jLabel3, null);

this.getContentPane().add(jLabel1, null);

this.getContentPane().add(jButton2, null);

this.getContentPane().add(jButton1, null);

this.getContentPane().add(jButton3, null);

this.getContentPane().add(jLabel2, null);

this.getContentPane().add(jTextField2, null);

}

/***************************************************************************

调用WebService* /

存款*/

void jButton1_actionPerformed(ActionEvent e) {

try {

String endpoint = "http://localhost:8080/axis/services/LxAccount";

String method = "deposit";

Integer i = Integer.valueOf(jTextField1.getText());

Service service = new Service();

Call call = (Call) service.createCall();

call.setTargetEndpointAddress(new java.net.URL(endpoint));

call.setOperationName(method);

Integer myFund = (Integer) call.invoke(new Object[] {i});

//更新数据

jTextField2.setText(myFund.toString());

jLabel1.updateUI();

}

catch (Exception ex) {

System.err.println(ex.toString());

}

}

/***************************************************************************

取款*/

void jButton2_actionPerformed(ActionEvent e) {

try {

String endpoint = "http://localhost:8080/axis/services/LxAccount";

String method = "withdraw";

Integer i = Integer.valueOf(jTextField1.getText());

Service service = new Service();

Call call = (Call) service.createCall();

call.setTargetEndpointAddress(new java.net.URL(endpoint));

call.setOperationName(method);

Integer myFund = (Integer) call.invoke(new Object[] {i});

//更新数据

jTextField2.setText(myFund.toString());

jLabel1.updateUI();

}

catch (Exception ex) {

System.err.println(ex.toString());

}

}

/***************************************************************************

显示当前金额*/

void jButton3_actionPerformed(ActionEvent e) {

try {

String endpoint = "http://localhost:8080/axis/services/LxAccount";

String method = "getAccount";

Service service = new Service();

Call call = (Call) service.createCall();

call.setTargetEndpointAddress(new java.net.URL(endpoint));

call.setOperationName(method);

Integer myFund = (Integer) call.invoke(new Object[] {});

//更新数据

jTextField2.setText(myFund.toString());

jLabel1.updateUI();

}

catch (Exception ex) {

System.err.println(ex.toString());

}

}

}

class LxClient_jButton1_actionAdapter

implements java.awt.event.ActionListener {

LxClient adaptee;

LxClient_jButton1_actionAdapter(LxClient adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jButton1_actionPerformed(e);

}

}

class LxClient_jButton2_actionAdapter

implements java.awt.event.ActionListener {

LxClient adaptee;

LxClient_jButton2_actionAdapter(LxClient adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jButton2_actionPerformed(e);

}

}

class LxClient_jButton3_actionAdapter

implements java.awt.event.ActionListener {

LxClient adaptee;

LxClient_jButton3_actionAdapter(LxClient adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jButton3_actionPerformed(e);

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有