摘要:本节主要介绍以下两点,1.带javabean的webservice的开发和调用 2.handler的简单介绍及使用
1.引言
在之前的一篇博客
中介绍了如何采用axis1.4来完成一个简单的webservice的开发流程(入参和出参都是基本类型),但是在实际的开发中,方法的入参和出参基本类型已经无法满足我们日常的需求,如果方法的入参和出参中有对象的时候,我们要怎么处理呢?通过本节的介绍我会一一道来。
同时,我会引入对handler的介绍以及简单的使用,写了一个统计webservice调用次数的handler。
2.项目环境
system:win7
myeclipse:6.5
tomcat:5.0
JDK:开发环境采用JDK1.5;编译环境采用JDK1.4
axis:仍然采用1.4的版本。采用版本1是axis1比axis2稳定,实际项目中我们项目中也只用axis1,axis1.4是目前axis1最新版本。
这里测试客户端和服务端放在同一个工程的不同package中;
web.xml---web项目的配置文件;这里我们只用来配置了webservice的处理类AxisServlet;
server-config.wsdd---axis1.4定制发布的配置文件,这里不再需要用AdminClient来生成,直接拷贝之前工程的配置文件然后修改;
WebServiceClientUtil.java---调用webservice服务的客户端,采用动态调用,并且这里的客户端更加灵活;
IGroupInfoService.java和IGroupInfoServiceImpl.java---一个入参和出参包含对象的webservice服务对应的接口和实现类;
GroupInfo.java和UserInfo.java---服务需要用的两个标准的javabean;
GroupServiceHandler.java---一个handler处理类(什么是handler?请见下面的介绍),用来统计webservice的调用次数;
3.Handler介绍
什么是handler?J2EE Web 服务中的Handler技术特点非常像Servlet技术中的Filter。我们知道,在Servlet中,当一个HTTP到达服务端时,往往要经过多个Filter对请求进行过滤,然后才到达提供服务的Servlet,这些Filter的功能往往是对请求进行统一编码,对用户进行认证,把用户的访问写入系统日志等。在我的理解看来,handler就是为了在不污染原有的代码的前提下,通过配置文件,我们可以增加我们需要的功能,相应的,Web服务中的Handler通常也提供一下的功能:比如:
(1)可以记录某一个webservice的访问次数和访问时间(本节有这个小例子来简单介绍handler)
(2)调用webservice之前根据我们的需求做检验(关于使用handler做IP和用户的校验后面会有介绍);
(3)对请求的SOAP消息进行加密,解密
(4)为webservice对象做缓存
handler的处理过程可以表示如下:
图中多个handler在一起,其实这就组成了chain,后面我会对这个做个简单的介绍;
图中有handler有request和response;
那么,到底我们要怎么实现一个handler?
(1)新建一个classs,并且使该类继承BasicHandler类
(2)实现invoke方法
(3)在wsdd文件配置handler处理类,采用标签
(4)在需要使用handler的webservice中引入handler类,采用或者
以上是实现一个handler的步骤,具体的看下面的实例。
4.项目代码
先看看jar包吧
配置文件
web.xml
web.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 xmlns="http://java.sun.com/xml/ns/j2ee"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee6 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
7
8
9 AxisServlet
10
11 org.apache.axis.transport.http.AxisServlet12
13
14
15 AxisServlet
16 /services/*
17
18
19
server-config.wsdd
server-config.wsdd
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
4
5
6
7
8
9 value="D:\tomcat5\webapps\WebService\WEB-INF\attachments" />
10
11
12 value="false" />
13
14
15
16 value="org.apache.axis.attachments.AttachmentsImpl" />
17
18
19
20
21
22
23
24
25
26
27
28 type="java:org.apache.axis.transport.local.LocalResponder" />
29
30 type="java:org.apache.axis.handlers.http.URLMapper" />
31
32 type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" />
33
34
35
36
37 http://xml.apache.org/axis/wsdd/
38
39
40
41
42
43
44
45
46
47
49
50
51 value="org.apache.axis.transport.http.QSListHandler" />
52
53 value="org.apache.axis.transport.http.QSWSDLHandler" />
54
55 value="org.apache.axis.transport.http.QSListHandler" />
56
57 value="org.apache.axis.transport.http.QSMethodHandler" />
58
59 value="org.apache.axis.transport.http.QSMethodHandler" />
60
61 value="org.apache.axis.transport.http.QSWSDLHandler" />
62
63
64
65
66
67
68
69
70
71 type="java:com.server.wsddhandler.GroupServiceHandler">
72
73
74
75
76
77
78
79 value="com.server.impl.IGroupInfoServiceImpl" />
80
81
83 qname="ns:GroupInfo"xmlns:ns="urn:BeanService">
84
85
86
88 qname="ns:UserInfo"xmlns:ns="urn:BeanService">
89
90
91
92
93
94
95
96
97
98
服务端代码
(1)javabean
GroupInfo.java
GroupInfo.java
1 packagecom.server.bean;2
3 importjava.util.List;4
5 public classGroupInfo {6
7 private List colNames = null; //数据库表的列名组成的List
8
9 private String[] colValues; //数据库表一条记录的各个列的值组成的数组,即一条数据库表记录值
10
11 private int colCount = 0; //数据库表记录的列数
12
13 private UserInfo userInfo = null;14
15 publicList getColNames() {16 returncolNames;17 }18
19 public voidsetColNames(List colNames) {20 this.colNames =colNames;21 }22
23 publicString[] getColValues() {24 returncolValues;25 }26
27 public voidsetColValues(String[] colValues) {28 this.colValues =colValues;29 }30
31 public intgetColCount() {32 returncolCount;33 }34
35 public void setColCount(intcolCount) {36 this.colCount =colCount;37 }38
39 publicUserInfo getUserInfo() {40 returnuserInfo;41 }42
43 public voidsetUserInfo(UserInfo userInfo) {44 this.userInfo =userInfo;45 }46
47 }
UserInfo.java
UserInfo.java
1 packagecom.server.bean;2
3 public classUserInfo {4
5 private String serverIp = "";6 private String localIp = "";7 private long opId = 0;8
9 publicString getServerIp() {10 returnserverIp;11 }12
13 public voidsetServerIp(String serverIp) {14 this.serverIp =serverIp;15 }16
17 publicString getLocalIp() {18 returnlocalIp;19 }20
21 public voidsetLocalIp(String localIp) {22 this.localIp =localIp;23 }24
25 public longgetOpId() {26 returnopId;27 }28
29 public void setOpId(longopId) {30 this.opId =opId;31 }32
33 }
(2)服务类
IGroupInfoService.java
IGroupInfoService.java
1 packagecom.server.interfaces;2
3 importcom.server.bean.GroupInfo;4 importcom.server.bean.UserInfo;5
6 /**
7 *8 *Module: IGroupInfoService.java9 *Description: 带javabean的webservice的服务10 *Company:11 *Version: 1.0.012 *Author: pantp13 *Date: Aug 21, 201214 */
15 public interfaceIGroupInfoService {16
17 public abstract GroupInfo getGroupInfo(UserInfo userInfo,longgroupId);18
19 }
IGroupInfoServiceImpl.java
IGroupInfoServiceImpl.java
1 packagecom.server.impl;2
3 importjava.util.ArrayList;4 importjava.util.List;5
6 importcom.server.bean.GroupInfo;7 importcom.server.bean.UserInfo;8 importcom.server.interfaces.IGroupInfoService;9
10 public class IGroupInfoServiceImpl implementsIGroupInfoService {11
12 public GroupInfo getGroupInfo(UserInfo userInfo, longgroupId) {13 System.out.println("开始打印入参值...");14 System.out.println("groupId:" +groupId);15 System.out.println("serInfo.getOpId():" +userInfo.getOpId());16 System.out.println("serInfo.getServerIp():" +userInfo.getServerIp());17 System.out.println("serInfo.getLocalIp():" +userInfo.getLocalIp());18 System.out.println("结束打印入参值...");19
20 //这里是为了学习webservice调用时带javabean,所以方法的返回值就直接手动的构造了
21 GroupInfo group = newGroupInfo();22 group.setColCount(1);23
24 List colNames = newArrayList();25 colNames.add("group_id");26 colNames.add("group_name");27 colNames.add("state");28 group.setColNames(colNames);29
30 String colValues[] = { "2100014", "中国移动通信", "1"};31 group.setColValues(colValues);32
33 group.setUserInfo(userInfo);34 returngroup;35 }36
37 }
(3)handler处理类
GroupServiceHandler.java
GroupServiceHandler.java
1 packagecom.server.wsddhandler;2
3 importjava.text.SimpleDateFormat;4 importjava.util.Date;5
6 importorg.apache.axis.AxisFault;7 importorg.apache.axis.MessageContext;8 importorg.apache.axis.handlers.BasicHandler;9
10 /*
11 * 采用handler统计webservice的访问次数12 */
13 public class GroupServiceHandler extendsBasicHandler {14
15 private static final long serialVersionUID = 1L;16
17 private static long COUNT = 0L;18
19 private int requestCount = 0;20
21 public void invoke(MessageContext arg0) throwsAxisFault {22 requestCount++;23 COUNT++;24 //拿到配置文件中配置的属性名称status对应的属性值
25 String status = (String) this.getOption("status");26 System.out.println("GroupServiceHandler's status is:" +status27 + ",COUNT=" + COUNT + ",HandlerRequestCount=" +requestCount);28 Date date=newDate();29 SimpleDateFormat df=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:SS E");30 System.out.println("access time:"+df.format(date));31
32 }33
34 };
客户端代码
WebServiceClientUtil.java
WebServiceClientUtil.java
1 packagecom.client;2
3 importjavax.xml.namespace.QName;4 importorg.apache.axis.client.Call;5 importorg.apache.axis.client.Service;6 importorg.apache.axis.description.OperationDesc;7 importorg.apache.axis.description.ParameterDesc;8 importorg.apache.axis.encoding.ser.BeanDeserializerFactory;9 importorg.apache.axis.encoding.ser.BeanSerializerFactory;10 importjava.net.URL;11 importorg.apache.axis.constants.Style;12 importorg.apache.axis.constants.Use;13 importorg.apache.axis.soap.SOAPConstants;14
15 /*实际开发中,16 *服务端和客户端不在同一工程,客户端需要新建自己的javabean,这里我直接用服务端的类了17 *至于怎么新建可以采用上一节博客中的genClient.bat文件18 */
19 importcom.server.bean.GroupInfo;20 importcom.server.bean.UserInfo;21
22 public classWebServiceClientUtil {23 public static void main(String args[]) throwsException {24 //准备参数
25 String methodName = "getGroupInfo";26
27 String key[] = { "userInfo", "groupId"};28
29 UserInfo userInfo = newUserInfo();30 userInfo.setLocalIp("127.0.0.1");31 userInfo.setOpId(1234);32 userInfo.setServerIp("127.0.0.1");33
34 Long groupId = new Long(2100000014);35 Object value[] ={ userInfo, groupId };36
37 //调用webservice服务
38 GroupInfo result =(GroupInfo) getGroupInfo(methodName, key, value);39
40 //打印返回的信息
41 System.out.println(result.getColCount());42
43 for (int i = 0; i < result.getColNames().size(); i++)44 System.out.print(result.getColNames().get(i) + "\t \t");45 System.out.println();46 for (int i = 0; i < result.getColValues().length; i++)47 System.out.print(result.getColValues()[i] + "\t \t");48 System.out.println();49 System.out.println(result.getUserInfo().getServerIp());50 }51
52 /**
53 *
54 *@parammethodName 调用webservice的方法名称55 *@paramkey 调用webservice的该方法所有的参数名称组成的数组56 *@paramvalue 调用webservice的该方法所有的参数对应的实际入参值57 *@return
58 *@Description:动态调用webservice的客户端代码59 */
60 public staticObject getGroupInfo(String methodName, String key[],61 Object value[]) throwsException {62
63 Service service = newService();64 Call call =(Call) service.createCall();65
66 //注册SimpleObject的序列化类型
67 QName qn = new QName("urn:BeanService", "GroupInfo");68 call.registerTypeMapping(GroupInfo.class, qn,69 new BeanSerializerFactory(GroupInfo.class, qn),70 new BeanDeserializerFactory(GroupInfo.class, qn));71
72 QName qn2 = new QName("urn:BeanService", "UserInfo");73 call.registerTypeMapping(UserInfo.class, qn2,74 new BeanSerializerFactory(UserInfo.class, qn2),75 new BeanDeserializerFactory(UserInfo.class, qn2));76
77 String wsdl_url = "http://localhost:8080/WebService02/services/GroupService?wsdl";78 String qname_url = "http://localhost:8080/WebService02/services/GroupService";79
80 call.setTargetEndpointAddress(new URL(wsdl_url)); //Web服务调用
81
82 OperationDesc oper = newOperationDesc();83
84 for (int i = 0; i < key.length; i++) {85 ParameterDesc param = new ParameterDesc(new QName("", key[i]),ParameterDesc.IN, null);86 oper.addParameter(param);87 }88 oper.setReturnType(new QName("urn:BeanService", "GroupInfo"));89 oper.setReturnClass(GroupInfo.class);90 oper.setReturnQName(new QName("", methodName));91 oper.setStyle(Style.RPC);92 oper.setUse(Use.ENCODED);93 call.setOperation(oper);94 call.setUseSOAPAction(true);95 call.setSOAPActionURI("");96 call.setSOAPVersion(SOAPConstants.SOAP11_CONSTANTS);97 call.setOperationName(newQName(qname_url, methodName));98
99 java.lang.Object _resp = null;100 _resp =call.invoke(value);101 return_resp;102 }103
104 }
5.运行效果
发布项目,启动tomcat服务器;
(1)在浏览器输入wsdl地址
(2)采用webservice客户端调用,查看返回结果
客户端后台日志:
服务端后台日志: