2012-10-02 92 views
2

我试图通过POST发送用户凭证后从网站获取cookie请求它似乎不能在android中以这种方式工作。我做的事情不好吗?请帮忙。我在这里搜索了不同的帖子,但没有有用的答案。Android:HttpURLConnection无法正常工作

这很奇怪,它运行在桌面Java实现中,它工作的很完美,但在Android平台上崩溃。而且它完全相同的代码,特别是在调用HttpURLConnection.getHeaderFields()时,它也会发生在其他成员方法中。这是一个简单的代码,我不知道为什么地狱不工作。

DESKTOP CODE:这又只是在main()

HttpURLConnection connection = null; 
     OutputStream out = null; 
     try {     
      URL url = new URL("http://www.XXXXXXXX.php");   
      String charset = "UTF-8";  

      String postback = "1"; 
      String user = "XXXXXXXXX"; 
      String password = "XXXXXXXX"; 
      String rememberme = "on"; 
      String query = String.format("postback=%s&user=%s&password=%s&rememberme=%s" 
        , URLEncoder.encode(postback, charset) 
        , URLEncoder.encode(user,charset) 
        , URLEncoder.encode(password, charset) 
        , URLEncoder.encode(rememberme, charset)); 

      connection = (HttpURLConnection)url.openConnection(); 
      connection.setRequestMethod("POST"); 
      connection.setRequestProperty("Accept-Charset", charset); 
      connection.setDoOutput(true);   
      connection.setFixedLengthStreamingMode(query.length()); 

      out = connection.getOutputStream(); 
      out.write(query.getBytes(charset)); 

      if (connection.getHeaderFields() == null){ 
       System.out.println("Header null"); 
      }else{ 
       for (String cookie: connection.getHeaderFields().get("Set-Cookie")){ 
        System.out.println(cookie.split(";", 2)[0]); 
       } 
      } 
     } catch (IOException e){ 
      e.printStackTrace(); 
     } finally { 
      try { out.close();} catch (IOException e) { e.printStackTrace();} 
      connection.disconnect();    
     } 

所以输出:

login_key=20ad8177db4eca3f057c14a64bafc2c9 
    FASID=cabf20cc471fcacacdc7dc7e83768880 
    track=30c8183e4ebbe8b3a57b583166326c77 
    client-data=%7B%22ism%22%3Afalse%2C%22showm%22%3Afalse%2C%22ts%22%3A1349189669%7D 

ANDROID CODE:这又doInBackground的AsyncTask体内

HttpURLConnection connection = null; 
      OutputStream out = null; 
      try {     
       URL url = new URL("http://www.XXXXXXXXXXXXXX.php");   
       String charset = "UTF-8";  

       String postback = "1"; 
       String user = "XXXXXXXXX"; 
       String password = "XXXXXXXX"; 
       String rememberme = "on"; 
       String query = String.format("postback=%s&user=%s&password=%s&rememberme=%s" 
         , URLEncoder.encode(postback, charset) 
         , URLEncoder.encode(user,charset) 
         , URLEncoder.encode(password, charset) 
         , URLEncoder.encode(rememberme, charset)); 

       connection = (HttpURLConnection)url.openConnection(); 
       connection.setRequestMethod("POST"); 
       connection.setRequestProperty("Accept-Charset", charset); 
       connection.setDoOutput(true);   
       connection.setFixedLengthStreamingMode(query.length()); 

       out = connection.getOutputStream(); 
       out.write(query.getBytes(charset)); 

       if (connection.getHeaderFields() == null){ 
        Log.v(TAG, "Header null"); 
       }else{ 
        for (String cookie: connection.getHeaderFields().get("Set-Cookie")){ 
         Log.v(TAG, cookie.split(";", 2)[0]); 
        } 
       } 
      } catch (IOException e){ 
       e.printStackTrace(); 
      } finally { 
       try { out.close();} catch (IOException e) { e.printStackTrace();} 
       connection.disconnect();    
      } 

并且在这里没有输出,看起来connection.getHeaderFields()不返回结果。它需要人至少30秒,以显示日志:

10-02 16:56:25.918: V/class com.giorgi.myproject.activities.HomeActivity(2596): Header null 

测试的银河NEXUS

+0

您可能需要刷新或关闭输出流? – njzk2

+0

它在finally子句中关闭。我也尝试了冲洗,如你所说,但没有任何反应。 – giorgiline

+0

我的意思是在读取标题之前 – njzk2

回答

3

我已经想清楚是什么问题了。 看来,使用Java桌面,标志FollowRedirects默认为false(我想),在Android中它是真的 。 getInstanceFollowRedirects在这两种情况下都是TRUE,所以我不知道它为什么会以不同的方式工作,但没关系,解决方案是完美的。

因此,它没有捕获POST请求的响应,而是在重定向后尝试从另一个GET自动请求获取响应。

解决的办法是要做到:connection.setInstanceFollowRedirects(false);


我能知道这是寻找到网络流量使用网络监控器的方式:

从桌面应用程序也进行了监测该业务:

23 10:08:50 03/10/2012 1.3944670 javaw.exe 192.168.1.36 www.XXXXXXXXX.com HTTP HTTP:Request, POST /es/login.php {HTTP:8, TCP:7, IPv4:6} 
24 10:08:50 03/10/2012 1.3954741 javaw.exe 192.168.1.36 www.XXXXXXXXX.com HTTP HTTP:HTTP Payload, URL: /es/login.php {HTTP:8, TCP:7, IPv4:6} 
32 10:08:50 03/10/2012 1.9811257 javaw.exe www.XXXXXXXXX.com 192.168.1.36 HTTP HTTP:Response, HTTP/1.1, Status: Moved temporarily, URL: /es/login.php {HTTP:8, TCP:7, IPv4:6} 

要监视在Android应用程序的流量,我不得不运行在模拟器代替phone.The结果是:

60 9:59:34 03/10/2012 4.0285909 emulator-arm.exe 192.168.1.36 XX.XX.XXX.XXX HTTP HTTP:Request, POST /es/login.php {HTTP:13, TCP:12, IPv4:11} 
65 9:59:34 03/10/2012 4.1524735 emulator-arm.exe 192.168.1.36 XX.XX.XXX.XXX HTTP HTTP:HTTP Payload, URL: /es/login.php {HTTP:13, TCP:12, IPv4:11} 
75 9:59:35 03/10/2012 4.6276286 emulator-arm.exe XX.XX.XXX.XXX 192.168.1.36 HTTP HTTP:Response, HTTP/1.1, Status: Moved temporarily, URL: /es/login.php {HTTP:13, TCP:12, IPv4:11} 
77 9:59:35 03/10/2012 4.7095994 emulator-arm.exe 192.168.1.36 XX.XX.XXX.XXX HTTP HTTP:Request, GET /es/login.php, Query:FASID=a5e39f35325499e060f43d35bc956a45 {HTTP:13, TCP:12, IPv4:11} 
311 9:59:55 03/10/2012 24.8355823 emulator-arm.exe XX.XX.XXX.XXX 192.168.1.36 HTTP HTTP:Response, HTTP/1.1, Status: Moved temporarily, URL: /es/login.php {HTTP:13, TCP:12, IPv4:11} 
313 9:59:55 03/10/2012 24.9384843 emulator-arm.exe 192.168.1.36 XX.XX.XXX.XXX HTTP HTTP:Request, GET /es/main.html, Query:FASID=a5e39f35325499e060f43d35bc956a45 {HTTP:13, TCP:12, IPv4:11} 
317 9:59:55 03/10/2012 25.0535818 emulator-arm.exe XX.XX.XXX.XXX 192.168.1.36 HTTP HTTP:HTTP Payload, URL: /es/main.html {HTTP:13, TCP:12, IPv4:11} 

因此,应用**connection.setInstanceFollowRedirects(false);**结果后的预期:

61 10:30:43 03/10/2012 4.9211205 emulator-arm.exe 192.168.1.36 XX.XX.XXX.XXX HTTP HTTP:Request, POST /es/login.php {HTTP:14, TCP:13, IPv4:12} 
64 10:30:43 03/10/2012 5.0362501 emulator-arm.exe 192.168.1.36 XX.XX.XXX.XXX HTTP HTTP:HTTP Payload, URL: /es/login.php {HTTP:14, TCP:13, IPv4:12} 
70 10:30:43 03/10/2012 5.5103384 emulator-arm.exe XX.XX.XXX.XXX 192.168.1.36 HTTP HTTP:Response, HTTP/1.1, Status: Moved temporarily, URL: /es/login.php {HTTP:14, TCP:13, IPv4:12} 

感谢您对所有的答案和兴趣。

0

这可能是一些与网络试图打开您在模拟器或手机的移动浏览器所请求的地址。

+0

那么你会推荐我去看看? – giorgiline

+0

你可以在手机浏览器中打开它吗? –

+0

是的,它不会重定向到移动网址或任何东西。 – giorgiline

0

确保您已在AndroidManifest.xml文件中添加了所需的权限。

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
+0

已检查。这些是清单中添加的唯一两个权限。 – giorgiline

0

我有很多的麻烦HTTPURLConnection努力了几天后,我发现,设置标题事项的顺序。这是对我有用的东西。

  conn = (HttpURLConnection) url.openConnection(); 
      conn.setRequestMethod("GET"); 
      conn.setRequestProperty("Host", "yoursite.com"); 
      conn.setRequestProperty("Authorization", "Basic " + Base64.encodeToString(toencode, Base64.DEFAULT)); 
      conn.setRequestProperty("Accept-Charset", "UTF-8"); 

      conn.setConnectTimeout (5000) ; 
      conn.setDoOutput(true); 
      conn.setDoInput(true); 

它应该为你工作。

+0

我试过几个设置属性的命令,但它似乎不是原因。 – giorgiline

+3

'conn.setDoOutput(true)'将方法设置为POST –