问题背景java代码调用.Net webservice服务

问题描述

                1.java部分【正常情况,无任何问题】:首先在eclipse或者MyEclipse中创建webservice client 项目【创建过程省略,基操】;然后代码调用.Net webservice,代码如下

import com.xxx.xxx.ApiService;

public class Testapi1 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ApiService ase = new ApiService();
		String reqmsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
						+ "<Request>"
						//这里的XML文档内容省略部分,不方便显示
						+ "</Request>";
		String msg = ase.getApiServiceSoap().invoke(reqmsg);
		System.out.print(msg);
	}
}

        2.java部分【

                调用方式:使用axis.jar包进行调用

                异常情况:

                        a.java代码已经请求了,然而.Net webservice服务中收不到任何数据,也没有任何接收的信号,这里表示接口还未连通;

                        b.java代码请求了,.Net webservice能接收到请求的信号,但是请求的 参数中为空或者空字符串】

                先贴上一段原始java代码,此代码能调用,.net webservice接收到请求,却无法收到参数值:

//本段代码为问题代码,代码逻辑没有问题,但是执行后,.net webservice能收到信号,却无法收到参数值





import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;

public class TestClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String reqmsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
				+ "<Request>"
				//XML具体内容不方便显示
				+ "</Request>";
		Test02(reqmsg);
	}
	
	
	private static void Test02(String reqstr) {
		try {
			String wsdlUrl = "http://127.0.0.1:8080/ApiService.asmx?wsdl";
			String methodNamespace = "http://xxx.xxx.com";
			String wsdlMethod = "invoke";
			
			Service service = new Service();
			Call call = (Call) service.createCall();
			call.setTargetEndpointAddress(new URL(wsdlUrl));
			call.setOperationName(new QName(methodNamespace, wsdlMethod));
			//这里请注意,后面会再次提到
			call.addParameter("xmlData", XMLType.XSD_STRING, ParameterMode.IN);
			call.setReturnType(XMLType.XSD_STRING);
			call.setTimeout(30 * 1000);
			// 设置方法中参数的值,获取接口返回结果
			Object result = call.invoke(new Object[] { reqstr});
			System.out.print("返回数据:" + result.toString());
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			System.out.print("创建call异常:" + e.getMessage());
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.print("Url创建异常:" + e.getMessage());
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			System.out.print("返回数据异常:" + e.getMessage());
		}
	}
}

以上就是问题问题描述2,就是本文的主要内容,下面介绍我的处理过程

处理过程

        a.java代码已经请求了,然而.Net webservice服务中收不到任何数据,也没有任何接收的信号,这里表示接口还未连通;此时我在.net 代码中加了两个属性,我放两段代码,第一段为原始代码,第二段为更新后的代码

using CollectService.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;

namespace CollectService
{
    /// <summary>
    /// ApiService 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://xxx.xxx.com")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 
    // [System.Web.Script.Services.ScriptService]
    public class ApiService : System.Web.Services.WebService
    {
        
        /// <summary>
        /// 获取实时数据
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        [WebMethod]
        public string invoke(string xmlData)
        {
            CommonTool.WriteTextRecordByTime("ApiLog", "DataModel.GetResponseXmlContent|接收到数据:" + xmlData);
            
            string res = "SUCCESS";
            return res;
        }
    }
}
using CollectService.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;

namespace CollectService
{
    /// <summary>
    /// ApiService 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://xxx.xxx.com")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    //本条属性就是新加的
    [SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement, Use = SoapBindingUse.Literal)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 
    // [System.Web.Script.Services.ScriptService]
    public class ApiService : System.Web.Services.WebService
    {
        
        /// <summary>
        /// 获取实时数据
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        [WebMethod]
        public string invoke(string xmlData)
        {
            CommonTool.WriteTextRecordByTime("ApiLog", "DataModel.GetResponseXmlContent|接收到数据:" + xmlData);
            string res = "SUCCESS";
            return res;
        }
    }
}

[SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement, Use = SoapBindingUse.Literal)],这一条属性就是新加的,然后用java代码调用,发现能收到请求信号,但是产生了新的问题:参数xmlData为空。

        b.新的问题:.net webservice接收到请求信号,但是没有参数值。

                此时需要在java中更改一段代码,即可解决问题,下面贴上最终的代码例程:

//本段代码为正常代码,最终例程版本

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;

public class TestClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String reqmsg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
				+ "<Request>"
				//XML具体内容不方便显示
				+ "</Request>";
		Test02(reqmsg);
	}
	
	
	private static void Test02(String reqstr) {
		try {
			String wsdlUrl = "http://127.0.0.1:8080/ApiService.asmx?wsdl";
			String methodNamespace = "http://xxx.xxx.com";
			String wsdlMethod = "invoke";
			
			Service service = new Service();
			Call call = (Call) service.createCall();
			call.setTargetEndpointAddress(new URL(wsdlUrl));
			call.setOperationName(new QName(methodNamespace, wsdlMethod));
			//这里请注意,这里就是更新的地方
			call.addParameter(new QName(methodNamespace, "xmlData"), XMLType.XSD_STRING, ParameterMode.IN);
			call.setReturnType(XMLType.XSD_STRING);
			call.setTimeout(30 * 1000);
			// 设置方法中参数的值,获取接口返回结果
			Object result = call.invoke(new Object[] { reqstr});
			System.out.print("返回数据:" + result.toString());
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			System.out.print("创建call异常:" + e.getMessage());
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.print("Url创建异常:" + e.getMessage());
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			System.out.print("返回数据异常:" + e.getMessage());
		}
	}
}

其中注意的一段代码为:call.addParameter(new QName(methodNamespace, "xmlData"), XMLType.XSD_STRING, ParameterMode.IN);

额外解释:QName全称是qualified name,表示合格且有限制 的 名称或者格式。例如:

<A xmlns:xsl="http://XXX">

<xsl:tname>

</xsl:tname>

</A>

第一行:xsl命名空间前缀与命名空间http://XXX相联系

第二行:xsl为名字空间前缀,tname为xml元素名称

可以这样说:xsl:tname就是一个Qname,即xml元素,其中的xsl结合tname产生一个特定的xml元素,起到修饰限定作用。

soap协议传输格式同样合适,数据为xml同样适合。

我的理解是:在参数中限定了xml格式,会更加规范。

以上就是本人此次处理问题的过程,完全是实践真知,一步一步填坑总结出来的。

以上是本人处理此问题的第一种方案,后面的内容为本人根据猜想,处理成功后的第二种方案

以下是本人在上一次处理后,再次查看代码,发现的另外一种方式,当我发现这种方式后,也被自己气到了,真相原来就这一笔画。我贴上关键的代码截图

//此方法为请求失败的代码段
private static void Test02(String reqstr) {
		try {
			String wsdlUrl = "http://127.0.0.1:8080/ApiService.asmx?wsdl";
            //这里的方法命名空间请注意 注意 注意 注意!!!
			String methodNamespace = "http://xxx.xxx.com";
			String wsdlMethod = "invoke";
			
			Service service = new Service();
			Call call = (Call) service.createCall();
			call.setTargetEndpointAddress(new URL(wsdlUrl));
			call.setOperationName(new QName(methodNamespace, wsdlMethod));
			//这里请注意,这里就是更新的地方
			call.addParameter("xmlData", XMLType.XSD_STRING, ParameterMode.IN);
			call.setReturnType(XMLType.XSD_STRING);
			call.setTimeout(30 * 1000);
			// 设置方法中参数的值,获取接口返回结果
			Object result = call.invoke(new Object[] { reqstr});
			System.out.print("返回数据:" + result.toString());
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			System.out.print("创建call异常:" + e.getMessage());
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.print("Url创建异常:" + e.getMessage());
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			System.out.print("返回数据异常:" + e.getMessage());
		}
	}

//此方法为请求成功的代码段
private static void Test02(String reqstr) {
		try {
			String wsdlUrl = "http://127.0.0.1:8080/ApiService.asmx?wsdl";
            //这里的方法命名空间请注意 注意 注意 注意!!!
			String methodNamespace = "http://xxx.xxx.com/";
			String wsdlMethod = "invoke";
			
			Service service = new Service();
			Call call = (Call) service.createCall();
			call.setTargetEndpointAddress(new URL(wsdlUrl));
			call.setOperationName(new QName(methodNamespace, wsdlMethod));
			
			call.addParameter("xmlData", XMLType.XSD_STRING, ParameterMode.IN);
			call.setReturnType(XMLType.XSD_STRING);
			call.setTimeout(30 * 1000);
			// 设置方法中参数的值,获取接口返回结果
			Object result = call.invoke(new Object[] { reqstr});
			System.out.print("返回数据:" + result.toString());
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			System.out.print("创建call异常:" + e.getMessage());
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.print("Url创建异常:" + e.getMessage());
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			System.out.print("返回数据异常:" + e.getMessage());
		}
	}

可以看到,上述就一笔只差。

请求失败的方法会报错如下图

java 项目垮包引用报错_myeclipse

 正确的方法只是将命名空间加上一笔;当然,只是这样的话,可能在.Net webservice中依然获取不到参数,这个时候只需要在.Net webservice中每个接口方法加上:[SoapRpcMethod(Use = SoapBindingUse.Literal, Action = "http://XXX.XXX.com/invoke", RequestNamespace = "http://XXX.XXX.com/", ResponseNamespace = "http://XXX.XXX.com/")]即可。

第二种解决方案为:

                                1.java代码的命名空间填写完整,最后那一个字符 “/” 不能少。上面代码已经很详细了。

                                2..Net webservice中,接口的那个类上面添加属性如下图

java 项目垮包引用报错_myeclipse_02