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相关信息已移至题末
我连接的地方:
- Cloud9 上的开发服务器
- 使用 Laravel Framework 5.2(由于项目依赖项不受支持,我们目前无法升级到 5.3)
- 服务器应该return一个JSON回答
- 如果我通过浏览器连接到同一个 URL,我会得到正确的响应(JSON 字符串。需要 HTTP Headers 和“200”HTTP 响应代码)
我从哪里连接
- Android phone(Oneplus 3,在 Android 6.0 上)
- 编译SDK版本:23
- 使用构建工具:“23.0.3”
- 使用 Min SDK 版本:19
- 使用目标 SDK 版本:22
- 我正在使用 HttpURL连接 object,使用 HTTP 方法 'GET'
Android
的 HTTP 响应
当我运行我的代码时,我从服务器得到以下结果:
HTTP 响应代码是 301
但消息是 null
。
- 新的 URL 完全相同,但使用 HTTPS。似乎服务器以某种方式强制执行 SSL/TSL 加密。当从浏览器访问 HTTP 时,不会发生什么。
HTTP Header(在 Android 上):
- 日期 => 2016 年 10 月 4 日,星期二 05:56:26 GMT
- location => https://domain.com/route/(我修改了这个位)
- content-length => 382
- content-type => text/html;字符集=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 => 网络 301
- 空 => HTTP/1.1 301
其他数据
- 由于服务器似乎希望Android使用HTTPS,我尝试修改代码以使用HTTPS(HttpsURLConnection)。这可能会或可能不会解决 这个 问题,但我无法检查它,因为我收到一个烦人的
SSL handshake failed
错误。另外我不需要在这个应用程序上加密,因此我不愿意解决随之而来的问题。
- 这就是 运行AsyncTask object 中的所有内容(因为当您尝试在主线程上使用网络连接时 Android 变得喜怒无常)。
- 设置新服务器(在 Cloud 9 之外且没有任何 SSL/TSL)可能是一个选项,但我不愿意这样做,因为这会非常耗时。
- 我尝试使用完全相同的代码连接到另一台 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¶meter2=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。
我正在尝试使用 Android 中的 HttpURL连接 object 执行 HTTP GET。
更新
我尝试连接到不同的服务器。这也托管在 Cloud 9 (c9.io) 中,并且 return 是一个 json 响应。这次我没有 获得 301 重定向,但我得到了服务器应该发送的实际响应。
因为这意味着问题出在服务器内部,我重新组织了以下部分以便集中阅读 server-related 信息。 Android相关信息已移至题末
我连接的地方:
- Cloud9 上的开发服务器
- 使用 Laravel Framework 5.2(由于项目依赖项不受支持,我们目前无法升级到 5.3)
- 服务器应该return一个JSON回答
- 如果我通过浏览器连接到同一个 URL,我会得到正确的响应(JSON 字符串。需要 HTTP Headers 和“200”HTTP 响应代码)
我从哪里连接
- Android phone(Oneplus 3,在 Android 6.0 上)
- 编译SDK版本:23
- 使用构建工具:“23.0.3”
- 使用 Min SDK 版本:19
- 使用目标 SDK 版本:22
- 我正在使用 HttpURL连接 object,使用 HTTP 方法 'GET'
Android
的 HTTP 响应当我运行我的代码时,我从服务器得到以下结果:
HTTP 响应代码是 301
但消息是 null
。
- 新的 URL 完全相同,但使用 HTTPS。似乎服务器以某种方式强制执行 SSL/TSL 加密。当从浏览器访问 HTTP 时,不会发生什么。
HTTP Header(在 Android 上):
- 日期 => 2016 年 10 月 4 日,星期二 05:56:26 GMT
- location => https://domain.com/route/(我修改了这个位)
- content-length => 382
- content-type => text/html;字符集=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 => 网络 301
- 空 => HTTP/1.1 301
其他数据
- 由于服务器似乎希望Android使用HTTPS,我尝试修改代码以使用HTTPS(HttpsURLConnection)。这可能会或可能不会解决 这个 问题,但我无法检查它,因为我收到一个烦人的
SSL handshake failed
错误。另外我不需要在这个应用程序上加密,因此我不愿意解决随之而来的问题。 - 这就是 运行AsyncTask object 中的所有内容(因为当您尝试在主线程上使用网络连接时 Android 变得喜怒无常)。
- 设置新服务器(在 Cloud 9 之外且没有任何 SSL/TSL)可能是一个选项,但我不愿意这样做,因为这会非常耗时。
- 我尝试使用完全相同的代码连接到另一台 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¶meter2=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。