Ksoap2调用webservice中连接超时的判断方法(如何判断超时?)

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wkw1125/article/details/48371553

问题背景:


项目中安卓端使用ksoap2调用webservice的函数获取数据。

在服务端发送给客户端的数据里,除了展示给用户的数据之外,还需要包含一些额外的逻辑代码给客户端。

如:

客户端登录一个用户,客户端发送了用户名aaa+密码111给服务端,那么服务端对aaa+111进行验证后,如果成功,也许返回aaa的详细资料(这是数据),还需要返回额外的信息提示客户端是登录成功?还是失败?

以上情况当然可以通过返回值true/false或者是否null来判断,但是,如果更友好一些,比如提示是用户名不存在?还是密码错误?等等。

所以,客户端与服务端交互的不单单是所需数据,而是用一个包含数据的“结果”。


我使用的方法是,自定义一个Result类,包含必要的逻辑标记(如是否成功?如果出错,错误的提示?是否带数据?)和数据。以下是Result类的部分代码,很简单。

服务端与客户端之间的所有的交互数据,都是一个Result对象,读不到这个对象就认为出现错误。(我将Result使用Json格式传送)。

	// 结果类型枚举
	public enum ResultType {
		Error, Success, Failed
	}

	public Result() {
		setValue(null, null, false, null);
	}

	public Result(ResultType type, String messgae, boolean hasReturnData,
			Object[] data) {
		setValue(type, messgae, hasReturnData, data);
	}

	public void setValue(ResultType type, String messgae,
			boolean hasReturnData, Object[] data) {

		this.mType = type == null ? ResultType.Error : type;
		this.mMessage = messgae == null ? "" : messgae;
		this.mhasReturnData = hasReturnData;
		this.mData = data;
	}


如何判断Ksoap2超时?

Ksoap2 某版本之前是不支持超时设定的,有网友通过扩展源码的方式来实现超时。但在我使用的2.6.5版本就已经自带超时功能,具体见:http://www.cnblogs.com/wangsx/p/3393026.html

这不是问题的重点。重点是,在“问题背景”中介绍了C/S交互中对错误类型的判断,但有一种错误还没包括进去:服务器挂了,没有响应。客户端根本就不能从服务器获得任何数据,那还怎么判断是什么类型的错误呢?

这类型的错误我觉得可以分为两种:1、超时(服务器正常,网络情况不好而已) 2、服务器挂了(也可以判断为超时,但是我的项目中要求客户端可以设置连接到的服务器,所以就得判断到底是网络不好?还是当前这台服务器不能用,如IP变了,需要连接另外个服务器?)


网上很多文章说明了如何设置超时,但好像没找到如何判断超时(是超时原因引起的,还是其他原因引起的异常)。下面是我的判断方法:

		HttpTransportSE transport = new HttpTransportSE(serviceUrl, 3000);

		// 获取返回的数据
		SoapObject resultso = null;
		try {
			/* step.5 使用call方法调用WebService方法 */
			transport.call(null, envelope); // 第1个参数一般为null

			/* step.6 使用getResponse方法获得WebService方法的返回结果 */
			if (envelope.getResponse() != null) {
				// 读取soapObject成功
				resultso = (SoapObject) envelope.bodyIn;
				return so2Result(resultso);
			} else {
				resultso = null;
				return Result.getErrorResult("服务器好像出了一点问题   <( ̄3 ̄)> !");
			}
		} catch (Exception e) {
			e.printStackTrace();

			String msg = e.getMessage();
			if (e instanceof java.net.SocketTimeoutException) {
				msg = "连接服务器超时,请检查网络";
			} else if (e instanceof java.net.UnknownHostException) {
				msg = "未知服务器,请检查配置";
			}
			return Result.getErrorResult(msg);

判断方法在catch中,我断点查过捕获的异常e,发现他的cause属性,在我故意使程序出现超时/非法IP的情况时,会呈现SocketTimeoutException 和 UnknownHostException 另种形式,然后使用instanceof 来判断捕获到的异常e是否是他们的实例。


从上图可以看到,e.detailMessage属性显示了错误消息,所以在网上也有看到网友使用e.detailMessage.contain("after 3000ms")这类型的方法来判断是否超时。异曲同工,但我的好一点吧。哈哈哈~~


最后,结合问题背景,我对服务端与客户端之间的交互方法可以总结为:

1、C/S交互通过一个Result类实现,这个类的对象是包含逻辑标记+数据的对象。并且将Result变换为json格式传输字符串,客户端收不到这个对象就认为是出错。

2、服务端发回的结果,包含数据,以及服务端对这次请求的逻辑处理结果(成功or失败。失败的原因等)

      客户端接收到服务端的结果,通过逻辑处理结果来决定表现行为(成功时跳转到详细页展示数据,失败时Toast提示失败)

3、客户端使用ksoap2发起请求,捕获超时异常后,ksoap2返回一个超时类型的Result给客户端自己,来提示超时(或IP错误等无法连接的错误类型)。

这样,该用的提示都有了,在发生错误后用户也知道怎么做。


虽然是很简单的问题,自己想办法解决还是很满足的。加油!


展开阅读全文

没有更多推荐了,返回首页