项目需求是从远程WS接口获取数据,进行处理后入库,简单讲就是数据汇集,从开发环境调用WS接口一切正常,但部署到服务器上后,频繁出现java.net.SocketException: Connection reset异常,在网上查找后得到的结论如下:
导致“Connectionreset”的原因是服务器端因为某种原因关闭了Connection,而客户端依然在读写数据,此时服务器会返回复位标志“RST”,然后此时客户端就会提示“java.net.SocketException: Connection reset”。(详见http://www.mamicode.com/info-detail-1050916.html)
网上给出的解决方案大体归纳为降低请求频率或优化降低请求次数或者发现错误时多停顿一段时间,在给自己的代码加入线程休眠及重试机制后问题得到了解决。下面给出具体代码:
使用IDEA自带的AXIS1.4根据WSDL生成客户端程序如下:
其中proxy代理类为自建类,实现IReportCommitWS接口。
@Override
public String querySummerRefReprotInfo(String ccsrd) throws RemoteException {
if (iReportCommitWS == null)
_initIReportCommitWSProxy();
String _result = "";
for (int i = 0; i < RETRY; i++) {
try {
_result = iReportCommitWS.querySummerRefReprotInfo(ccsrd);
} catch (Exception e) {
e.printStackTrace();
try {
System.out.println("querySummerRefReprotInfo接口调用失败,5秒后重试");
Thread.currentThread().sleep(5000);
} catch (InterruptedException ie) {
ie.printStackTrace();
continue;
}
continue;
}
if (StrUtils.isNotEmpty(_result)) {
break;
}
}
return _result;
}
for循环中RETRY为自己定义的最大重试次数,循环中TRY-CATCH包裹WS接口调用方法,出现异常则休眠当前线程5秒后进入下一次循环,如果未报异常,返回结果正常则跳出循环,返回结果,如果超过3次重试,则返回空字符。
修改代码后,测试出现java.net.SocketException: Connection reset异常后,5秒后重试即可请求成功,未出现重试同样失败的情况。初步判断出现该异常的原因为服务器网络环境(防火墙、网闸等)导致。
附上_initIReportCommitWSProxy()方法代码
private void _initIReportCommitWSProxy() {
try {
iReportCommitWS = (new ReportCommitWSServiceLocator()).getReportCommitWSPort();
if (iReportCommitWS != null) {
if (_endpoint != null)
((Stub) iReportCommitWS)._setProperty("javax.xml.rpc.service.endpoint.address", _endpoint);
else
_endpoint = (String) ((Stub) iReportCommitWS)._getProperty("javax.xml.rpc.service.endpoint.address");
}
} catch (ServiceException serviceException) {
serviceException.printStackTrace();
}
}