WEBSERVICE使用(基于AXIS2)
使用WEBSERVICE(基于AXIS2)
【AXIS2(非集成)的情况下发布和使用】
一、部署AXIS2
部署:
axis2-bin.zip:此包包括所有的AXIS2使用的JAR包以及工具。
axis2-war.zip:此包是对WEBSERVICE支持的WEB工程
解压axis2-war.zip并将axis2.war发布到TOMCAT中
然后通过URL访问:http://localhost:8080/axis2
发布成功将会出现相关页面。
配置AXIS2热发布,热更新和默认发布目录
axis2\WEB-INF\conf\axis2.xml中配置
热发布:
热更新:
发布目录:
说明在/axis2/WEB-INF/mydir下可以发布WEBSERVICE
二、工具说明
1.通过WSDL生成客户端代码
%AXIS2_HOME%\bin\wsdl2java -uri xxx -p xxx -s -a -o xxx
通过WSDL生成客户端代码,
-uri 指定WSDL地址
-p 生成客户端文件包名
-s 生成客户端同步调用代码
-a 生成客户端异步调用代码
-o 生成文件的路径
2.通过JAVA文件生成WSDL文件
%AXIS2_HOME%\bin\java2wsdl -cp . -sn xxx -tn xxx -of sayhello.wsdl -cn SayHello
-cp 指定CLASSPATH
-sn 指定service名称
-tn 指定TargetNameSpace
-of 指定wsdl名称
-cn 指定CLASS位置和名称
-g 表示生成客户端代码
-ss 标识生成服务端代码
在生成的服务端文件xxxSkeleton中可以加入相关的业务逻辑代码
三、发布WEBSERVICE
1.零配置发布
<1>.即时发布
在axis2/WEB-INF下创建pojo目录,将class放到此目录下。
注:此种方式发布的JAVA类,不能引用package
URL访问如:http://localhost:8080/axis2/services/SayHello/say?name=test
<2>编写动态代理Client:
String url="http://localhost:8080/axis2/services/SayHello";
RPCServiceClient rpcServiceClient=new RPCServiceClient();
Options options=rpcServiceClient.getOptions();
EndpointReference endPoint=new EndpointReference(url);
options.setTo(endPoint);
Object[] param=new Object[]{"boy"};
Class[] classes=new Class[]{String.class};
//注意此处的QNAME,此值为WSDL文件的命名空间,也就是
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,/axis2","say");
Object rs=rpcServiceClient.invokeBlocking(qn, param,classes)[0];
System.out.println("rs="+rs);
QName qn2=new QName("https://www.sodocs.net/doc/ea6447701.html,/axis2","getDate");
rs=rpcServiceClient.invokeBlocking(qn2, new Object[]{}, classes)[0];
System.out.println("rs="+rs);
invokeBlocking:当调用的方法有返回值时使用此方法。
invokeRobust:当调用的方法没有返回值时使用此方法。
invokeBlocking和invokeRobust是同步调用方式,调用后等待返回数据。
invokeNonBlocking:异步访问SERVICE,不等待服务端返回结果数据。
<3>使用命令生成JAVA Client Stub
如:%AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/SayHello?wsdl -p client -s -o stub
其中-url参数指定了wsdl文件的路径,可以是本地路径,也可以是网络路径。-p参数指定了生成的Java类的包名,-o参数指定了生成的一系列文件保存的根目录
-s 表示生成同步代码。-a 表示生成异步代码。
Client:
SayHelloStub sayStub=new SayHelloStub();
SayHelloStub.Say say=new SayHelloStub.Say();
say.setName("wlong");
String rs=sayStub.say(say).get_return();
System.out.println("result="+rs);
System.out.println("age="+sayStub.getAge().get_return());
<4>复杂数据类型的传递和接收
在Axis2中可以直接使用将WebService方法的参数或返回值类型声明成数组或类(接口)。定义数组类型时只能使用一维数组。
如:
传递byte[]数组:
String url="http://localhost:8080/axis2/services/ComplexDataService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
opt.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,/axis2","uploadImg");
Class[] cl=new Class[]{boolean.class};
File f=new File("c:/a.jpg");
FileInputStream fis=new FileInputStream(f);
byte[] buff=new byte[(int)f.length()];
int n=fis.read(buff);
fis.close();
Object [] param=new Object[]{buff,n};
Object rs= rpcClient.invokeBlocking(qn,param,cl)[0];
System.out.println("flag="+rs);
传递自定义对象和接收自定义对象
String url="http://localhost:8080/axis2/services/ComplexDataService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
opt.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,/axis2","info");
Person p=(Person)rpcClient.invokeBlocking(qn, new Object[]{new Person()},new Class[]{Person.class})[0];
System.out.println("str="+p.getInfo());
接收数组;
String url="http://localhost:8080/axis2/services/ComplexDataService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
opt.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,/axis2","getAry");
String[] rs=(String[])rpcClient.invokeBlocking(qn, new Object[]{},new Class[]{String[].class})[0];
for(String str:rs)
{
System.out.println("str="+str);
}
接收序列化对象数组:
String url="http://localhost:8080/axis2/services/ComplexDataService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
op
t.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,/axis2","getByteData");
byte[] rs=(byte[])rpcClient.invokeBlocking(qn, new Object[]{},new Class[]{byte[].class})[0];
ByteArrayInputStream bis=new ByteArrayInputStream(rs);
ObjectInputStream ois=new ObjectInputStream(bis);
Person p=(Person)ois.readObject();
System.out.println("str="+p.getName()+" "+p.getAge());
接收对象数组:
String url="http://localhost:8080/axis2/services/ComplexDataService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
opt.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,/axis2","getListPerson");
Person[] rs=(Person[])rpcClient.invokeBlocking(qn, new Object[]{},new Class[]{Person[].class})[0];
for(Person p:rs)
{
System.out.println("str="+p.getName());
}
注:a.在AXIS2中不能返回List,Map,因为他们不能被序列化,所以在返回多个对象时,可以时候用对象数组来作为返回值。
b。零配置发布缺点:不能使用PACKAGE。所以实际开发发布带来不便。
2.通过配置进行发布
<1>编写services.xml
如:
注:
<2> 创建arr包
组织目录:
如:c:/ws/包目录
c:/ws/META-INF/services.xml
cmd进入c:/ws执行jar -cvf myws.arr
<3>将arr包放到axis2/WEB-INF/services下
<4>启动AXIS2服务,通过客户端访问。
<5>动态代理调用Client:
String url="http://localhost:8080/axis2/services/orderService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
opt.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,","sendOrder");
Order order=new Order();
order.setId("1");
order.setName("1");
order.setPwd("123456");
order.setInfo("client");
Object rs=rpcClient.invokeBlocking(qn, new Object[]{order},new Class[]{String.class})[
0];
System.out.println("str="+rs);
<6>生成Stub调用:
执行命令生成OrderServiceStub类:%AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/orderService?wsdl -p client -s -o stub
OrderServiceStub stub=new OrderServiceStub();
String rs=stub.heartBeat().get_return();
System.out.println("heartbeat="+rs);
OrderServiceStub.SendOrder so=new OrderServiceStub.SendOrder();
OrderServiceStub.Order order=new OrderServiceStub.Order();
order.setName("1");
order.setPwd("123456");
so.setOrder(order);
rs=stub.sendOrder(so).get_return();
System.out.println("sendOrder="+rs);
3.异步调用
通过异步访问SERVICE,客户端可以去执行另外的程序。不必等待SERVICE返回后再执行。
<1>使用异步方法invokeNonBlocking调用
如:
String url="http://localhost:8080/axis2/services/checkService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
opt.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,","getInfo");
//异步调用
rpcClient.invokeNonBlocking(qn, new Object[]{}, new AxisCallback(){
public void onComplete() {
// TODO Auto-generated method stub
System.out.println("complete");
}
public void onError(Exception arg0) {
// TODO Auto-generated method stub
System.out.println("error");
}
public void onFault(MessageContext arg0) {
// TODO Auto-generated method stub
System.out.println("fault");
}
public void onMessage(MessageContext mc) {
// TODO Auto-generated method stub
System.out.println(mc.getEnvelope().getFirstElement().
getFirstElement().getFirstElement().getText());
}
});
System.out.println("call services。。。");
//防止程序退出
System.in.read();
<2>生成客户端异步STUB进行调用
%AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/checkService?wsdl -p com.wl.ws.client -s -a -o stub
执行后生成2个文件
如:CheckServiceCallbackHandler.java和CheckServiceStub.java
然后编写客户端调用程序进行调用
如:
public class CheckCallbackClient
{
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
CheckServiceStub stub=new CheckServiceStub();
stub.startgetInfo(new MyCheckCallback());
System.out.println("call services...");
System.in.read();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class MyCheckCallback extends CheckServiceCallbackHandler
{
public void receiveResultgetInfo(com.wl.ws.client.CheckServiceStub.GetInfoResponse result)
{
System.out.println("result="+result.get_return());
}
}
4.会话管理
在
AXIS2 WebService需要使用org.apache.axis2.context.MessageContext和org.apache.axis2.context.ServiceContext类来保存与获得保存在服务端的状态信息.
AXIS2中有四种会话:application、soapsession、transportsession、request。
其中request为scope属性的默认值。transportsession和application分别实现同一个WebService和跨WebService的会话管理(即全局范围)。
<4-1-1>配置会话范围:services.xml中为Servie配置scope(同一SERVICE的会话管理)
如:
<4-1-2>客户端需要打开SESSION管理
setManageSession(true)
a.对于动态调用方式的客户端:
RPCServiceClient rpcClient=new RPCServiceClient();
Options opt=rpcClient.getOptions();
opt.setManageSession(true);
b.STUB方式访问客户端:
xxxStub stub=new xxxStub();
stub._getServiceClient().getOptions().setManageSession(true);
<4-1-3>服务端例子:
loginService:
public String login(String user,String pwd)
{
if("wl".equals(user)&&"123456".equals(pwd))
{
MessageContext mc=MessageContext.getCurrentMessageContext();
ServiceContext sc=mc.getServiceContext();
sc.setProperty("login", "true");
return "success";
}
else
{
return "failure";
}
}
//获取数据时判断是否已经登录
public String getData()
{
MessageContext mc=MessageContext.getCurrentMessageContext();
ServiceContext sc=mc.getServiceContext();
if(sc.getProperty("login")!=null&&sc.getProperty("login").equals("true"))
{
return "data from server";
}
else
{
return "please login first";
}
}
<4-1-4>客户端:登录后获取数据。
String url="http://localhost:8080/axis2/services/loginService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
opt.setManageSession(true);//允许服务端对SESSION的管理
opt.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,","login");
Object rs=rpcClient.invokeBlocking(qn, new Object[]{"wl","123456"},new Class[]{String.class})[0];
System.out.println("str="+rs);
QName qn2=new QName("https://www.sodocs.net/doc/ea6447701.html,","getData");
Object rs2=rpcClient.invokeBlocking(qn2, new Object[]{},new Class[]{String.class})[0];
System.out.println("str="+rs2);
<4-2-1>跨service的会话管理:用于2个service之间共享会话状态。
需要共享会话的service的SCOPE必须设置为
application
配置方式如:
<4-2-2>服务端代码如:
loginService:
public String login2(String user,String pwd)
{
if("wl".equals(user)&&"123456".equals(pwd))
{
MessageContext mc=MessageContext.getCurrentMessageContext();
ServiceGroupContext sc=mc.getServiceGroupContext();
sc.setProperty("login", "true");
return "success";
}
else
{
return "failure";
}
}
dataService:
public String getData()
{
MessageContext mc=MessageContext.getCurrentMessageContext();
ServiceGroupContext sc=mc.getServiceGroupContext();
if(sc.getProperty("login")!=null&&sc.getProperty("login").equals("true"))
{
return "yes ";
}
else
{
return "please login first";
}
}
<4-2-3>Client:(也可以生成STUB进行调用)
public static void test()
{
try {
String url="http://localhost:8080/MY_WEBSERVICE_AXIS2/services/loginService";
RPCServiceClient rpcClient=new RPCServiceClient();
EndpointReference endpoint=new EndpointReference(url);
Options opt=rpcClient.getOptions();
opt.setManageSession(true);//允许服务端对SESSION的管理
opt.setTo(endpoint);
QName qn=new QName("https://www.sodocs.net/doc/ea6447701.html,","login2");
Object rs=rpcClient.invokeBlocking(qn, new Object[]{"wl","123456"},new Class[]{String.class})[0];
System.out.println("str="+rs);
String url2="http://localhost:8080/MY_WEBSERVICE_AXIS2/services/checkService";
RPCServiceClient rpcClient2=new RPCServiceClient();
EndpointReference endpoint2=new EndpointReference(url2);
Options opt2=rpcClient2.getOptions();
opt2.setManageSession(true);
opt2.setTo(endpoint2);
QName qn2=new QName("https://www.sodocs.net/doc/ea6447701.html,","getData");
Object rs2=rpcClient2.invokeBlocking(qn2, new Object[]{"1"},new Class[]{String.class})[0];
System.out.println("str="+rs2);
} catch (Exception e) {
e.printStackTrace();
}
}
【AXIS2(集成WEBPROJECT)的情况下发布和使用】
1.将axis2/WEB-INF/* 拷贝到 WEBPROJECTNAME/WebRoot/WEB-INF/下
2.将axis2.war/axis2-web拷贝至WebPROJECTNAME/WebRoot/axis2-web/
3.编写web.xml如下内容
org.apache.axis2.transport.http.AxisServlet
ervlet>
4.WebRoot/WEB-INF/services下建立一个文件夹。如:myws
然后在myws下建立META-INF文件夹,在此文件夹下建立services.xml文件
services.xml配置跟上面的相同。
5.发布工程
6.访问,查看服务列表:http://localhost:8080/WEBPROJECTNAME/services/listServices