HttpURLConnection拋異常java.io.FileNotFoundException
阿新 • • 發佈:2019-01-24
今天在除錯app的時候,用HttpURLConnection獲取伺服器資料的時候出現了java.io.FileNotFoundException異常,原因還不太明瞭,不過已經找到了解決方法。
由於我們的伺服器資料有兩種型別,一種是xml(請求帶引數,即post方式),一種是json格式(請求引數直接附加在url後面,應該是get方式)。
之前請求這兩種資料都是用同一種方式獲取的即post方式,方法如下:
json資料地址為http://72.52.93.xxx/hdepg_data/dataForQuanQiuBo/2220143.js
/** * post方式請求 * @param param 請求引數 * @param urlStr 請求地址 * @param contentType 內容格式 * @return */ public InputStream postMethod(String param, String urlStr, String contentType) { InputStream is = null; try { byte[] xmlData = param.getBytes("UTF-8"); URL url = new URL(urlStr); URLConnection urlCon = url.openConnection(); urlCon.setDoOutput(false); urlCon.setDoInput(true); urlCon.setConnectTimeout(40000); urlCon.setReadTimeout(40000); urlCon.setUseCaches(false); urlCon.setRequestProperty("Content-Type", contentType); urlCon.setRequestProperty("Content-length", String.valueOf(xmlData.length)); DataOutputStream printout = new DataOutputStream( urlCon.getOutputStream()); printout.write(xmlData); printout.flush(); printout.close(); is = urlCon.getInputStream(); } catch (IOException e) { Log.e(TAG, "Url connection failed!"); e.printStackTrace(); } catch (Exception e) { Log.e(TAG, "Failed getting input stream!"); e.printStackTrace(); } return is; }
後來json資料換了一個地址:http://xxx.hanyastar.com/hdepg_data/dataForQuanQiuBo/xxxx.js,再用post方式請求資料的時候就出現java.io.FileNotFoundException異常了。感覺很奇怪,只是換了個地址而已,其他的操作都沒變,為什麼就不能成功訪問了呢?
後來上網查了下,發現有人如是說:
原文地址:http://www.mikebai.com/html/2012-03/939.html 最近把機器刷到4.0了 跑了一下自己的app,發現下載xml檔案部分丟擲異常:java.io.FileNotFoundException: http://www.jpfocus.com/xxxx.xml 可是在2.3的系統卻可以正常下載 我的程式碼: URL url = new URL(urlstr); HttpURLConnection httpCon = (HttpURLConnection) url.openConnection(); httpCon.setRequestMethod("GET"); httpCon.setDoOutput(true); httpCon.connect(); 原因: 4.0中設定httpCon.setDoOutput(true),將導致請求以post方式提交,即使設定了httpCon.setRequestMethod("GET"); 將程式碼中的httpCon.setDoOutput(true);刪除即可 關於setDoOutput(true) 網上查到的解釋是,設定true,表示你傳送的請求,會把body的內容傳送至server端,即POST和PUT才需要使用。GET完全可以不用設定。
難道新地址不支援post方式了?
於是我把請求方法修改了下:
註釋掉了post的body引數(如果不註釋,而setDoOutput又設定為false的時候會報: java.net.ProtocolException: method does not support a request body: GET),setDoOutput設定為false(或者註釋掉)。再用此方法獲取新地址json資料就成功了。public InputStream postMethodHanya(String param, String urlStr, String contentType) { InputStream is = null; try { byte[] xmlData = param.getBytes("UTF-8"); URL url = new URL(urlStr); URLConnection urlCon = url.openConnection(); urlCon.setDoOutput(false); urlCon.setDoInput(true); urlCon.setConnectTimeout(40000); urlCon.setReadTimeout(40000); urlCon.setUseCaches(false); // urlCon.setRequestProperty("Content-Type", contentType); // urlCon.setRequestProperty("Content-length", // String.valueOf(xmlData.length)); // // urlCon.setFixedLengthStreamingMode(xmlData.length); // DataOutputStream printout = new DataOutputStream( // urlCon.getOutputStream()); // printout.write(xmlData); // printout.flush(); // printout.close(); is = urlCon.getInputStream(); } catch (IOException e) { Log.e(TAG, "Url connection failed!"); e.printStackTrace(); } catch (Exception e) { Log.e(TAG, "Failed getting input stream!"); e.printStackTrace(); } return is; }
雖然用get方式獲取到了json資料,但是為什麼會有兩個地址的前後差異,現在還是沒弄明白,在這裡記錄下。如果有大神知道還請賜教。
ps:setDoInput和setDoOutput的含義
- publicvoid setDoInput(boolean doinput)將此 URLConnection 的 doInput 欄位的值設定為指定的值。
- URL 連線可用於輸入和/或輸出。如果打算使用 URL 連線進行輸入,則將 DoInput 標誌設定為 true;如果不打算使用,則設定為 false。預設值為 true。
- publicvoid setDoOutput(boolean dooutput)將此 URLConnection 的 doOutput 欄位的值設定為指定的值。
- URL 連線可用於輸入和/或輸出。如果打算使用 URL 連線進行輸出,則將 DoOutput 標誌設定為 true;如果不打算使用,則設定為 false。預設值為 false。
- httpUrlConnection.setDoOutput(true);以後就可以使用conn.getOutputStream().write()
- httpUrlConnection.setDoInput(true);以後就可以使用conn.getInputStream().read();
- get請求用不到conn.getOutputStream(),因為引數直接追加在地址後面,因此預設是false。
- post請求(比如:檔案上傳)需要往服務區傳輸大量的資料,這些資料是放在http的body裡面的,因此需要在建立連線以後,往服務端寫資料。
- 因為總是使用conn.getInputStream()獲取服務端的響應,因此預設值是true。