|
以下是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 但是不知道是不是好用。 |
|
|
加长超时时间,我是这样解决的
|
|