- 浏览: 434701 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
陌路人丁:
SmallFish 写道同上,我也遇到了这个问题,目前还没解决 ...
Java类动态加载(一)——java源文件动态编译为class文件 -
陌路人丁:
冯程程 写道如果java源码中引用了第三方类后,动态编译会报软 ...
Java类动态加载(一)——java源文件动态编译为class文件 -
lvhejin:
Java设计模式源代码——自己看pdf写的 -
yunxi_2015:
不好用啊,查询失败
用Java解析手机号获取手机信息(归属地、Sim卡类型、移动或是联通、区号、邮编) -
zhouyicang:
我是拿来现成用的,非常感谢博主的代码,不过我给和我一样的人一个 ...
判断点与多边形的位置关系
附件中附带页面jsp、js,还有dwr的action,service以及util,我的环境是spring、dwr、ext、jquery。由于整个工具牵扯的比较多,所以没有将完整的可运行的代码整理出来,只将所有核心的代码贴了出来,如果需要运行还需要解决些小问题
近段时间,需要为公司的QA测试人员提供一个Webservice的测试工具,具体要求为:测试人员提供webservice的url,测试工具根据url得到webservice发布的方法及方法的参数,然后测试人员在页面输入参数,并点击运行,工具运行后,在页面上显示返回的结果。其实测试人员可以用现成在测试框架soapui来测试webservice,不过测试人员仍觉得麻烦,Team Leader还要求工具不能用wsdl2java生成webservice的客户端代码。我想可能是不想在项目中存放过多的无用的临时文件吧。
测试工具支持参数和返回值的类型有:数组、List、java基本数据类型、java对象以及这些类型的相互嵌套。工具截图如下
下面说说工具的实现思路:
在看实现代码前,不懂wsdl和schema的朋友们可以根据以下网址,先熟悉一下wsdl和schema文件的结构,和各个属性字段
代码讲解:
用于在页面显示方法和方法参数的实体bean
获取webservice发布的方法
得到方法的参数
解析输入参数的核心方法
当页面输入完参数后,执行方法
发送soap请求,然后获得返回的soap消息
将参数解析成发送的soap消息核心方法
将返回的soap消息解析成页面参数核心方法
近段时间,需要为公司的QA测试人员提供一个Webservice的测试工具,具体要求为:测试人员提供webservice的url,测试工具根据url得到webservice发布的方法及方法的参数,然后测试人员在页面输入参数,并点击运行,工具运行后,在页面上显示返回的结果。其实测试人员可以用现成在测试框架soapui来测试webservice,不过测试人员仍觉得麻烦,Team Leader还要求工具不能用wsdl2java生成webservice的客户端代码。我想可能是不想在项目中存放过多的无用的临时文件吧。
测试工具支持参数和返回值的类型有:数组、List、java基本数据类型、java对象以及这些类型的相互嵌套。工具截图如下
下面说说工具的实现思路:
- 用wsdl4j工具根据webservice的url解析出wsdl文件中包含的方法
- 利用dom解析wsdl的schema部分,手动解析出方法的参数
- 利用soapui获得发送soap请求消息的模板
- 将参数填入发送的soap请求消息
- 获得返回的soap消息
- 解析返回的soap消息中的返回值,显示到页面
在看实现代码前,不懂wsdl和schema的朋友们可以根据以下网址,先熟悉一下wsdl和schema文件的结构,和各个属性字段
代码讲解:
用于在页面显示方法和方法参数的实体bean
/** * @author zhengtian * * @date 2011-8-4 下午11:21:50 */ @SuppressWarnings("all") public class WebServiceMethod { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
import java.util.ArrayList; import java.util.List; public class ParameterInfo { private String name;// 参数名 private String value;// 参数值 private String type;// 参数类型 private String childType;// 如果是数组,那么该字段为数组元素的类型 private List<ParameterInfo> children = new ArrayList<ParameterInfo>(); public ParameterInfo() { } public ParameterInfo(String name, String type) { this.name = name; this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getType() { return type; } public void setType(String type) { this.type = type; } public List<ParameterInfo> getChildren() { return children; } public void setChildren(List<ParameterInfo> children) { this.children = children; } public String getChildType() { return childType; } public void setChildType(String childType) { this.childType = childType; } /** * 增加子参数 * * @param param */ public void addChild(ParameterInfo param) { children.add(param); } }
获取webservice发布的方法
public List<WebServiceMethod> getAllMethodByServiceUrl(String webserviceUrl) throws Exception { // 结果 List<WebServiceMethod> list = new ArrayList<WebServiceMethod>(); try { // 将url修正为合法的url,即带wsdl后缀的 webserviceUrl = getWebserviceUrl(webserviceUrl); if (StringUtils.isNotEmpty(webserviceUrl)) { List<String> methodList = WsdlUtil.getOperationList(webserviceUrl); for (String methodName : methodList) { WebServiceMethod webServiceMethod = new WebServiceMethod(); webServiceMethod.setName(methodName); list.add(webServiceMethod); } } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } return list; }
/** * 得到wsdl中所有的方法 * * @param wsdlUrl * @return * @throws Exception */ public static List<String> getOperationList(String wsdlUrl) throws Exception { Document document = getDefinitionDocument(wsdlUrl); XPath xpath = getXpath(document); NodeList operations = DOMUtil.findNodeList(document, "wsdl:definitions/wsdl:portType/wsdl:operation"); // 返回的结果集list List<String> operationList = new ArrayList<String>(); for (int i = 0; i < operations.getLength(); i++) { Node operation = operations.item(i); String operationName = DOMUtil.getNodeName(operation); if (operationName != null && !"".equals(operationName)) { log.debug("解析" + wsdlUrl + "中的方法:" + operationName); operationList.add(operationName); } } return operationList; }
得到方法的参数
/** * 根据方法名称和webserviceUrl得到参数 * * @param methodName * @param webserviceUrl * @return * @throws Exception */ public List<ParameterInfo> getParamByMethodNameAndWsUrl(String methodName, String webserviceUrl) throws Exception { try { Document document = WsdlUtil.getDefinitionDocument(webserviceUrl); // 返回结果 List<ParameterInfo> inputParamList = new ArrayList<ParameterInfo>(); // 解析参数 StringBuilder xpathBuilder = new StringBuilder(); WsdlUtil.getInputParam(inputParamList, document, methodName, xpathBuilder, null, false); return inputParamList; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } }
解析输入参数的核心方法
/** * 得到输入参数 * * @param inputParamList * @param document * @param operationName * @param xpathBuilder * @param parentParam * @param isSelfDefinition * @throws Exception */ public static void getInputParam(List<ParameterInfo> inputParamList, Document document, String operationName, StringBuilder xpathBuilder, ParameterInfo parentParam, boolean isSelfDefinition) throws Exception { // 得到complexTypeName String complexTypeName = ""; if (parentParam == null) { complexTypeName = operationName; } else { if (parentParam.getType().equals(SchemaDefaulyType.type_array.type)) { complexTypeName = parentParam.getChildType(); } else { complexTypeName = parentParam.getType(); } } // 得到所有的element结点 List<Node> children = getSequenceElementOfComplexType(document, parentParam, complexTypeName, xpathBuilder, isSelfDefinition); for (int i = 0; i < children.size(); i++) { // 子结点 Node child = children.get(i); String name = DOMUtil.getNodeName(child); // 参数 ParameterInfo param = new ParameterInfo(); param.setName(name); // 是否存在type属性(判断其type是引用还是自身定义) if (DOMUtil.assertNodeAttributeExist(child, "type")) {//type存在 String type = DOMUtil.getNodeType(child); if (DOMUtil.isArray(child)) { param.setType(SchemaDefaulyType.type_array.type); param.setChildType(type); // 如果是简单的数组,则为数组增加一个子参数 ParameterInfo childParam = new ParameterInfo("", type); param.addChild(childParam); // 复杂类型数组 if (!DOMUtil.isDefaultType(child)) { getInputParam(inputParamList, document, operationName, xpathBuilder, childParam, false); } } else { param.setType("anyType".equals(type) ? "object" : type); // 复杂类型 if (!DOMUtil.isDefaultType(child)) { StringBuilder complextXpath = new StringBuilder("wsdl:definitions/wsdl:types/xs:schema"); getInputParam(inputParamList, document, operationName, complextXpath, param, false); } } } else {// 如果type属性不存在,说明该结点的类型在其子结点中定义 String currentAppendStr = "/xs:complexType[@name='" + parentParam.getType() + "']/xs:sequence/xs:element[@name='" + name + "']"; xpathBuilder.append(currentAppendStr); Node inner = DOMUtil.findNode(document, xpathBuilder.toString() + "/xs:complexType/xs:sequence/xs:element[position()=1]"); if (DOMUtil.isArray(inner)) { // 得到数组的类型 String type = getSequenceElementType(document, inner); param.setType(SchemaDefaulyType.type_array.type); param.setChildType(type); // 为数组增加一个子参数 ParameterInfo childParam = new ParameterInfo("", type); param.addChild(childParam); if (!DOMUtil.isDefaultType(type)) {// 复杂类型数组 getInputParam(inputParamList, document, operationName, xpathBuilder, childParam, true); } } else { param.setType(name); // 遍历其子结点xs:element getInputParam(inputParamList, document, operationName, xpathBuilder, param, true); } // 将xpath还原 xpathBuilder.delete(xpathBuilder.length() - currentAppendStr.length(), xpathBuilder.length()); } if (parentParam == null) { inputParamList.add(param); } else { parentParam.addChild(param); } } }
当页面输入完参数后,执行方法
/** * 执行方法 * * @param webserviceUrl * @param methodName * @param paramStr * @return * @throws Exception */ public String executionMethod(String webserviceUrl, String methodName, String paramStr) throws Exception { String result = ""; try { // 将json参数转换为List<ParameterInfo> List<ParameterInfo> paramList = convertStrToListParam(paramStr); List<ParameterInfo> resultList = new SoapUtil().sendRequest(methodName, paramList, webserviceUrl); result = JSONArray.fromObject(resultList).toString(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } return result; }
发送soap请求,然后获得返回的soap消息
/** * 发送请求 * * @param operation * @param params * @param wsdlUrl * @return * @throws Exception */ public List<ParameterInfo> sendRequest(String operation, List<ParameterInfo> paramList, String wsdlUrl) throws Exception { // 获取操作 Operation operationInst = getOperation(wsdlUrl, operation, null); // 组装请求消息 String message = buildRequest(wsdlUrl, operationInst, paramList); // 发送请求,得到返回的soap消息 String address = wsdlUrl.substring(0, wsdlUrl.indexOf("?wsdl")); String responseStr = sendRequest(address, message, operationInst.getAction()); Document soapDocument = getResponseDocument(responseStr); // 判断返回的soap消息是否为soap:Fault if (isFaultResponseSoap(soapDocument)) { processFaultResponseSoap(soapDocument); } // 解析返回结果 List<ParameterInfo> outPutParamList = new ArrayList<ParameterInfo>(); List<Map<String, Object>> wsdlMapSoapList = new ArrayList<Map<String, Object>>(); String complextTypeName = operation + "Response"; getOutPutParam(WsdlUtil.getDefinitionDocument(wsdlUrl), soapDocument, complextTypeName, complextTypeName, wsdlMapSoapList, outPutParamList, null); return outPutParamList; }
将参数解析成发送的soap消息核心方法
/** * 构建soap消息 * * @param wsdlDocument * @param soapDocument * @param operationInst * @param paramList * @param parentNode * @throws Exception */ private void buildSOAPMessage(Document wsdlDocument, Document soapDocument, Operation operationInst, List<ParameterInfo> paramList, Node parentNode, ParameterInfo parentParam) throws Exception { // 操作名称 String operationName = operationInst.getName(); // 如果是操作方法的根节点,则清空其子节点 if (parentNode == null) { parentNode = getOperationNodeInRequestSoapDom(soapDocument, operationName); parentNode.setTextContent(""); } for (int i = 0; i < paramList.size(); i++) { // 得到参数的name、type、value ParameterInfo param = paramList.get(i); String value = param.getValue(); String name = param.getName(); String type = param.getType(); // 判断是否为基本类型 if (DOMUtil.isDefaultType(type) || (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(type)) || ("entry".equals(type) || "JsonEntry".equals(type))) { if (StringUtils.isEmpty(name)) { if (i > 0) { Element ele = soapDocument.createElement(parentNode.getNodeName()); Text text = soapDocument.createTextNode(value); ele.appendChild(text); Node grandParentNode = parentNode.getParentNode(); grandParentNode.appendChild(ele); } else { if ("entry".equals(type) || "JsonEntry".equals(type)) { Element ele = soapDocument.createElement(type); parentNode.appendChild(ele); // 组装子结点 if (param.getChildren().size() > 0) { List<Node> childList = DOMUtil.getChildElementNodes(parentNode); Node lastChildNode = childList.get(childList.size() - 1); buildSOAPMessage(wsdlDocument, soapDocument, operationInst, param.getChildren(), lastChildNode, param); } } else { Text text = soapDocument.createTextNode(value); parentNode.appendChild(text); } } } else { Element ele = soapDocument.createElement(name); Text text = soapDocument.createTextNode(value); ele.appendChild(text); parentNode.appendChild(ele); // 组装子结点 if (param.getChildren().size() > 0) { List<Node> childList = DOMUtil.getChildElementNodes(parentNode); Node lastChildNode = childList.get(childList.size() - 1); buildSOAPMessage(wsdlDocument, soapDocument, operationInst, param.getChildren(), lastChildNode, param); } } } else {// 如果不是基本类型,则直接组装该节点的子结点 if (i > 0) { Element ele = soapDocument.createElement(parentNode.getNodeName()); Node grandParentNode = parentNode.getParentNode(); grandParentNode.appendChild(ele); // 组装子结点 if (param.getChildren().size() > 0) { List<Node> childList = DOMUtil.getChildElementNodes(grandParentNode); Node lastChildNode = childList.get(childList.size() - 1); buildSOAPMessage(wsdlDocument, soapDocument, operationInst, param.getChildren(), lastChildNode, param); } } else { // 组装子结点 if (param.getChildren().size() > 0) { buildSOAPMessage(wsdlDocument, soapDocument, operationInst, param.getChildren(), parentNode, param); } } } } }
将返回的soap消息解析成页面参数核心方法
/** * 解析返回的soap消息,然后将结果填充到outPutParamList中 * * @param wsdlDocument * @param soapDocument * @param operationResponseName * @param complextTypeName * @param wsdlMapSoapList * @param outPutParamList * @throws Exception */ public void getOutPutParam(Document wsdlDocument, Document soapDocument, String operationResponseName, String complextTypeName, List<Map<String, Object>> wsdlMapSoapList, List<ParameterInfo> outPutParamList, ParameterInfo parent) throws Exception { // 得到返回的参数 List<Node> outPutNodeList = WsdlUtil.getSequenceElementOfComplexType(wsdlDocument, complextTypeName); for (int i = 0; i < outPutNodeList.size(); i++) { Map<String, Object> wsdlMapSoap = new HashMap<String, Object>(); // 组装参数param Node outPutNode = outPutNodeList.get(i); String name = DOMUtil.getNodeName(outPutNode); String type = DOMUtil.getNodeType(outPutNode); ParameterInfo currentParam = new ParameterInfo(); currentParam.setName(name); if (DOMUtil.isDefaultType(outPutNode)) {// 该参数为基本类型 if (DOMUtil.isArray(outPutNode)) {// 数组 currentParam.setType(WsdlUtil.SchemaDefaulyType.type_array.getType()); currentParam.setChildType(type); // 组装映射关系 wsdlMapSoap.put("name", name); wsdlMapSoap.put("index", new Integer(-1)); wsdlMapSoapList.add(wsdlMapSoap); // 得到该数组在返回soap消息中的个数 int arrayLength = getArrayLengthFromResponseSoap(soapDocument, operationResponseName, wsdlMapSoapList); // 从soap消息中取出值 for (int j = 1; j <= arrayLength; j++) { ParameterInfo param = new ParameterInfo(); param.setName(name); param.setType(type); wsdlMapSoap.put("index", new Integer(j)); String value = getValueFromResponseSoap(soapDocument, wsdlMapSoapList, operationResponseName); param.setValue(value); currentParam.addChild(param); } } else {// 不是数组 currentParam.setType(type); // 根据映射关系,从返回的soap消息中取值 wsdlMapSoap.put("name", name); wsdlMapSoap.put("index", new Integer(-1)); wsdlMapSoapList.add(wsdlMapSoap); String value = getValueFromResponseSoap(soapDocument, wsdlMapSoapList, operationResponseName); currentParam.setValue(value); } } else {// 该参数为复杂类型 if (DOMUtil.isArray(outPutNode)) {// 数组 currentParam.setType(WsdlUtil.SchemaDefaulyType.type_array.getType()); currentParam.setChildType(type); // 组装映射关系 wsdlMapSoap.put("name", name); wsdlMapSoap.put("index", new Integer(-1)); wsdlMapSoapList.add(wsdlMapSoap); // 得到该数组在返回soap消息中的个数 int arrayLength = getArrayLengthFromResponseSoap(soapDocument, operationResponseName, wsdlMapSoapList); // 从soap消息中取出值 for (int j = 1; j <= arrayLength; j++) { ParameterInfo param = new ParameterInfo(); param.setType(type); wsdlMapSoap.put("index", new Integer(j)); // 继续查找 getOutPutParam(wsdlDocument, soapDocument, operationResponseName, type, wsdlMapSoapList, outPutParamList, param); currentParam.addChild(param); } } else {// 不是数组 currentParam.setType(type); // 根据映射关系,从返回的soap消息中取值 wsdlMapSoap.put("name", name); wsdlMapSoap.put("index", new Integer(-1)); wsdlMapSoapList.add(wsdlMapSoap); // 继续查找 getOutPutParam(wsdlDocument, soapDocument, operationResponseName, type, wsdlMapSoapList, outPutParamList, currentParam); } } // 增加参数 if (parent == null) { outPutParamList.add(currentParam); } else { parent.addChild(currentParam); } // 在映射关系中除去当前的结点 wsdlMapSoapList.remove(wsdlMapSoapList.size() - 1); } }
- webserviceTest.rar (8.1 MB)
- 下载次数: 1627
评论
15 楼
zouruixin
2014-02-12
API的调用非常好, 节省了我很多调研时间啊, 感谢分享~
14 楼
leelun
2012-11-07
楼主提供的这个工具不错,只是下面这样wsdl的内容,这些代码解析不了。
...... <xs:element name="extension"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" minOccurs="0" name="entry"> <xs:complexType> <xs:sequence> ......
13 楼
黎明的前夕
2012-10-23
黎明的前夕 写道
貌似这个工具不是通用的啊 对有的WSD服务地址不能够解析出来,作者能够给个QQ交流一下吗
12 楼
黎明的前夕
2012-10-23
貌似这个工具不是通用的啊 对有的WSD服务地址不能够解析出来
11 楼
zhaominaaaa
2012-08-22
你的JS好像少了不少呀!不能完整的给出JS吗?
10 楼
xbfxbfxbf
2012-06-27
想问一下
<sequence>
<element ...>
<attribute ...>
...
</sequence>
如果sequence子元素既有element,又有attribute,那么在解析输入输出参数时,是否需要解析attribute这个元素呢?
<sequence>
<element ...>
<attribute ...>
...
</sequence>
如果sequence子元素既有element,又有attribute,那么在解析输入输出参数时,是否需要解析attribute这个元素呢?
9 楼
lgh1117
2012-06-20
你好,能完整的给个代码吗?谢谢!
8 楼
joqk12345
2012-03-19
写的很好,但是你的源码里面的js文件好像不够,能够给提供么?
7 楼
fanglaolaoda
2012-03-01
我的qq是849854893,最近在弄这个,万分感谢
6 楼
fanglaolaoda
2012-03-01
附件中附带页面jsp、js,还有dwr的action,service以及util,我的环境是spring、dwr、ext、jquery。由于整个工具牵扯的比较多,所以没有将完整的可运行的代码整理出来,只将所有核心的代码贴了出来,如果需要运行还需要解决些小问题 ??可以教一下怎么运行起来吗?或者给个完整一点的
5 楼
zheng12tian
2011-11-07
不能设置,http请求没有做你说的相关设置
4 楼
lianshisheng
2011-11-05
非常感谢,我也正在做这一块,我想做的是一个全自动的服务架构(全部WSDL相关数据都存在数据库中,外部传递一些信息过来,程序自动根据数据库中的配置进行Web service的调用),有个问题想问一下你,如果我想在调用某个web service的时候设置超时时间、keep-live参数的话,你这个程序可以支持么?
3 楼
zsx1234567
2011-10-06
问下,假如一个string []={"123","456","789"}的数组转换为ParameterInfo的各个字段的值应该是怎样的?
2 楼
zheng12tian
2011-09-07
说实话,这个东西,不静下心,连我自己都看不大懂.
1 楼
dic_1988
2011-09-06
好复杂哦 看不懂
相关推荐
axis2根据wsdl生成java客户端代码 D:\Software\axis2-1.6.2\bin>wsdl2java.bat -uri http://10.33.30.216:9099/facs/services/ResourceSynchroWebService?wsdl -o E:\wsdloutput -p com.util wsdl2java.bat -uri ...
WebService的WSDL文件生成Java代码工具
使用cxf wsdl2java生成webservice客户端命令
根据WSDL文件生成客户端代码与创建客户端工程 注意小细节:在根据对方提供的webservice地址,先将对方webservice的wsdl文件描述文件保存到本地时,格式先保存为xml,后将其后缀名为.wsdl的文件 否则报:...
根据对方提供的webservice地址,你先将对方webservice的wsdl文件描述文件保存到本地为后缀名为.wsdl的文件,然后保存到Tools的这个文件夹下,编辑WSDL2AxisClient.bat这个文件,将%Java_Cmd% org.apache.axis.wsdl....
Eclipse根据wsdl文件逆向生成webservice客户端项目源码,包括wsdl文件,测试示例,测试webservice代码,包含备注信息
利用wsdl2java工具和SoapUI工具生成webservice的客户端代码 Java实现登陆验证调用 压缩包里包括需要的所有文件,供需要的同学使用 1.apache-cxf-3.3.7 2.SoapUI 5.4.0-EB 3.生成代码的教程 4.获取service调用的...
soapui生成webservice客户端代码,比较详细的讲解了配置,以及生成客户端代码的步骤
通过此方法可以把webservice接口通过接口生成的wsdl文件生成本地调用代码,详细配置可以查看wsdl2_java登入.bat文件,此包原来放在H盘根目录,双击wsdl2_java登入.bat文件即可以生成Create文件夹中的JAVA代码
Java开发生生WebService客户端代码操作步骤 Java开发生生WebService客户端代码操作步骤 Java开发生生WebService客户端代码操作步骤
解决使用wsdl生成java客户端报错:java.lang.reflect.invocationtargetexception的方法之一
Java使用SOAP获取webservice实例解析 具体实例分析说明。
WSDL2Java--根据wsdl生成Java客户端工具
axis1.4生成访问客户端代码
VB.NET(2010)/JAVA 采用SOAP 与Webservice发送/接收数据
详细介绍3种方法根据wsdl逆向生成webservice服务端;有最原始的wsdl2java指令,还有通过soapUI工具以及通过myeclipse的web service project来生成。
利用wsdl的本地文件,或者wsdl的url地址 可秒生成webserice客户端代码。绝对可用!
webservice soap wsdl详解
利用axis jar包 根据wsdl文件生成java webservice 工具 (附带生成后调用方法和详细说明) 及其适合工作着与初学者调试和学习,已经通过测试完全可用
使用axis2 1.6.2 生成webservice wsdl客户端代码,快速便捷,方便操作。使用有问题可留言,如看到尽快回复