FileNotFoundException在Android Studio中运行,但在浏览器中运行良好
我正在尝试连接到一个网站以接收一些JSON信息。当我在Android Studio中使用连接的Nexus 7设备运行应用程序时,我会得到一个java.io.FileNotFound异常,但如果我单击未找到的文件名,预期的响应会立即显示在我的浏览器中。这对我来说是一个新的应用程序,但我在过去做过类似的事情。在过去的两天里,我尝试了多种方法,但似乎都没有发现问题。当我调用connection.getInputStream()时,代码会崩溃。所有这些都在异步任务中运行 我的代码FileNotFoundException在Android Studio中运行,但在浏览器中运行良好,android,https,download,filenotfoundexception,Android,Https,Download,Filenotfoundexception,我正在尝试连接到一个网站以接收一些JSON信息。当我在Android Studio中使用连接的Nexus 7设备运行应用程序时,我会得到一个java.io.FileNotFound异常,但如果我单击未找到的文件名,预期的响应会立即显示在我的浏览器中。这对我来说是一个新的应用程序,但我在过去做过类似的事情。在过去的两天里,我尝试了多种方法,但似乎都没有发现问题。当我调用connection.getInputStream()时,代码会崩溃。所有这些都在异步任务中运行 我的代码 public byte
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)
感谢您的帮助。在额外阅读了webservice文档(其中一些对我来说似乎有点单薄)和web上的其他帖子之后,答案是它们需要在请求中包含接受和用户代理标题。我已经做了这些更改,代码现在可以按预期工作了 新的静态常数
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
代码更改
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
虽然我花了一段时间才弄清楚如何添加标题及其格式,但不需要进行其他更改
感谢您查看。您阅读了此Web服务的文档吗?Selvin-是的,我阅读了,但我感到尴尬的是,我似乎对一些内容进行了润色,因为其他一些网站没有相同的要求。请看我对自己问题的回答。好吧,有人说你需要在请求中包含两个特定的标题…Selvin-好吧,当我在浏览器中键入api访问字符串时,一切都很顺利。我“假设”我可以在我的代码中复制浏览器字符串,它可以正常工作。你应该用curl或fiddler之类的东西来测试它,它发送“普通”请求……你确定版本应该是header吗?我认为应该是
Accept:application/geo+json;版本=1
。。。同样作为用户代理,您应该发送您的应用程序名称(可能还有版本)Selvin-我会将Accept标题更改为您的建议。他们谈论版本的方式,我想我可以使用版本属性。它们指定用户代理字符串可以是任何内容,但如果您包含联系信息(网站或电子邮件),则如果您的字符串与安全事件关联,它们可以与您联系。用户代理将来将被API密钥替换。谢谢你指出这些事情。我以前从未处理过这些标题。