在 URLConnection 上使用 getInputStream() 时出现 ProtocolException

ProtocolException when using getInputStream() on URLConnection

编辑: 导致错误的原因是 url 变量声明中的拼写错误。提供的代码在输入正确的情况下有效。详情见我的回答。

原问题: 我正在开发一个定期向特定 Web 服务器发送 GET 请求的应用程序。

我已经尝试并验证了 URL 和浏览器中的查询,我按预期获得了 XML 格式的信息。

URL/query 看起来像这样: http://foo.bar.com:8080/bla/ha/get_stuff?param1=gargle&param2=blurp

我正在尝试将原始内容传输到我的设备(Android 平板电脑)并将其输出到屏幕。

但是,在我的 URLConnection 对象上调用 getInputStream() 时,出现以下异常:

java.net.ProtocolException: Unexpected status line: SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1.1

在同一个对象上调用 connect() 不会导致异常(但是其他方法,例如 getContent(),会)。

getContentType() returns null.

我正在使用 AsyncTask 来收集和显示数据(显示效果很好)。

代码中也有一个 Authenticator 部分,但是删除它对抛出的异常没有任何影响,所以我认为这不是问题所在。

这是因为数据是XML格式吗?

如果是这样,我还应该如何访问它?

代码

class GetPositionTask extends AsyncTask<Void, Void, String> {
    @Override
    protected String doInBackground(Void... params) {
        String url = "http://foo.bar.com/8080/bla/ha/get_stuff";
        String charset = "UTF-8";
        String param1 = "gargle";
        String param2 = "blurp";
        try {
            String query = String.format("param1=%s&param2=%s",
                    URLEncoder.encode(param1, charset),
                    URLEncoder.encode(param2, charset));

            Authenticator.setDefault(new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("userName", "passWord".toCharArray());
                }
            });

            URLConnection urlConnection = new URL(url + "?" + query).openConnection();
            urlConnection.setRequestProperty("Accept-Charset", charset);
            InputStream response = urlConnection.getInputStream(); //Commenting this out prevents exception

            return "Made it through!"; // Never reaches this
        }
        catch (IOException e) {
            e.printStackTrace();
            return "Exception in GetPositionTask";
        }

    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText(s);
    }
}

注意:这与其他几个问题类似,但我无法通过阅读这些问题解决我的问题。

您正在连接到 SSH 服务器,而不是 HTTP 服务器。

它在 connect() 上没有发生的原因是 connect() 实际上没有连接。如有必要,您提到的其他方法也可以。

原因是 url 字符串中的一个简单类型,它应该是

String url = "http://foo.bar.com:8080/bla/ha/get_stuff";

而不是

String url = "http://foo.bar.com/8080/bla/ha/get_stuff";

改正错字让整个事情变得很有魅力。

有趣的是,当我通过将完整的 URL/query 粘贴到下面的 URL 构造函数中来规避整个连接和格式化业务时,它仍然有效(即使 URLEncoder#encode 调用确实在 param2 中切换了一些 : 个字符。

URLConnection urlConnection = new URL("http://foo.bar.com:8080/bla/ha/get_stuff?param1=gurgle&param2=blurp").openConnection();

(在我的真实情况下,param2 变量包含一个 MAC 地址,: 被替换为 %xx 类型的内容)