【问题标题】:FileNotFoundException in Android Studio, but works fine in browserAndroid Studio 中的 FileNotFoundException,但在浏览器中运行良好
【发布时间】:2018-09-12 03:59:00
【问题描述】:

我正在尝试连接到网站以接收一些 JSON 信息。当我使用连接的 Nexus 7 设备在 Android Studio 中运行应用程序时,我得到一个 java.io.FileNotFound 异常,但如果我单击未找到的文件的名称,预期的响应会立即显示在我的浏览器中。这对我来说是一个新应用程序,但我过去做过类似的事情。在过去的 2 天里,我一直在尝试多种方法,但似乎找不到问题所在。当我调用 connection.getInputStream() 时,代码会爆炸。所有这些都在 AsyncTask 中运行。

我的代码

public byte[] getUrlBytes(String urlSpec) throws IOException{
    URL url = new URL(urlSpec);
    // urlSpec: https://api.weather.gov/points/48.0174,-115.2278

    try {
        connection = (HttpsURLConnection) url.openConnection();
    } catch (IOException ioe) {
        Log.d(TAG, "connection ioe: " + ioe.toString());
        Toast.makeText(context, "@string/can_not_connect",
                Toast.LENGTH_LONG).show();
    }


    try {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        InputStream in = connection.getInputStream(); *** Blows up here ****

        if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
            Log.d(TAG, "connection Response code: " + 
                  connection.getResponseMessage());
        }

        int bytesRead = 0;
        byte[] buffer = new byte[1024];
        while ((bytesRead = in.read(buffer)) > 0) {
            out.write(buffer, 0, bytesRead);
        }

        out.close();
        return out.toByteArray();
    } finally {
        connection.disconnect();
    }
}

Logcat

04-02 15:40:59.693 32471-32495/com.drme.weathertest E/WeatherFetcher: Failed 
 to fetch items
java.io.FileNotFoundException: https://api.weather.gov/points/48.0174,-115.2278 
*** Note that if I click on this file name, it works in my browser ***
    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:206)       
    at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)   
    at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:25)
    at com.drme.weatherNoaa.WeatherFetcher.getUrlBytes(WeatherFetcher.java:148)
    at com.drme.weatherNoaa.WeatherFetcher.getUrlString(WeatherFetcher.java:183)
    at com.drme.weatherNoaa.WeatherFetcher.downloadGridPoints(WeatherFetcher.java:202)
    at com.drme.weatherNoaa.WeatherFetcher.requestForecast(WeatherFetcher.java:262)
    at com.drme.weatherNoaa.WeatherFragment$SearchTask.doInBackground(WeatherFragment.java:329)
    at com.drme.weatherNoaa.WeatherFragment$SearchTask.doInBackground(WeatherFragment.java:296)
    at android.os.AsyncTask$2.call(AsyncTask.java:292)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)

感谢您的帮助。

【问题讨论】:

  • 你阅读过这个网络服务的文档吗?
  • Selvin - 是的,我做到了,但我很尴尬我似乎掩盖了一些,因为其他一些网站没有相同的要求。请参阅我对自己问题的回答。
  • 嗯,写的是需要在请求中包含两个具体的headers...
  • Selvin - 好吧,当我在浏览器中输入 api 访问字符串时,一切看起来都很简单,一切都很好。我“假设”我可以在我的代码中复制浏览器字符串并且它可以正常工作。
  • 您应该使用 curl 或 fiddler 之类的发送“普通”请求的东西来测试它......

标签: android https download filenotfoundexception


【解决方案1】:

在额外阅读 web 服务文档(其中一些对我来说似乎有点薄)和网络上的一些额外帖子之后,答案是它们需要在请求中包含 Acceptance 和 User-agent 标头。我已经进行了这些更改,现在代码可以正常工作了。

新的静态常量

private static final String ACCEPT_PROPERTY = "application/geo+json;version=1";
private static final String USER_AGENT_PROPERTY = "xxxx.com (xxxxxxxxx@gmail.com)";

代码更改

 connection = (HttpsURLConnection) url.openConnection();
 connection.setRequestProperty("Accept", ACCEPT_PROPERTY);  // added
 connection.setRequestProperty("User-Agent", USER_AGENT_PROPERTY); // added

不需要进行其他更改,尽管我花了一段时间才弄清楚如何添加标题以及它们的格式可能是什么。

感谢您查看此内容。

【讨论】:

  • 你确定那个版本应该是标题吗?我认为它应该是 Accept: application/geo+json;version=1 ... 作为用户代理,您应该发送您的应用名称(可能还有版本)
  • Selvin - 我会将 Accept 标头更改为您的建议。他们谈论版本的方式,我认为我可以使用版本属性。他们指定 User-Agent 字符串可以是任何内容,但如果您包含联系信息(网站或电子邮件),如果您的字符串与安全事件相关联,他们可以与您联系。将来用户代理将被 API 密钥替换。感谢您指出这些事情。我以前从未处理过这些标题。
猜你喜欢
  • 1970-01-01
  • 2015-08-18
  • 2019-03-16
  • 1970-01-01
  • 2016-10-01
  • 2015-07-10
  • 2017-12-18
  • 2016-02-01
  • 2023-04-01
相关资源
最近更新 更多