写在前面:首先完整的内容应该是实现java解析wsdl文档获取方法与参数,然后使用soapui发送soap请求获取返回值并解析,而且基本可以解析主流webservice框架生成的wsdl。但是呢,出于有部分有些商业用途的,所以只提供比较基础的那部分内容,哪怕我算是原作者~~
完整的思路包含三步(代码仅含一二步):
1. 使用wsdl4j解析wsdl,wsdl文档结构推荐参考http://blog.csdn.net/wudouguerwxx/article/details/2036821!
2. 使用DOM解析XML Schema,获取元素名称和类型。
3. 使用soapui发送请求。(其实自己拼接http请求其实也完全没问题的,不过没那么方便罢了)
首先呢,要储备下知识,wsdl文档结构、xml schema等都是必须的,知晓了这些其实离完成代码很近了。
接下去就是上代码了。
用来存储参数的ParamterInfo。
public class ParameterInfo { /** * 名称 */ private String name; /** * 值,仅基本类型会被填入 */ private String value; /** * 类型,类型未空时表示自己定义的complexType */ private String type; /** * 子类型,用于识别array类型下的type,应该是不用担心array嵌套array的,目前我测试的java * webservice框架无法自动生成对应的wsdl文档 */ private String childType; /** * 子结点 */ private List<ParameterInfo> children = new ArrayList(); /** * 我个人建议是加上这个父结点,方便以后回溯用,但本例中上我并未使用到 */ private ParameterInfo parentParam; public ParameterInfo() { } public ParameterInfo(String name, String type) { this.name = name; this.type = type; } public ParameterInfo(String name, String value, String type, String childType, List<ParameterInfo> children) { this.name = name; this.value = value; this.type = type; this.childType = childType; this.children = children; this.parentParam = null; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getValue() { return this.value; } public void setValue(String value) { this.value = value; } public String getType() { return this.type; } public void setType(String type) { this.type = type; } public List<ParameterInfo> getChildren() { return this.children; } public void setChildren(List<ParameterInfo> children) { this.children = children; } public String getChildType() { return this.childType; } public void setChildType(String childType) { this.childType = childType; } public void addChild(ParameterInfo param) { this.children.add(param); } public ParameterInfo getParentParam() { return parentParam; } public void setParentParam(ParameterInfo parentParam) { this.parentParam = parentParam; } }
存储XML Schema类型的类,目前我就写入了些与java相关的类型(就当是偷了点懒)~~
public enum SchemaDefaultType { type_string("string"), type_decimal("decimal"), type_integer("integer"), type_int("int"), type_float("float"), type_long("long"), type_boolean("boolean"), type_time("time"), type_date("date"), type_datetime("datetime"), type_array("array"), type_anyType("anyType"); private String type; private SchemaDefaultType(String type) { this.type = type; } public String getType() { return this.type; } }
稍微说下会用到的方法:
获取wsdl文档中方法的方法
public static void getOperationList(String wsdlUrl, List<String> operationList) throws WSDLException { // 获取wsdl定义 Definition def = getWsdlReader().readWSDL(wsdlUrl); // 遍历bindings Map bindings = def.getBindings(); Iterator<Map.Entry> iterator = bindings.entrySet().iterator(); while (iterator.hasNext()) { Binding binding = (Binding) iterator.next().getValue(); if (binding != null) { List extEles = binding.getExtensibilityElements(); if (extEles != null && extEles.size() > 0) { ExtensibilityElement extensibilityElement = (ExtensibilityElement) extEles.get(0); if (extensibilityElement != null) { String namespaceUri = extensibilityElement.getElementType().getNamespaceURI(); // 默认使用soap1.1的binding,与soapui调用一致 if (WAIXPathConstant.SOAPBINDING11.equals(namespaceUri) || WAIXPathConstant.SOAPBINDING12.equals(namespaceUri)) { List<Operation> operations = binding.getPortType().getOperations(); for (Operation operation : operations) { operationList.add(operation.getName()); } break; } } } } } }
获取对应方法的详细参数和类型的方法
public static List<ParameterInfo> getMethodParams(String wsdlUrl, String operationName) throws WSDLException { Operation operation = getOperationByName(wsdlUrl, operationName); List<ParameterInfo> parameterInfoList = null; if (operation == null) { log.error("can not find operation " + operationName + " , please check again"); throw new RuntimeException("can not find operation " + operationName + " , please check again"); } else { // 输入 Map inputParts = operation.getInput().getMessage().getParts(); parameterInfoList = findParamsByOperation(wsdlUrl, inputParts); } return parameterInfoList; }
至于如何调用,其实因为本身是工具类,只需要main函数直接调用即可,而我在其中也写了示例的test。
最后,提供下完整项目的附件,因为是重新整理的,也就不考虑包的划分了,还望自己划分。补充一句:WA是WangAi的缩写,个人的恶趣味罢了。