java调用.net写的webserver接口(.asmx后缀)
之前项目上一直调用的是java代码写的接口,方法一直没有问题,这次调用.asmx后缀的.net接口的时候,原来的方法在创建连接的时候就已经出错,百度得到很多答案,在此整理一下。
一、使用axis1.x调用webservice方法
Axis的最常用版本:1.4和2.0版本。以下为1.4版本
1.所需jar包
maven仓库国内镜像地址:https://mvnrepository.com/
2.相关代码
核心代码:
// webserviceURL
// 指出service所在完整的URL String url= "http://xxx/WebService.asmx"; Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(new java.net.URL(url));
// 设置要调用的方法
// http://tempuri.org/是wsdl中definitions根节点的targetNamespace属性值 call.setOperationName(new QName("http://tempuri.org/","addProductRepStage"));
// 该方法需要的参数
call.addParameter("CustNo", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); call.addParameter("passwd", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); call.addParameter("Jobno", org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
// 方法的返回值类型
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING); // call.setUseSOAPAction(true); // call.setSOAPActionURI("http://tempuri.org/addProductRepStage"); // 调用该方法, new Object[] { CustNo, passwd, Jobno}为参数列表 String xmlStr = call.invoke(new Object[] { CustNo, passwd, Jobno}).toString(); } catch (Exception e) { e.printStackTrace(); }
JAVA用这种方式调用webservice,需要注意的地方:
1. 服务器未能识别 HTTP 标头 SOAPAction 的值:
症状一:
Web Service + ASP.NET 应用程序部署到服务器默认目录中,在IE中用http://<服务器地址>/<程序目录名>/<默认启动页面名>发生“服务器未能识别 HTTP 标头 SOAPAction 的值”错误。
症状二:
在Java平台上调用.NET Web Service的服务时,出现"服务器未能识别 HTTP 标头 SOAPAction 的值"。
症状三:
在Java平台下调用.NET WEB Service,出现数据时有时无。
解决对策:
给.NET的WebService类(即.asmx文件下的类)添加属性[SoapDocumentService(RoutingStyle=SoapServiceRoutingStyle.RequestElement)]
小知识:
什么是SoapAction?它在WSDL中有何作用?
SOAPAction HTTP request header被用来标识SOAP HTTP请求的目的地,其值是个URI地址。SOAP发送并不限制格式、URI特征或其必须可解析,那么在这种情况下,发送一个HTTP SOAP请求时,其HTTP客户端必须使用/指明SOAPAction HTTP request header。
SOAPAction header的内容可以被用在服务端,诸如:防火墙适当的过滤基于HTTP的SOAP请求消息等场景。SOAPAction header的值为空串("")表示SOAP消息的目的地由HTTP请求的URI标识;无值则表示没有指定这条消息的目的地。
补充说明:
在.NET环境调用.NET WebService出现 “SOAPAction 值在 XML Web services 的所有方法中不唯一的错误”,也可以通过此法解决。
2. 为了Java能够调用WebService的方法,所以.NET写的WebServiced的每个方法都要声明为Rpc方法,即添加"[SoapRpcMethod.....]".
例如:[WebMethod]
[SoapRpcMethod(Use=SoapBindingUse.Literal,Action= http://tempuri.org/HelloWorld", RequestNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/")]
3. 对返回值、参数的处理上:
应尽量将webservice方法的返回值、参数都写成字符串(String)不要使用复杂对象类型,这样便于在网络上传输。避免了复杂对象类型的不易转换问题。。。对于返回类型是字符串数组型的,可以设置返回类型为org.apache.axis.encoding.XMLType.SOAP_VECTOR或java.lang.String[].class.
二.利用xfire调用WebService
XFire是新一代的Java Web服务引擎,XFire使得在JavaEE应用中发布Web服务变得轻而易举。和其他Web服务引擎相比,XFire的配置非常简单,可以非常容易地和Spring集成,它使得Java开发人员终于可以获得和.Net开发人员一样的开发效率。
核心代码:
Service service = new ObjectServiceFactory().create(IWebservice.class); XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire()); String url= "http://localhost:8080/webservices/services/webservices"; IWebservice iw = (IWebservice) factory.create(service, url); List list=iw.getTest();
完整示例代码:
package avicit.mms.common; import javax.xml.namespace.QName; import org.apache.axis.Constants; import org.apache.axis.client.Call; import org.apache.axis.client.Service; public class Test { public static void main(String[] args) { Textaxis(); } //通过axis方式调用webservice接口 public static void Textaxis() { try { StringBuffer xml = new StringBuffer(); xml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\n"); xml.append("<stages>\n"); xml.append("..."); xml.append("</stages>\n"); // 指出service所在完整的URL String url = "http://127.0.0.1:9080/xxx/WebService.asmx"; //调用接口的targetNamespace //targetNamespace 就是你用浏览器打开url 路径加上?wsdl,即http://xxx/WebService.asmx?wsdl 中的targetNamespace属性值 String targetNamespace = "http://tempuri.org/"; //所调用接口的方法method String method = "addProductRepStage"; // 创建一个服务(service)调用(call) Service service = new Service(); Call call = (Call) service.createCall();// 通过service创建call对象 // 设置service所在URL call.setTargetEndpointAddress(new java.net.URL(url)); //设置要调用的方法 call.setOperationName(new QName(targetNamespace, method)); //设置要返回的数据类型 call.setReturnType(new QName(targetNamespace, method), String.class); call.setUseSOAPAction(true); call.setSOAPActionURI(targetNamespace+method); //变量最好只是用String类型,其他类型会报错,这里的proRepStageInfoXml是.net接口中需要的参数名 call.addParameter(new QName(targetNamespace, "proRepStageInfoXml"), Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);//设置参数名 proRepStageInfoXml 第二个参数表示String类型,第三个参数表示入参 //调用方法并传递参数 String flag = (String) call.invoke(new Object[] {xml.toString()});//此处为数组,有几个变量传几个变量 System.out.println(flag); } catch (Exception e){ e.printStackTrace(); } } }
这两天发现一个问题,所以在此备注一下,Axis的jar包中的axis-wsdl4j-1.5.1和cxf调用接口中要用到的wsdl4j-1.6.2有冲突,版本多少其实不重要,就是两个jar包里面的类差不多,所以如果有高版本的wsdl4j的jar包,就不需要在引axis-wsdl4j-1.5.1的jar包了。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步