【问题标题】:java.net.ProtocolException: Unexpected status line: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">java.net.ProtocolException: 意外的状态行:<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
【发布时间】:2016-07-10 09:49:41
【问题描述】:

我是 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 变量检索到的&lt;input_username&gt; - &lt;input_password&gt;

$jsonObj = json_decode($_GET["data"], TRUE);

echo $jsonObj["loginMail"] . " - " . $jsonObj["loginPassword"];

这个问题阻塞了我大概两天,我该怎么做才能解决这个问题?

【问题讨论】:

  • 如果不深入研究这个问题,我可以建议使用 OkHttp 进行网络调用吗?它对我很有帮助,它可能会为你解决这个问题。
  • 听起来很像HTTP响应无效;如果是这样,问题出在服务器端,而不是引用的代码。
  • @T.J.Crowder - 服务器文件工作正常,即使只是回显“A”从 Java 调用它也不起作用
  • 我只是说,这个错误是一个协议异常,当它试图读取 HTTP 响应的状态行时,它得到了有效负载的第一行。这表明发送端有问题(或HttpURLConnection 中的错误,但select isn't broken,所以...)。
  • 谢谢@Vucko,我刚刚google了一下,找到了XD

标签: java php android httpurlconnection protocolexception


【解决方案1】:

重要

致任何在 Volley HTTP 实现中遇到此错误的人:

java.net.ProtocolException: Unexpected status line: <!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>

请检查并使用 OkHttp Dependency 来解决它。 Here the documentation to check.

就我而言(我不知道为什么),我的 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.

【讨论】:

    【解决方案2】:

    我还不能发表评论,因此我需要写一个答案。 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

    【讨论】:

    • 谢谢你的建议,我去测试一下
    • 嗯,那么可能标头完全丢失并且客户端找不到它。然后你可以试试echo "HTTP/1.0 200 OK\r\n\r\n";。你有它托管在某个地方吗?你能给我们访问权限吗?
    • The header is set,我用 Fiddler 测试过。我想我会使用@Vucko 建议的OkHttp,谢谢你的帮助;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 2016-11-13
    • 2011-05-08
    • 1970-01-01
    • 2011-12-11
    • 2021-10-04
    • 2016-11-09
    相关资源
    最近更新 更多