关于HttpsURLConnection自动重试导致的请求重复
来源:互联网 发布:c并发编程实战 中文版 编辑:程序博客网 时间:2024/05/21 06:40
[问题描述]
在业务中与第三方对接时,在11秒log显示开始发起请求,24秒接受到请求结果,显示“请求序列号重复,请求失败”。查询log确认这段程序只触发一次,对方给出的日志显示第一次请求11秒接收,14秒给出返回结果,23秒收到同一序列号的请求,给出请求失败的response。
[代码段]
/** * 向指定URL发送POST方法的请求 * * @return URL所代表远程资源的响应 * @throws Exception */ public static String sendPost(String tr1XML, String postUrl, String authString, int timeOutSecond, KeyManager[] keyManagers) throws Exception { log.info("发送tr1报文:{}", tr1XML); ParseXMLUtil parseUtil = new ParseXMLUtil(); OutputStream out = null; String reqData = null; try { HttpsURLConnection conn = (HttpsURLConnection) createConnection(postUrl, authString, timeOutSecond, keyManagers); // 获取URLConnection对象对应的输出流 out = conn.getOutputStream(); //发送请求参数 out.write(tr1XML.getBytes("utf-8")); //flush 输出流的缓冲 out.flush(); //得到服务端返回 InputStream is = conn.getInputStream(); if (is != null && !"".equals(is)) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] receiveBuffer = new byte[2048]; int readBytesSize = is.read(receiveBuffer);//读取数据长度,InputStream要读取的数据长度一定要小于等于缓冲区中的字节数 while (readBytesSize != -1) { bos.write(receiveBuffer, 0, readBytesSize); readBytesSize = is.read(receiveBuffer); } reqData = new String(bos.toByteArray(), "UTF-8"); } log.info("返回tr2报文:{}", reqData); } catch (Exception e) { throw YqgException.wrap(e); } finally { if (out != null) { out.close(); } } return reqData; }
[资料查询]
在网上查询 HttpsURLConnection 相关资料,得知在 conn.getInputStream() 才开始真正发起请求,猜测可能是由于网络超时等原因丢包,发起了两次请求,但是这个过程是发生在底层机制中而不是业务层,所以没有被log记录下。然后同事查到貌似HttpsURLConnection确实有这样的机制(本人英语渣渣,只能附上url
相关资料:
- HttpURLConnection超时处理
- Android (Java) HttpURLConnection silent retry on 'read' timeout - Stack Overflow
[解决]
没法解决。虽然在第二篇文章中有解决办法,但是第一篇中也提到应该在JDk1.5就得到了修复,我们的生产环境是1.8,而且不稳定复现,目前为止就出现了一笔。
所以在同一个同事的建议下,使用okHttp替代HttpsURLConnection。
[修改后的代码段]
........//static段先注册KeyManagerprivate void prepareHttpClient() throws Exception { SSLContext sslContext = SSLContext.getInstance("SSL"); TrustManager[] trustManagers = {new MyX509TrustManager()}; sslContext.init(keyManagers, trustManagers, null); SSLSocketFactory factory = sslContext.getSocketFactory(); client.setSslSocketFactory(factory); client.setConnectTimeout(HttpClient.TIMEOUT_SECOND_60, TimeUnit.SECONDS); client.setReadTimeout(HttpClient.TIMEOUT_SECOND_60, TimeUnit.SECONDS); }private String sendPost(String tr1XML, String postUrl, String authString) throws Exception { log.info("发送tr1报文:{}", tr1XML); String reqData = null; try { String auth = "Basic " + Base64Binrary.encodeBase64Binrary(authString.getBytes()); Response response = HttpClientCommand.syncPostXmlWithAuthorizationOrThrow(client, postUrl, auth, tr1XML); reqData = response.body().string(); log.info("返回tr2报文:{}", reqData); } catch (Exception e) { throw YqgException.wrap(e); } return reqData; }--------------------public static Response syncPostXmlWithAuthorizationOrThrow(OkHttpClient client, String url, String authorization, String request) throws IOException { MediaType mediaType = MediaType.parse("application/xml"); Request httpReq = new Request.Builder() .url(url) .post(RequestBody.create(mediaType, request)) .header("Authorization", authorization) .build(); Response response = doExecute(client, httpReq); LOGGER.info("syncPostRaw: url: {}, response: {}, mediaType: {}", url, response, mediaType); return response; }
阅读全文
0 0
- 关于HttpsURLConnection自动重试导致的请求重复
- 关于Xutils网络请求重试的问题
- nginx重试机制-重新发起请求导致的问题
- 遇到问题---web访问超长时间操作请求时方法会自动运行两次--nginx自动重试导致的post提交两次
- Nginx重试引发Http请求重复执行
- HttpsURLConnection实现SSL的GET/POST请求
- https HttpsURLConnection请求的单向认证
- HttpsURLConnection实现SSL的GET/POST请求
- 关于JAVA发送Https请求(HttpsURLConnection和HttpURLConnection)
- 我的Android进阶之旅------>Android关于HttpsURLConnection一个忽略Https证书是否正确的Https请求工具类
- Java https请求 HttpsURLConnection
- Java https请求 HttpsURLConnection
- JAVA HTTPS请求 HttpsURLConnection
- Part2:Volley请求失败的重试机制
- 关于jquery重复提交请求的原因
- 关于Volley重复请求的问题
- 优雅的repo sync自动重试
- rabbitmq可靠发送的自动重试机制
- Gazebo Error [Node.cc:90] No namespace found
- 网格寻优SVM
- hibernate 注解 映射实体属性不做映射
- Android KEYSTORE文件签名-->JKS文件签名
- 图形视图框架
- 关于HttpsURLConnection自动重试导致的请求重复
- 分布式开放消息系统(RocketMQ)的原理与实践
- 第十篇实训博客
- 机器学习实战第九章ValueError: Masked arrays must be 1-D
- 在github上新建项目
- Android——深入浅出RxJava 和RxAndroid(操作符)
- svg绘制简单流程图
- 免费看VIP视频
- Android组件化初探三(Application共存问题)