最近的项目中和第三方接口联调,需要调用webservice接口获取json格式字符串,然后转化成对象。
在此记录一下遇到的问题。
1.Stirng字符串问题,第一个字符为空,不是"{"
前期开发过程中,第三方是内网,无法进行联调,客户把某一天返回的字符串结果保存在文本中发给我调试,令人郁闷的是下面语句总是报错:
JSONObject jsonObject = JSONObject.fromObject(resJsonStr);
错误信息:
net.sf.json.JSONException: A JSONObject text must begin with '{' at character 1 of {"results":[{"
意思是返回的json格式字符串不标准,不是一个“{”开头,可是我打开调试模式看到的结果是这样的:
的确是以“{”开头的,后来调试好久,打开debug模式下的value中看到内部存储的值,才发现第一个字节不是"{",而是空!
如下图:
这个让人很郁闷,因为通过“肉眼”根本看不出来,第一个字节是空,修改一下代码如下,测试通过:
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 Listresults = new ArrayList (); private int count ; private boolean status; private String msg; public List 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> classMap = new HashMap >(); classMap.put("results", ClassRoomInfo.class); JSONObject jsonObject = JSONObject.fromObject(resJsonStr); //为list指定泛型属性 responseInfo = (ResponseInfo) JSONObject.toBean(jsonObject, ResponseInfo.class, classMap);
测试成功。