Android HttpURLConnection接收HTTP 301响应代码 [英] Android HttpURLConnection receives HTTP 301 response code

查看:1569
本文介绍了Android HttpURLConnection接收HTTP 301响应代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Android中的HttpURLConnection对象执行HTTP GET。

I'm trying to do a HTTP GET using the HttpURLConnection object in Android.

更新

我尝试连接到其他服务器。它也托管在Cloud 9(c9.io)中,并返回json响应。这次我获得301重定向,但我得到了服务器应该发送的实际响应。

I tried connection to a different server. This is also hosted within Cloud 9 (c9.io) and also returns a json response. This time I'm not getting a 301 redirect, but I am getting the actual response the server is supposed to send.

因为这意味着问题已在服务器中本地化,我重新组织了以下部分,以便将阅读重点放在与服务器相关的信息上。 Android相关信息已移至问题末尾。

Since this means the problem is localised within the server, I've reorganized the following sections in order to focus reading onto the server-related information. Android related information has been moved to the end of the question.

我要连接的地方:


  • Cloud9上的开发服务器

  • 使用Laravel Framework 5.2(由于项目依赖性不受支持,我们目前无法升级到5.3)

  • 服务器应返回JSON答案

  • 如果我通过浏览器连接到同一个URL,我会得到正确的响应(JSON字符串。必需的HTTP标头和'200'HTTP响应代码)

  • Development server on Cloud9
  • Using the Laravel Framework 5.2 (we cannot upgrade to 5.3 at this time, due to unsupported project dependencies)
  • The server should return a JSON answer
  • If I connect to the same URL through the browser I get the correct response (JSON string. Required HTTP Headers and a '200' HTTP Response Code)

我在哪里连接FROM


  • Android手机(Oneplus 3,在Android 6.0上)

  • 编译SDK版本:23

  • 使用构建工具:23.0.3

  • 使用Min SDK版本:19

  • 使用Target SDK版本:22

  • 我使用HttpURLConnection对象连接,使用HTTP方法'GET'

  • Android phone (Oneplus 3, on Android 6.0)
  • Compile SDK version: 23
  • Using Build Tools: "23.0.3"
  • Using Min SDK verion: 19
  • Using Target SDK version: 22
  • I'm connectiong using a HttpURLConnection object, using HTTP Method 'GET'

HTTP响应的Android

当我运行我的代码时,我从服务器得到了结果:

When I run my code I get the folling result from the server:

HTTP响应代码是 301 但邮件是 null

The HTTP response code is 301 but the message is null.


  1. 新网址完全相同,但使用的是HTTPS。似乎服务器以某种方式强制SSL / TSL加密。从浏览器访问HTTP时会发生

  1. The new URL is exactly the same, but using HTTPS. It seems server is somehow forcing SSL/TSL encryption. Which does not happen when accessing HTTP from the browser.

HTTP标头(在Android上):

HTTP Header (on Android):


  • date =>星期二,2016年10月4日05:56:26 GMT

  • location => https://domain.com/route/ (我对此进行了修改)

  • content-length => 382

  • content-type => text / html; charset = iso-8859-1

  • X-BACKEND => apps-proxy

  • X-Android-Selected-Protocol => http / 1.1

  • X-Android-Sent-Millis => 1475560583894

  • X-Android-Received-Millis => 1475560585637

  • X-Android-Response-Source => NETWORK 301

  • null => HTTP / 1.1 301

  • date => Tue, 04 Oct 2016 05:56:26 GMT
  • location => https://domain.com/route/ (I modified this bit)
  • content-length => 382
  • content-type => text/html; charset=iso-8859-1
  • X-BACKEND => apps-proxy
  • X-Android-Selected-Protocol => http/1.1
  • X-Android-Sent-Millis => 1475560583894
  • X-Android-Received-Millis => 1475560585637
  • X-Android-Response-Source => NETWORK 301
  • null => HTTP/1.1 301

其他数据


  1. 由于服务器似乎希望Android使用HTTPS,我尝试修改代码使用HTTPS(HttpsURLConnection)。这可能会或可能不会解决问题,但我无法检查它,因为我收到恼人的 SSL握手失败错误。此外,我不需要对此应用程序进行加密,因此我不愿意解决随之而来的问题。

  2. 这一切都在AsyncTask对象中运行(因为Android会变得情绪化您尝试在主线程上使用网络连接。)

  3. 设置新服务器(在Cloud 9之外,没有任何SSL / TSL)可能是一个选项,但我是不愿意这样做,因为它会非常耗时。

  4. 我尝试使用完全相同的代码连接到另一台Cloud 9服务器(也返回json响应),一切正常。这表明问题源自HTPP 301错误。

  1. Since it seems the server wants Android to use HTTPS, I tried modifying the code to use HTTPS (HttpsURLConnection). This may or may not solve this problem, but I am unable to check it since I get an annoying SSL handshake failed error. Plus I have no need for encryption on this application, and therefore I'm reluctant to solve the problems coming with it.
  2. This is all running within an AsyncTask object (since Android get moody when you try to use a network connection on the main thread).
  3. Setting up a new server (outside of Cloud 9 and without any SSL/TSL) could be an option, but I'm reluctant to do this since it would be quite time consuming.
  4. I tried connecting to another Cloud 9 server (which also returns a json response), using the exact same code, and everything works correctly. This suggests that the problem arises from the HTPP 301 error.

我将尝试与您分享您可能需要回答的任何其他信息我的问题!

I will try to share with you any other information you may require to answer my question!

原生Android内容(在更新时移动,见上文)

响应内容似乎不完整 JSON:

The response content seems to be an incomplete JSON:

{ 'status':'ERROR'

注意我没有忘记收盘} 字符,这就是响应实际包含的内容。在工作流程中,这是注入某个未知的(对我而言)。当我捕获HTTP响应时(在我的PC上使用Charles,它被设置为我手机的Wi-Fi连接的代理),它的内容是(如预期的那样)一个简单的HTML,告诉您将(HTPP代码301)重定向到新路由。

Note I did NOT forget the closing } character, that's what the response actually containts. This is injected somewhere unknown (to me) during the workflow. When I capture the HTTP response (using Charles on my PC, which is set as a Proxy for my phone's Wi-Fi connection) it's content is (as expected) a simple HTML telling you to redirect (HTPP code 301) to a new route.

无效的JSON代码(上图)不存在,但有效 HTML是。

The invalid JSON code (above) isn't there, but a valid HTML is.

这表明无效的JSON出现在我的代码内部(不在服务器或传输上)。但我的应用程序上没有生成JSON字符串的代码,更不用说将其注入我正在处理的响应中。

This would suggest that the invalid JSON appears somewhere internally to my code (not on the server, or transport). But there is no code on my app that generates a JSON string, let alone inject it into the response I'm processing.

HttpURLConnection的代码

this.setURL(ruta); //gets correct url
HttpURLConnection cxn = (HttpURLConnection) this.getURL().openConnection(); //init
cxn.setRequestMethod("GET"); //use HTTP GET verb
cxn.setUseCaches(false); //no cache
cxn.setRequestProperty("Cache-Control", "no-cache"); //even less cache
cxn.setDoOutput(false); //only true in POST/PUT requests
cxn.setRequestProperty("Connection","keep-alive");
cxn.setRequestProperty("DNT", "1"); //TEMP
cxn.setInstanceFollowRedirects(true); //should follow redirects
cxn.setRequestProperty( "charset", "utf-8");

读取结果的代码

int status_code = cxn.getResponseCode();
InputStream responseStream = new BufferedInputStream(cxn.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null) {
    stringBuilder.append(line).append("\n");
}
responseStreamReader.close();
String response = stringBuilder.toString();
cxn.disconnect();


推荐答案

删除用于创建<的代码code> HttpURLConnection 并试试这个:

Remove the code you've used to create the HttpURLConnection and try with this one:

URL url;
HttpURLConnection urlConnection = null;
try {
    url = new URL("http://www.domain.com/index.aspx?parameter1=X&parameter2=X"); //Use your url and add the GET parameters

    urlConnection = (HttpURLConnection) url.openConnection();

    urlConnection.setInstanceFollowRedirects(false); /* added line */

    InputStream in = urlConnection.getInputStream();

    InputStreamReader isw = new InputStreamReader(in);

    int data = isw.read();
    while (data != -1) {
        char current = (char) data;
        data = isw.read();
        System.out.print(current);
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if (urlConnection != null) {
        urlConnection.disconnect();
    }    
}

这应该是你需要设置的所有获取请求。

This should be all you need to set for your GET request.

编辑:

我使用 Volley 测试了网络服务,这里是代码I用于检索Web服务响应:

I've tested the webservice using Volley, here's the code I've used in order to retrieve the webservice response:

public class MainActivity extends AppCompatActivity {

  public String response;
  TextView textView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView = (TextView) findViewById(R.id.rTextView);

    RequestQueue queue = Volley.newRequestQueue(this);
    String url = "yourWebserviceUrl";

    // Request a string response from the provided URL. 
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
      new Response.Listener < String > () {
        @Override
        public void onResponse(String response) {
          textView.setText("Response is: " + response);
        }
      }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
          textView.setText("That didn't work!");
        }
      });
    // Add the request to the RequestQueue. 
    queue.add(stringRequest);

  }

}

这是我收到的回复:

{"status":"ok","found":false,"extra":"App\\Scanners"}

这篇关于Android HttpURLConnection接收HTTP 301响应代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆