以下是android发送Http请求的代码,但是经常出现:服务器响应很久, android端出现ReadTimeout, android端又会再发一次同样的请求,导致数据重复。有人说是jdk1.4.2的问题,但我用的是1.6.0。请大神们帮忙 URL url = null; HttpURLConnection conn = null; String result = ""; try { String sParam = "&m=" + methodName; if (vector != null) { for (int i = 0; i < vector.size(); i++) { sParam += "&p" + String.valueOf(i) + "=" + vector.elementAt(i).toString(); } } byte[] data = sParam.getBytes(); url = new URL(realURL.replace("xx.mobile", methodName+".mobile")); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(CONNECT_TIMEOUT); conn.setReadTimeout(READ_TIMEOUT); conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestMethod(METHOD_POST); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", String.valueOf(data.length)); conn.setRequestProperty("Charset", "utf-8"); conn.setUseCaches(false); OutputStream outStream = conn.getOutputStream(); outStream.write(data); outStream.flush(); outStream.close(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) // ResponseCode:200 { InputStream inStream = conn.getInputStream(); //int contentLen = conn.getContentLength(); result = readInputStream(inStream,1024); inStream.close(); } else { result = "500"; //server error } } catch (ConnectTimeoutException e) { // TODO: handle exception CommonData.Log("ConnectTimeoutException"); throw new MyException(HTTP_RESULT_CONNECT_TIMEOUT); } catch (SocketTimeoutException e) { // TODO: handle exception CommonData.Log("SocketTimeoutException"); throw new MyException(HTTP_RESULT_READ_TIMEOUT); } catch (Exception e) { // TODO: handle exception CommonData.Log(e.getLocalizedMessage()); throw new MyException(HTTP_RESULT_EXCEPTION); } finally { conn.disconnect(); } |
|
我觉得不太可能重复发送请求
除非你的代码调用有问题,或者你的请求放在了service里面,service重复执行导致的。 |
|
没有放service里,用的AsyncTask。 看下下面的文章,说是jdk1.4.2的bug,但是我用的是1.6.6,谢谢 |
|
conn.setRequestProperty(“Connection”,?”Keep-Alive”); 这个去掉看看。
|
|
有试过,还是 一样 |
|
加入log 看看你这段代码是不是执行了两次
而且你还要看看你测试时android的版本 |
|
只有调一次,有打Log, android 4.3 sansung note3. 华为荣耀四核 android4.2都会出现这样的情况。 |
|
来人啊,帮忙啊
|
|
10分 |
尝试用 httpclient 吧
看不出什么问题,属于疑难杂症吧 |
Android我已经换成HttpClient,有设置HttpRequestRetryHandler为false,就不会出现重发的现象. |
|
大牛们啊,帮忙啊
|
|
10分 |
底层的实现中 如果发现http请求超时 有重发机制
|
网络抓包吧 , 看有没有发送出去
|
|
请问,这个有资料可查吗?如何能禁用呢? |
|
有发出去. |
|
以前在一个人的blog中看到的,现在找不到了 |
|
麻烦帮忙找下,万分感谢。 |
|
10分 |
原来那个找不到了 你看看这个 意思类似 |
谢谢。但是他说是jdk1.4.2的bug,可是我用的是jdk1.6.0,还是会出现这个重发的问题 |
|
来人啊,帮忙啊
|
|
10分 |
http://developer.nokia.com/community/wiki/Using_HTTP_and_HTTPS_in_Java_ME
这个你看下 还有你的j2me 中的相关代码 也请po出来, 前面的是 android中的代码。 |
谢谢你的回复。看了上面的帖子,还是没得到有用的信息。下面我就贴出j2me的代码。 |
|
以下是J2ME 发送http请求的代码,如果超过一定时间服务器没有响应,j2me就会重发一次相同的请求
private class RunHttpRequest implements Runnable { private HttpConnection conn = null; private OutputStream os = null; private InputStream is = null; private ByteArrayOutputStream baos = null; private DataOutputStream dos = null; private String result; private String url; private String method; private Vector ps; public RunHttpRequest(String url, String method, Vector ps) { this.url = url; this.method = method; this.ps = ps; } public void run() { try { String sParam = "&m=" + method; for (int i = 0; i < ps.size(); i++) { sParam += "&p" + String.valueOf(i) + "=" + ps.elementAt(i).toString(); } conn = (HttpConnection) Connector.open(url, Connector.READ_WRITE); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", Integer.toString(sParam.length())); conn.setRequestProperty("Charset", "utf-8"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Content-Language", "en-US"); conn.setRequestMethod(HttpConnection.POST); os = conn.openDataOutputStream(); //sParam = URLEncoder.encode(sParam,"UTF-8"); os.write(sParam.getBytes()); os.flush(); int respCode = conn.getResponseCode(); if (respCode == HttpConnection.HTTP_OK) { is = conn.openDataInputStream(); int contentLen = (int)conn.getLength(); if(contentLen>0){ byte[] b = new byte[contentLen]; int len = 0; baos = new ByteArrayOutputStream(); dos = new DataOutputStream(baos); while ((len = is.read(b)) != -1) { dos.write(b, 0, len); } byte[] bytes = baos.toByteArray(); result = new String(bytes, "utf-8"); result = StringUtil.replaceString(result, "\r\n", "\n"); } } else if(respCode == HttpConnection.HTTP_MOVED_TEMP){ //当用户从其它地方登录时,服务器URL发生转向. result = HTTP_RESULT_MOVED_TEMP; } else { result = HTTP_RESULT_SERVER_ERROR; } } catch (Exception e) { result = HTTP_RESULT_EXCEPTION; MainMidlet.perferences.setRecord_Log(CommonData.KEY_LOGINFO,("Exception-"+e.getMessage()).getBytes()); } finally { close(); } } /** * @return the result */ public String getResult() { return result; } public void close() { try { if (conn != null) { conn.close(); conn = null; } if (os!=null){ os.close(); os = null; } if (is != null) { is.close(); is = null; } if (baos != null) { baos.close(); baos = null; } if (dos != null) { dos.close(); dos = null; } } catch (IOException ex) { ex.printStackTrace(); } } } |
|
1 关闭的顺序 不知道有没有关系 应该是先输入输出流 然后才是connect。
2 你看下能否查看源代码,然后找到这个重发的相关设置的位置,利用java反射机制关掉它。 |
|
1.顺序应该没有关系吧,我试试看。 |
|
50分 |
1:
http://bugs.java.com/view_bug.do?bug_id=6672144 这里面描述的 bug 和你说的很像。 它的解决方案是设置系统属性。 2: 这个完全是你说的案例。它的建议是后台参与进来 |
你应该试下jdk 1.7 如果1.7没有这个现象 那就是jdk1.6也存在这个bug 如果jdk1.7不存在这个问题 那就是你自己代码问题 |
|
非常感谢你的回复。对于这个问题,在前端还是没有什么办法解决吗? 还是只能通过后台来过滤…. |
|
顶顶顶,还有没有别的办法啊
|
|
顶顶顶,求大神啊
|
|
连接超时和读取超时时间会不会不一致?
|
|
这2者不一致有关系吗? |
|
10分 |
如果连接还没有超时,而读取时间超时的话,HttpUrlConnection就会再重新发送请求。所以,要解决这个重发问题,可以试一下,把读取超时的时间设置得比连接超时稍长一点,因为有时候,jdk计算的时间会有点偏差,这样可以保证在连接超时之前不会读取超时 |
楼主,我也碰到这个问题了。请问这个问题解决了吗
|
|
楼主,我也碰到这个问题了。请问这个问题解决了吗???
|
|
你的是什么问题 |
|
你什么问题 |
|
我这边用HttpUrlConnection上传文件,在服务器超时后,客户端已经捕获到SocketTimeOut,并在界面显示发送失败,但底层的协议又会去重发请求,而且重发又成功了,导致客户端显示的是失败,而服务器已经收到数据了。 |
|
底层如果动不了,考虑应用层解决,后台这边通过接收时长来判断是否重复发送的请求进行过滤操作。
|
|
我也遇到这个问题了,网上搜到的
http://blog.sina.com.cn/s/blog_8d76e0ed0101l1eh.html 但是不知道是不是好用。 |
|
加长超时时间,我是这样解决的
|