Android HttpURLConnection 收到 HTTP 301 响应代码

Android HttpURLConnection receives HTTP 301 response code

我正在尝试使用 Android 中的 HttpURL连接 object 执行 HTTP GET。

更新

我尝试连接到不同的服务器。这也托管在 Cloud 9 (c9.io) 中,并且 return 是一个 json 响应。这次我没有 获得 301 重定向,但我得到了服务器应该发送的实际响应。

因为这意味着问题出在服务器内部,我重新组织了以下部分以便集中阅读 server-related 信息。 Android相关信息已移至题末

我连接的地方:

我从哪里连接

Android

的 HTTP 响应

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

HTTP 响应代码是 301 但消息是 null

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

HTTP Header(在 Android 上):

其他数据

  1. 由于服务器似乎希望Android使用HTTPS,我尝试修改代码以使用HTTPS(HttpsURLConnection)。这可能会或可能不会解决 这个 问题,但我无法检查它,因为我收到一个烦人的 SSL handshake failed 错误。另外我不需要在这个应用程序上加密,因此我不愿意解决随之而来的问题。
  2. 这就是 运行AsyncTask object 中的所有内容(因为当您尝试在主线程上使用网络连接时 Android 变得喜怒无常)。
  3. 设置新服务器(在 Cloud 9 之外且没有任何 SSL/TSL)可能是一个选项,但我不愿意这样做,因为这会非常耗时。
  4. 我尝试使用完全相同的代码连接到另一台 Cloud 9 服务器(这也是 return 的一个 json 响应),并且一切正常。这表明问题是由 HTPP 301 错误引起的。

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

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

回复内容好像不完整JSON:

{ 'status':'ERROR'

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

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

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

Http 代码URL连接

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();

删除您用于创建 HttpURLConnection 的代码并尝试使用此代码:

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();
    }    
}

这应该是您需要为您的 GET 请求设置的全部内容。

编辑:

我已经使用 Volley 测试了网络服务,这是我用来检索网络服务响应的代码:

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"}

将协议更改为 https 对我有用。

更改行: HttpURLConnection cxn = (HttpURLConnection) this.getURL().openConnection();

与 : HttpsURLConnection cxn = (HttpsURLConnection) this.getURL().openConnection();

所以你将能够处理 https

我遇到了同样的问题,看了this source后修复了它。
我们需要做的就是处理如下所示的 3** 错误

if(responseCode > 300 && responseCode < 400) {

    String redirectHeader = conn.getHeaderField("Location");
    if(TextUtils.isEmpty(redirectHeader)) {                       
        return new JsonResponse(responseCode, "Failed to redirect");
    }
    JsonRequest newRequest = request;
    newRequest.url = redirectHeader;
    return getJsonFromUrl(newRequest);
}

每个 3** 响应都应该有一个 header,名称为 Location,其中包含我们应该使用的重定向 link。