Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android:HttpURLConnection工作不正常_Java_Android_Httpurlconnection - Fatal编程技术网

Java Android:HttpURLConnection工作不正常

Java Android:HttpURLConnection工作不正常,java,android,httpurlconnection,Java,Android,Httpurlconnection,在通过POST请求发送用户凭证后,我试图从网站上获取cookie,但在android中,这种方式似乎不起作用。我在做坏事吗?。请帮忙。我在这里搜索了不同的帖子,但没有有用的答案 奇怪的是,它在桌面Java实现中运行,工作得很完美,但在Android平台上崩溃了。这与代码完全相同,特别是在调用HttpURLConnection.getHeaderFields()时,其他成员方法也会出现这种情况。这是一个简单的代码,我不知道为什么地狱不工作 桌面代码:这只是主代码() 因此,输出为: log

在通过POST请求发送用户凭证后,我试图从网站上获取cookie,但在android中,这种方式似乎不起作用。我在做坏事吗?。请帮忙。我在这里搜索了不同的帖子,但没有有用的答案

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

桌面代码:这只是主代码()

因此,输出为:

    login_key=20ad8177db4eca3f057c14a64bafc2c9
    FASID=cabf20cc471fcacacdc7dc7e83768880
    track=30c8183e4ebbe8b3a57b583166326c77
    client-data=%7B%22ism%22%3Afalse%2C%22showm%22%3Afalse%2C%22ts%22%3A1349189669%7D
ANDROID代码:它位于doInBackground异步任务体内部

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

在GALAXY NEXUS上测试

可能是由于网络试图在模拟器或手机的移动浏览器中打开您请求的地址。

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

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

我在使用
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); 

它应该对你有用

我已经找出了问题所在。似乎使用Java桌面时,FollowRedirects标志默认为false(我想),而在Android中则为true。getInstanceFollowRedirects在这两种情况下都是正确的,所以我真的不知道为什么它以不同的方式工作,但无论如何,解决方案是完美的

因此,它并没有捕获POST请求的响应,而是遵循一些重定向,并试图从另一个get auto请求获取响应

解决方案是:connection.setInstanceFlowRedirects(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应用程序中的流量,我必须在模拟器中运行它,而不是在手机上运行。结果是:

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.setInstanceFlowRedirects(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}


感谢您的回答和关注。

您可能需要刷新或关闭outputstream?它在finally子句中关闭。正如你所说,我也尝试过刷新,但没有任何效果。我的意思是在阅读标题之前,你是否收到服务器上的请求?我如何检查?通过执行connection.getResponseMessage(),它抛出:10-02 17:56:44.332:W/System.err(5177):java.io.eofexceptions您建议我查看什么?您能在移动浏览器中打开它吗?选中。这是清单中添加的仅有的两个权限。我尝试了几个设置属性的顺序,但似乎这不是原因。
conn.setDoOutput(true)
将方法设置为POST
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}