我是Java和Android编程的新手,我正在尝试在我的服务器上获取PHP文件的结果,但我得到以下异常:
java.net.ProtocolException: Unexpected status line: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at com.android.okhttp.internal.http.StatusLine.parse(StatusLine.java:54)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:905)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:789)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:443)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at it.codesnippet.dots.LoginActivity$1$override.run(LoginActivity.java:49)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at it.codesnippet.dots.LoginActivity$1$override.access$dispatch(LoginActivity.java)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at it.codesnippet.dots.LoginActivity$1.run(LoginActivity.java:0)
07-10 11:18:54.112 24683-25081/it.codesnippet.dots W/System.err: at java.lang.Thread.run(Thread.java:818)
这是异常来自的代码(在 LoginActivity.java 中):
Thread loginCheckThread = new Thread(new Runnable() {
public void run() {
String result = "", dataObj = "";
TextView username = (TextView) findViewById(R.id.login_mail);
TextView password = (TextView) findViewById(R.id.login_password);
JSONObject jsonObj = new JSONObject();
try {
jsonObj.put("loginMail", username.getText());
jsonObj.put("loginPassword", password.getText());
dataObj = jsonObj.toString(0);
} catch (JSONException e) {
e.printStackTrace();
}
try {
URL url = new URL("http://myserver.it/testandroid.php?data=" + dataObj);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
/* line #49 */ InputStream in = new BufferedInputStream(urlConnection.getInputStream());
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int i = in.read();
while (i != -1) {
bo.write(i);
i = in.read();
}
result = bo.toString();
} catch (IOException e) {
result = "Exception: Class::IOStream Related";
e.printStackTrace();
} finally {
urlConnection.disconnect();
}
} catch (IOException e) {
result = "Exception: Class::URL Related";
}
System.out.println(result);
}
});
loginCheckThread.start();
导致异常的行是行 #49:
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
PHP 文件现在只是一个测试文件,应该返回从查询字符串中的 data
变量检索<input_username> - <input_password>
:
$jsonObj = json_decode($_GET["data"], TRUE);
echo $jsonObj["loginMail"] . " - " . $jsonObj["loginPassword"];
这个问题阻止了我大约两天,我该怎么做才能解决这个问题?
重要
对于在Volley HTTP实现中遇到此错误的任何人:
java.net.ProtocolException: Unexpected status line: <!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>
请检查并使用 OkHttp 依赖项来解决它。这里是要检查的文档。
就我而言(我不知道为什么),我的Android测试手机(MOTO E V.4.4.4 Kitkat)让我回到了java.net.ProtocolException: Unexpected status line
例外。我尝试重置手机并删除应用程序,但没有任何效果。
另一方面,我的Nexus 5X(使用Android Oreo)运行良好(相同的应用程序,相同的网络,相同的后端)。
请(真的)尝试OkHttp
依赖项,它将起作用。
Psd:一些堆栈溢出线程说关于 Volley Cache 或类似的东西,我自己尝试了所有内容, but OkHttp solved my trouble.
我还不能发表评论,因此我需要写一个答案。HTTP 和 HTML 之间是有区别的。HTTP 用于下载数据(例如 HTML)。您的PHP脚本生成可下载的内容,但HTTP客户端似乎并不认为它已经是内容。作为一个例子,我想向您展示HTTP响应通常的样子:
HTTP/1.1 200 OK
Date: Sun, 10 Jul 2016 10:02:42 GMT
Content-Type: text/html
Content-Length: 6920
Last-Modified: Sun, 10 Jul 2016 04:00:22 GMT
Connection: keep-alive
Accept-Ranges: bytes
Here goes the content.
如您所见,HTTP 信息一直出现,直到出现双换行符或 CRLF(回车符、换行符)。我已经看到一些服务器仅使用 LF 实现了这一点,这可能是问题所在,因为您的 Java 客户端无法看到内容何时开始。让我们做一个测试:在 PHP 文件的开头添加一个echo "'r'n'r'n";
以手动打印 CRLFCRLF。如果它有效,则服务器软件的输出是错误的。不是你的脚本,也不是你的客户端。但是,RFC 2616 还表示建议忽略 CR,只监视 LF:
消息头字段的行终止符是序列 CRLF。 但是,我们建议应用程序在解析此类标头时, 将单个 LF 识别为线路终止符,并忽略前导 CR。 RFC 2616