Я новичок в программировании на 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 пока что является тестовым файлом и должен возвращаться <input_username> - <input_password>
извлечено из data
переменная в строке запроса:
$jsonObj = json_decode($_GET["data"], TRUE);
echo $jsonObj["loginMail"] . " - " . $jsonObj["loginPassword"];
Около двух дней эта проблема заблокировала меня, что я могу сделать, чтобы решить эту проблему?
Важный
Всем, у кого есть эта ошибка в вашей реализации HTTP-залпа:
java.net.ProtocolException: Unexpected status line: <!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>
Пожалуйста, проверьте и используйте OkHttp Dependency для ее решения. Здесь документация для проверки.
В моем случае (я не знаю почему) мой тестовый телефон Android (MOTO E V.4.4.4 Kitkat) возвращал меня java.net.ProtocolException: Unexpected status line
исключение. Я попытался перезагрузить телефон и удалить приложение, и ничего не работает.
С другой стороны, мой Nexus 5X (с Android Oreo) работал хорошо (то же приложение, та же сеть, тот же бэкэнд).
Пожалуйста (действительно) попробуйте OkHttp
зависимость и это сработает.
PSD: Некоторые потоки stackoverflow говорят о 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-клиент не может видеть, когда запускается контент. Давайте сделаем тест: добавить echo "\r\n\r\n";
прямо в начале вашего файла PHP, чтобы распечатать CRLFCRLF вручную. Если это сработает, то вывод вашего серверного программного обеспечения будет неправильным. Не ваш сценарий и не ваш клиент. Тем не менее, RFC 2616 также говорит, что это рекомендуемые игнорировать CR и только наблюдать за LF:
Терминатором строки для полей заголовка сообщения является последовательность CRLF.
Тем не менее, мы рекомендуем приложениям при разборе таких заголовков
распознавать один LF в качестве ограничителя строки и игнорировать ведущий CR.
RFC 2616