对于想了解Webservice的wsdl文件解析与Soap消息的发送、接收(不生成java客户端代码)的读者,本文将是一篇不可错过的文章,我们将详细介绍webservicesoapwsdl,并且为您提
对于想了解Webservice的wsdl文件解析与Soap消息的发送、接收(不生成java客户端代码)的读者,本文将是一篇不可错过的文章,我们将详细介绍webservice soap wsdl,并且为您提供关于.net wsdl.exe 生成java开发的webservice客户端类的时候报错,无法从命名空间获取绑定、cxf发布webservice与java客户端解析webservice、eclipse根据wsdl文件生成webservice客户端、Java 调用C# webservice接口 生成java客户端 实现方式的有价值信息。
本文目录一览:- Webservice的wsdl文件解析与Soap消息的发送、接收(不生成java客户端代码)(webservice soap wsdl)
- .net wsdl.exe 生成java开发的webservice客户端类的时候报错,无法从命名空间获取绑定
- cxf发布webservice与java客户端解析webservice
- eclipse根据wsdl文件生成webservice客户端
- Java 调用C# webservice接口 生成java客户端 实现方式
Webservice的wsdl文件解析与Soap消息的发送、接收(不生成java客户端代码)(webservice soap wsdl)
近段时间,需要为公司的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文件的结构,和各个属性字段
- wsdl:http://www.w3school.com.cn/wsdl/index.asp
- schema:http://www.w3school.com.cn/schema/index.asp
代码讲解:
用于在页面显示方法和方法参数的实体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,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,operationName,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,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,true); } } else { param.setType(name); // 遍历其子结点xs:element getInputParam(inputParamList,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,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,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,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,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,param); } } else { // 组装子结点 if (param.getChildren().size() > 0) { buildSOAPMessage(wsdlDocument,parentNode,param); } } } } }
将返回的soap消息解析成页面参数核心方法
/** * 解析返回的soap消息,然后将结果填充到outPutParamList中 * * @param wsdlDocument * @param soapDocument * @param operationResponseName * @param complextTypeName * @param wsdlMapSoapList * @param outPutParamList * @throws Exception */ public void getoutPutParam(Document wsdlDocument,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,operationResponseName); param.setValue(value); currentParam.addChild(param); } } else {// 不是数组 currentParam.setType(type); // 根据映射关系,从返回的soap消息中取值 wsdlMapSoap.put("name",new Integer(-1)); wsdlMapSoapList.add(wsdlMapSoap); String value = getValueFromresponseSoap(soapDocument,operationResponseName); currentParam.setValue(value); } } else {// 该参数为复杂类型 if (DOMUtil.isArray(outPutNode)) {// 数组 currentParam.setType(WsdlUtil.SchemaDefaulyType.type_array.getType()); currentParam.setChildType(type); // 组装映射关系 wsdlMapSoap.put("name",wsdlMapSoapList); // 从soap消息中取出值 for (int j = 1; j <= arrayLength; j++) { ParameterInfo param = new ParameterInfo(); param.setType(type); wsdlMapSoap.put("index",new Integer(j)); // 继续查找 getoutPutParam(wsdlDocument,type,param); currentParam.addChild(param); } } else {// 不是数组 currentParam.setType(type); // 根据映射关系,从返回的soap消息中取值 wsdlMapSoap.put("name",new Integer(-1)); wsdlMapSoapList.add(wsdlMapSoap); // 继续查找 getoutPutParam(wsdlDocument,currentParam); } } // 增加参数 if (parent == null) { outPutParamList.add(currentParam); } else { parent.addChild(currentParam); } // 在映射关系中除去当前的结点 wsdlMapSoapList.remove(wsdlMapSoapList.size() - 1); } }
.net wsdl.exe 生成java开发的webservice客户端类的时候报错,无法从命名空间获取绑定
这是java jdk开发的webservice地址:
用wsdl.exe生成该wsdl的客户端类的时候报错:
用vs打开wsdl,经观察该服务还有一个文件地址为 http://localhost:8081/MyService/ServiceTest?xsd=1,访问该文件内容并替换到这个报警告的标签中,再通过wsdl.exe生成客户端类就没问题了
另一个可能的报错:
请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称。
这个值改为小写
wsimport 语句:
wsimport -encoding utf-8 -keep -s 输出目录 -p pakagename wsdl目录
其中:
-encoding :指定编码格式
-keep:是否生成Java源文件
-s:指定.java文件的输出目录
-p:定义生成类的包名,不定义的话有默认包名
cxf发布webservice与java客户端解析webservice
cxf发布webservice与java客户端解析webservice
一.服务端发布webservice(CXF,添加cxf所需jar):
1.接口类
package com.god.ws @WebService(targetNamespace="http://webservice.myservice.god.com") public interface IWsPersonInfo { //根据姓名和年龄查询人员信息 public String getPersonInfo(@WebParam(name = "name")String name,@WebParam(name="age")int age); }
2.实现类
package com.god.ws.impl @WebService(endpointInterface = "com.god.ws",targetNamespace="http://webservice.myservice.god.com") public class WsPersonInfoImpl implements IWsPersonInfo { public String getPersonInfo(String NAME,int age){ StringBuilder strXml = new StringBuilder(); strXml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); strXml.append(".......添加人员信息..........."); return strXml.toString(); } }
3.spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:meta-inf/cxf/cxf.xml"/> <import resource="classpath:meta-inf/cxf/cxf-extension-soap.xml"/> <import resource="classpath:meta-inf/cxf/cxf-servlet.xml"/> <jaxws:endpoint id="infoEndpoint" implementor="com.god.ws.impl.WsPersonInfoImpl" address="/PersonInfo"></jaxws:endpoint> </beans>
4.web.xml配置CXF
<servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/webservices/*</url-pattern> </servlet-mapping>
二.客户端解析webservice
// 获取SOAP连接工厂 SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance(); // 从SOAP连接工厂创建SOAP连接对象 SOAPConnection connection = factory.createConnection(); // 获取消息工厂 MessageFactory mFactory = MessageFactory.newInstance(); // 从消息工厂创建SOAP消息对象 SOAPMessage message = mFactory.createMessage(); // 创建SOAPPart对象 SOAPPart part = message.getSOAPPart(); // 创建SOAP信封对象 SOAPEnvelope envelope = part.getEnvelope(); // 创建SOAPHeader对象 SOAPHeader header = message.getSOAPHeader(); // 创建SOAPBody对象 SOAPBody body = envelope.getBody(); // 创建XML的根元素 ,设置查询参数 SOAPHeaderElement headerElementRoot1 = header.addHeaderElement(new QName("http://webservice.myservice.god.com","name","tns")); SOAPHeaderElement headerElementRoot2 = header.addHeaderElement(new QName("http://webservice.myservice.god.com","age","tns")); body.addBodyElement(new QName("http://webservice.myservice.god.com","getPersonInfo","tns")); headerElementRoot1.addTextNode("神仙"); headerElementRoot2.addTextNode("28"); // 访问Web服务地址 SOAPMessage reMessage = connection.call(message,new URL("http://localhost:8080/项目名/webservices/PersonInfo?wsdl")); //strRootXml即为服务端传过来的xml数据 String strRootXml = reMessage.getSOAPPart().getEnvelope().getBody().getTextContent(); connection.close();
eclipse根据wsdl文件生成webservice客户端
现在webservice用的比较多的是xfire和axis,xfire主要是和spring结合来实现,也比较简单,service比较独立,只要在配置文件配置即可,下面说的是用wsdl2java来生成客户端
axis1 生成的是多个文件,有Soap11BindingStub和Soap12BindingStub,还有多个对应的request和response类等
axis2 生成的是两个文件
打开Eclipse,Run-->Open Run Dialog,在Main class框里 输入 WSDL2Java 进行搜索,前提是你的工程里已加入axis的jar包,会搜索到org.apache.axis.wsdl.WSDL2Java,在arguments标 签栏里输入参数,默认基础目录为当前工程,src\\cfg\\test.wsdl -p com.test.outsys.prod.client -t 这是比较简单的生成客户端代码参数,运行就可以,刷新工程,会与src同级的地方出现com.test.outsys.prod.client之前设置的 包名 ,复制到src下,详细参数在下面介绍,如果要生成服务端加入参数-s,生成后修改***Locator.java文件,修改里面 的***HttpSoap11Endpoint_address及****HttpSoap12Endpoint_address为实际使用的地址即可, 在程序里使用时可仿照***TestCase.java里写就可以。
以上介绍的是适合新入手webservice的朋友参考的
-h, --help
print this message and exit
-v, --verbose
print informational messages
-n, --noImports
only generate code for the immediate WSDL document
-O, --timeout <argument>
timeout in seconds (default is 45, specify -1 to disable)
-D, --Debug
print debug information
-W, --noWrapped
turn off support for "wrapped" document/literal
-q, --quiet
do not print any informational or debug messages (except err
ors)
-s, --server-side
emit server-side bindings for web service
-S, --skeletonDeploy <argument>
deploy skeleton (true) or implementation (false) in deploy.w
sdd. Default is false. Assumes --server-side.
-N, --NStoPkg <argument>=<value>
mapping of namespace to package
-f, --fileNStoPkg <argument>
file of NStoPkg mappings (default NStoPkg.properties)
-p, --package <argument>
override all namespace to package mappings, use this package
name instead
-o, --output <argument>
output directory for emitted files
-d, --deployScope <argument>
add scope to deploy.wsdd: "Application", "Request", "Session
"
-t, --testCase
emit junit testcase class for web service
-a, --all
generate code for all elements, even unreferenced ones
-T, --typeMappingVersion <argument>
indicate 1.1 or 1.2. The default is 1.1 (SOAP 1.1 JAX-RPC c
ompliant. 1.2 indicates SOAP 1.1 encoded.)
-F, --factory <argument>
name of a custom class that implements GeneratorFactory inte
rface (for extending Java generation functions)
-H, --helperGen
emits separate Helper classes for meta data
-B, --buildFile
emit Ant Buildfile for web service
-U, --user <argument>
username to access the WSDL-URI
-P, --password <argument>
password to access the WSDL-URI
-X, --classpath
additional classpath elements
-i, --nsInclude <argument>
include namespace in generated code
-x, --nsExclude <argument>
exclude namespace from generated code
-c, --implementationClassName <argument>
custom name of web service implementation
-u, --allowInvalidURL
emit file even if WSDL endpoint URL is not a valid URL
-w, --wrapArrays
Prefers building beans to straight arrays for wrapped XML ar
ray types (defaults to off).Java 调用C# webservice接口 生成java客户端 实现方式







今天关于Webservice的wsdl文件解析与Soap消息的发送、接收(不生成java客户端代码)和webservice soap wsdl的讲解已经结束,谢谢您的阅读,如果想了解更多关于.net wsdl.exe 生成java开发的webservice客户端类的时候报错,无法从命名空间获取绑定、cxf发布webservice与java客户端解析webservice、eclipse根据wsdl文件生成webservice客户端、Java 调用C# webservice接口 生成java客户端 实现方式的相关知识,请在本站搜索。
本文标签: