最近研究Android调用WebService,采用Json映射数据,由于不熟悉Android端Json解析走了不少弯路。
先把整个经历分享。
1.服务器端封装Json字符串。
基本未遇到问题,服务器端引用json相关jar包:
json-lib-2.2.3-jdk15.jar
commons-logging.jar
commons-beanutils.jar
commons-collections.jar
commons-lang.jar
ezmorph-1.0.6.jar
参考博客
编写JsonHelper类
public class JsonHelper {
//从普通的Bean转换为字符串
public static String getJson(Object o){
JSONObject jo=JSONObject.fromObject(o);
return jo.toString();
}
//从Java的列表转换为字符串
public static String getJson(List list){
JSONArray ja=JSONArray.fromObject(list);
return ja.toString();
}
//从Java对象数组转换为字符串
public static String getJson(Object[] arry){
JSONArray ja=JSONArray.fromObject(arry);
return ja.toString();
}
//从json格式的字符串转换为Map对象
public static Map getObject(String s){
return JSONObject.fromObject(s);
}
//从json格式的字符串转换为List数组
public static List getArray(String s){
return JSONArray.fromObject(s);
}
//从json格式的字符串转换为某个Bean
public static Object getObject(String s,Class cls){
JSONObject jo=JSONObject.fromObject(s);
return JSONObject.toBean(jo, cls);
}
//从json格式的字符串转换为某类对象的数组
public static Object getArray(String s,Class cls){
JSONArray ja=JSONArray.fromObject(s);
return JSONArray.toArray(ja, cls);
}
}
在方法中调用JsonHelper.getJson(resultList).toString() 返回Json字符串。
2.Java客户端测试,也没遇到问题,正常引入Json.jar包
直接像如下方法生产JsonArray对象,进一步处理。
JSONArray array = JSONArray.fromObjcet(json);
3.测试通过后,将代码移植到Android环境,
1)在引jar包时,首先发生:commons-collections.jar重复引入,导致无法启动虚拟机。
Conversion to Dalvik format failed with error 1
java.lang.IllegalArgumentException: already added: Lorg/apache/commons/collections/FastHashMap;
[2012-11-08 17:00:28 - WeatherManager] Dx at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123)
[2012-11-08 17:00:28 - WeatherManager] Dx at com.android.dx.dex.file.DexFile.add(DexFile.java:163)
[2012-11-08 17:00:28 - WeatherManager] Dx at com.android.dx.command.dexer.Main.processClass(Main.java:486)
[2012-11-08 17:00:28 - WeatherManager] Dx at com.android.dx.command.dexer.Main.processFileBytes(Main.java:455)
[2012-11-08 17:00:28 - WeatherManager] Dx at com.android.dx.command.dexer.Main.access$400(Main.java:67)
[2012-11-08 17:00:28 - WeatherManager] Dx at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:394)
2)在去掉该jar后,json解析时又报NoClassFoundException的错误。陷入两难境地。
3)抛弃使用原生json 的jar包json-lib,使用Android的json对象,org.json.JSONArray、org.json.JSONObject发现使用方法由于原生对象有所区别,
无法解析前面测试通过的json String:
[{"alarmArea":"铁西区","alarmContent":"预计31日降温20℃","alarmDate":"20121108101000","alarmName":"寒潮蓝色预警"},
{"alarmArea":"皇姑区","alarmContent":"预计31日降温22℃","alarmDate":"20121108101000","alarmName":"寒潮黄色预警"}]
4)经过查询有人提出Google的json转换工具Gson可以解决问题,
前往http://code.google.com/p/google-gson/downloads/list下载jar包,
引入后,使用如下几行代码解决问题:
Gson gson=new Gson();
Type listType=new TypeToken<ArrayList<MessageBean>>(){}.getType();
ArrayList<MessageBean> list = gson.fromJson(json, listType);
其中MessageBean是自定义的数据对象。
综上所述,有类似需求的Android开发,可以考虑使用Gson来解析Service端返回的数据,可以比较方便的将Json格式的报文信息,转化为实体对象。