最近的項目中和第三方接口聯調,須要調用webservice接口獲取json格式字符串,而後轉化成對象。java
在此記錄一下遇到的問題。web
1.Stirng字符串問題,第一個字符爲空,不是"{"json
前期開發過程當中,第三方是內網,沒法進行聯調,客戶把某一天返回的字符串結果保存在文本中發給我調試,使人鬱悶的是下面語句老是報錯:app
JSONObject jsonObject = JSONObject.fromObject(resJsonStr);
錯誤信息:dom
net.sf.json.JSONException: A JSONObject text must begin with '{' at character 1 of {"results":[{"測試
意思是返回的json格式字符串不標準,不是一個「{」開頭,但是我打開調試模式看到的結果是這樣的:編碼
的確是以「{」開頭的,後來調試很久,打開debug模式下的value中看到內部存儲的值,才發現第一個字節不是"{",而是空!spa
以下圖:debug
這個讓人很鬱悶,由於經過「肉眼」根本看不出來,第一個字節是空,修改一下代碼以下,測試經過:調試
resJsonStr = resJsonStr.substring(resJsonStr.indexOf("{"),resJsonStr.lastIndexOf("}")+1);//截取第一次出現「{」到最後一次出現「}」的部分
問題緣由:我是從txt文件中讀取json格式的字符串,可能跟文件存儲有關係,緣由待查。
2.從文本中讀取字符串偶爾會有亂碼現象。
從文本中讀取的字符串有個別漢字出現亂碼問題,我覺得是文本里面的內容有問題,後來發現跟讀取文本的方式有關係,以前讀取文本里面的內容是經過以下方式:
/** * 讀文件 * * @param path * @return * @throws IOException */ public static String readFileByString(String path) throws IOException { File file = new File(path); if (!file.exists() || file.isDirectory()) throw new FileNotFoundException(); FileInputStream fis = new FileInputStream(file); byte[] buf = new byte[1024]; StringBuffer sb = new StringBuffer(); while ((fis.read(buf)) != -1) { sb.append(new String(buf)); buf = new byte[1024];// 從新生成,避免和上次讀取的數據重複 } fis.close(); return sb.toString(); }
這段代碼是每次讀取1024個字節,而後不斷加到StringBuffer後面,因爲我用的是utf-8編碼,裏面每一個漢字佔用三個字節,就會出現這種可能:
一個漢字被拆分紅了兩部分,第一次讀取的時候只讀了前面兩個字節或者一個字節,這樣的話這個漢字就會出現亂碼
知道問題所在就比較容易改了,改爲按行讀取就不會出現這種問題,從新寫了一個方法,以下:
public static String readFileToStringByLine(String path) throws IOException{ int len=0; StringBuffer str=new StringBuffer(""); File file = new File(path); if (!file.exists() || file.isDirectory()) throw new FileNotFoundException(); try { FileInputStream is=new FileInputStream(file); InputStreamReader isr= new InputStreamReader(is); BufferedReader in= new BufferedReader(isr); String line=null; while( (line=in.readLine())!=null ) { str.append(line); len++; } in.close(); is.close(); } catch (IOException e) { e.printStackTrace(); } return str.toString(); }
測試經過。
問題緣由:utf-8編碼方式中一個漢字佔三個字節,每次從文本中讀取1024個字節有可能會把一個漢字拆開,出現亂碼問題。
3.經過JSONObject轉複雜對象。
從json字符串到要轉成的對象以下:
public class ResponseInfo { private List<ClassRoomInfo> results = new ArrayList<ClassRoomInfo>(); private int count ; private boolean status; private String msg; public List<ClassRoomInfo> getResults() { return results; } ... ... }
對於這種對象中含有複雜對象,如list,若是不指定,如:
JSONObject jsonObject = JSONObject.fromObject(resJsonStr); responseInfo = (ResponseInfo) JSONObject.toBean(jsonObject, ResponseInfo.class); //簡單對象能夠用這種方法,複雜對象則不行
則會報錯:
java.lang.ClassCastException: net.sf.ezmorph.bean.MorphDynaBean cannot be cast to com.hikvision.cms.wsclient.hdu.domain.ClassRoomInfo
這時須要構造一個屬性的map放進去才行,以下:
Map<String, Class<?>> classMap = new HashMap<String, Class<?>>(); classMap.put("results", ClassRoomInfo.class); JSONObject jsonObject = JSONObject.fromObject(resJsonStr); //爲list指定泛型屬性 responseInfo = (ResponseInfo) JSONObject.toBean(jsonObject, ResponseInfo.class, classMap);
測試成功。