旁观者

参与软件开发这些年来,不断地遇到新领域新知识点,屡屡感受到新进入者的迷惑和彷徨,所以对遇到的每一个问题都详细记录问题现象、解决思路以及解决方案,并在blog中留下印迹,以备他日有心人google之而知之。
你们的新手之痛,你们的新业务发展之初的思路混沌,我都感同身受,所以欢迎和我一起探讨这些话题,诸如Semantic/NLP/Mashup/J2ME/IVR/SMS/WAP/Python等,知无不言言无不尽。
posts - 538, comments - 970, trackbacks - 39, articles - 1
   ::  ::  ::  :: 订阅 订阅 :: 管理

[j2me] Nokia S60如何处理302 HTTP状态

历史

Version

Date

Creator

Description

1.0.0.2

2006-7-24

郑昀

第一稿

 

1 Nokia S60如何处理302HTTP状态

 

HttpConnection/302/ HTTP_TEMP_REDIRECT

关键词

详细描述

当用HttpConnection读取远端数据,而远端返回状态码302表示重定向时,继续调用openInputStream来读取输入流将会导致程序崩溃。

 

此种现象发生在以下机型:

Nokia N90/

6600/6630/6680

 

N70不会崩溃但也不会正常运行。

根据协议规定,此时的Location头域中保存了你应该重新请求的地址。

请看

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3 来了解更多关于"302 Found"

 

也就是说,此时用HttpConnection.getHeaderField("Location")来得到具体的跳转url,然后重新向新地址发起请求。

 

代码示范:

 

private HttpConnection open(String url) throws IOException {

HttpConnection c;

int status = -1;

 

// Open the connection and check for redirects

while (true) {

c = (HttpConnection) Connector.open(url);

 

// Get the status code,

// causing the connection to be made

status = c.getResponseCode();

 

if ((status == HttpConnection.HTTP_TEMP_REDIRECT)

|| (status == HttpConnection.HTTP_MOVED_TEMP)

|| (status == HttpConnection.HTTP_MOVED_PERM)) {

 

// Get the new location and close the connection

url = c.getHeaderField("location");

c.close();

} else {

break;

}

}

 

// Only HTTP_OK (200) means the content is returned.

if (status != HttpConnection.HTTP_OK) {

c.close();

throw new IOException("Response status not OK");

}

return c;

}

 

 

参考资料1RFC2616

10.3.3 302 Found

The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.

The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).

If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

      Note: RFC 1945 and RFC 2068 specify that the client is not allowed
      to change the method on the redirected request.  However, most
      existing user agent implementations treat 302 as if it were a 303
      response, performing a GET on the Location field-value regardless
      of the original request method. The status codes 303 and 307 have
      been added for servers that wish to make unambiguously clear which
      kind of reaction is expected of the client.

 

参考资料2Nokia Forum

KVM crashes when reading content with HTTP "302 Found" response on N90 and 6680

Feedback

#1楼[楼主]  回复 引用 查看   

2006-07-25 15:19 by 让变化成为计划的一部分      
13:52 dabaohe: 我想跟你讨论一下J2ME中处理Http302的问题,你有空吗?
13:53 我: 那我建议你还是用ieHTTPHeaders v1.5工具看看
能看到http headers的各种字段。
这样,你就明白到底跳转地址填写在了哪里。
肯定是有一个字段保存的。否则浏览器如何得知如何跳转。
13:54 dabaohe: 呵呵,我自己写了一个Java程序, 用Http-Client实现的联网,完全可以正确的解析出Location这个字段。
用HttpAnalyser
也测试过,也是可以看到
13:55 我: 那为什么在httpconnection中拿不到这个字段呢?
dabaohe: 但是到了手机上就不行了,调用HttpConnection.getHeaderField("Location")返回空
我尝试把Location换成小写location,也不行。
13:56 另外我尝试通过HttpConnection.getHeaderField(int n) 来读取从0-10000内所有的Field都为空。
13:57 这个问题只在手机上出现,具体是我帖子上详细写的那几个机型。
我: 那你可不可以写一个php页面
13:58 <?php
header('Location: http://www.forum.nokia.com/' );
echo 'plop';
?>
放在你的服务器上
然后你来请求。
看看如此明确地填写了location,手机端是否还拿不到?
dabaohe: 这个我也尝试过,我们自己的服务器就是这样的,很简单的页面,结果一样。
我: 你用cmnet和cmwap都不行吗?
dabaohe: 我们服务器端就是php的页面,跳转也一样。
13:59 我: 那就真的奇怪了。看来不是服务器的事情。
dabaohe: Nokia6600 Symbian 60 v2.0中用wap网关方式连接时出现
Nokia6630 Symbian 60 v3.0中用直连和wap网关的方式都会出现
s40 v2.0和索爱下一切正常
能给点线索不?
我: 我得想想。提一个建议:
dabaohe: 嗯,说吧。
我: 如果真地解决不了,那是不是可以让你的nokia S60请求你的一个php页面,其实这个页面自己请求远端第三方页面,也就是说,让
14:04 你的页面来负责redirect。
等你的页面拿到了真正的数据后,再送给你的手机。
这样,就不用手机端来处理302了。
你看呢?
因为OperaMini绝对能够处理redirect的页面。
14:05 所以我们可以猜测他也许是在服务器端悄悄处理的
而不是像我们原来猜测的那样,是在手机端处理的。
dabaohe: 这个建议我们也曾经考虑过,但很多请求是无法转发到服务器端去处理的,例如梦网的页面。
14:06 我: 好吧。
14:09 dabaohe: 我曾经试过在6600上用Socket连到10.0.0.172,然后模仿HTTP去请求网页,在返回流中很清晰的找到了Location,但这招有点损,一方面40很多不支持Socket另一方面60 Symbian 3.0连Socket的80端口需要把jar包认证才行,这个太麻烦了。

14:36 我: "
以前我们尝试改了content-type的内容,加入一些自定义串,在模拟器上没有问题
但在手机上,wap网关又会自己更改了我们的content-type的值
我觉得wap网关只会去取http的数据,但http头他都会重新封装一遍,所以尽量不要用更多的http头来传输协议"
dabaohe: Nokia6630非常典型,无论如何不行。
wap.3gtb.com
郑昀: 如果我这么说,你是否同意:“但如果说S40能拿到Location字段,S60第二版不能,那确实S60 v2.0的KVM有点BUG了。”
dabaohe: 嗯,我考虑是这样,wap网关那边可能对header动了一点手脚,加上S60KVM上有点小BUG,导致了目前这个问题。
郑昀: 你可以到nokia社区里问管理员这是不是一个BUG
如果是,看来你需要绕道走了。
1:尽量不要出现跳转。
dabaohe: 嗯,也只能这样了,呵呵
郑昀: 2:如果实在要跳转,可以在服务器端预先用自己的页面接住;
3:如果是梦网页面,那就。。。惨了。。可以不请求。

#2楼  回复 引用   

2006-10-13 18:03 by 林子[匿名][未注册用户]
我也遇到了此类问题,不过我想在J2EE中写代码解决,因为本人不是很懂J2ME,部分代码如下:
URL url=new URL("http://www.sisdown.com/Soft/ShowSoftDown.asp?UrlID=1&SoftID=6913");//创建URL
URLConnection urlconn=url.openConnection();
HttpURLConnection httpconn=(HttpURLConnection)urlconn;
urlconn.connect();
httpconn.setRequestMethod("GET");
httpconn.setFollowRedirects(false);//无需跳转
//httpconn.getInstanceFollowRedirects()
//httpconn.connect();
int code=httpconn.getResponseCode();
不知为什么得到的code总是200,但实际上应是302的.接下的代码就无法正确运行,各位高人帮小妹指点一下.期待中,谢谢

#3楼  回复 引用   

2007-10-20 09:32 by bruddy[未注册用户]
我也与到这个问题,得到响应码为302,但是读取"location"的头参数为null

#4楼  回复 引用   

2008-01-24 20:17 by 布老虎[未注册用户]
哈,太巧了,没想到这次帮我解决问题的贴子又是您发出的。。
我习惯在google上搜索解答,结果又找到你了。google真的很伟大,而我和你似乎很有缘!嘿嘿~~~
祝你的事业越办越好!

#5楼[楼主]  回复 引用 查看   

2008-01-24 22:35 by 旁观者      
为什么是“又”呢?