1. 程式人生 > >【Java】JSOUP請求JSON 及解決jsoup不能完整獲取響應內容的問題

【Java】JSOUP請求JSON 及解決jsoup不能完整獲取響應內容的問題

用JSOUP來請求介面,構造請求頭的時候非常方便。程式碼如下:

Document doc = Jsoup
		.connect(Constant.DATA_URL)
		.timeout(10000).get();
Element body = doc.body();
JSONObject json = JSONObject.fromObject(body.text());

 但是出現問題了,請求就報錯:

org.jsoup.UnsupportedMimeTypeException: Unhandled content type. Must be text/*, application/xml, or application/xhtml+xml. Mimetype=application/json;charset=UTF-8, URL=http://www.baidu.com/
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:600)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:540)
    at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:227)
    at org.jsoup.helper.HttpConnection.get(HttpConnection.java:216)

找了如下解決方案:

String body =Jsoup
                 .connect(Constant.DATA_URL)
                 .timeout(100000)
                 .ignoreContentType(true)
                 .execute()
                 .body();
body = body.replaceAll("\\n", "");

上面其實關鍵點在於:ignoreContentType(true) ,這個是忽略請求型別。建議用execute()

 去執行,如果用get 去執行的話,返回來是一個 HTML  頁面包裹的 JSON  ,你處理起來稍微有點費勁。

而且你要處理換行, JSON  正確的格式是一行返回,多行的話轉成 JSON  物件的時候就會報錯。所以還是推薦用execute() 去執行。

當使用jsoup訪問http的介面時,但如果遇到不能完整獲取響應內容時,一般有以下幾個原因。

1. 網路異常,造成讀取不全。這個很少發生,因為jsoup會報告exception

2. 網路超時,此時可以設定 connection.timeout(n) 增加超時時間。

3. 一切看起來都正常,也沒有異常發生。 但是獲取的資料就是少了一截。

這裡主要將第三點。

仔細分析獲取到的資料,發現得到資料都是1024k。

如果獲取到的資料不超過1024k,程式正常,得到的資料也正常。

一旦資料超過1024k時,資料就只有預期得到資料的前1024k位元組了。

仔細查詢jsoup的api 發現,預設設定下,jsoup最大獲取的響應長度正好時1M。

所以這個時候只要設定 connection.maxBodySize(0),設定為0,就可以得到不限響應長度的資料了。
 

String body =Jsoup
                 .connect(Constant.DATA_URL)
                 .timeout(100000)
                 .maxBodySize(0)
                 .ignoreContentType(true)
                 .execute()
                 .body();

body = body.replaceAll("\\n", "");

方法二:

InputStreamReader reader = null;
BufferedReader in = null;
try {
	URL url = new URL(Constant.DATA_URL);
	URLConnection connection = url.openConnection();
	connection.setConnectTimeout(1000);
	reader = new InputStreamReader(connection.getInputStream(), "UTF-8");
	in = new BufferedReader(reader);
	String line = null; // 每行內容
	StringBuffer content = new StringBuffer();
	while ((line = in.readLine()) != null) {
		content.append(line);
	}
	if (StringUtils.isNotBlank(content)) {
		String jsonStr = content.toString().replaceAll("\\n", "");
		data = JSONObject.fromObject(jsonStr);
	}
} catch (SocketTimeoutException e) {
	System.out.println("連線超時!!!");
} catch (JSONException e) {
	System.out.println("網站響應不是json格式,無法轉化成JSONObject!!!");
} catch (Exception e) {
	System.out.println("連線網址不對或讀取流出現異常!!!");
} finally {
	if (in != null) {
		try {
			in.close();
		} catch (IOException e) {
			System.out.println("關閉流出現異常!!!");
		}
	}
	if (reader != null) {
		try {
			reader.close();
		} catch (IOException e) {
			System.out.println("關閉流出現異常!!!");
		}
	}
}