Gson是谷歌官方提供的解析json数据的工具类。json数据的解析可以使用JSONObject和JSONArray配合使用解析数据,但是这种原始的方法对于小数据的解析还是有作用的,但是陪到了复杂数据的解析,就很难完成任务。
Gson这个java类库可以把java对象转换成JSON,也可以把JSON字符串转换成一个相等的java对象。
下面我们来看一下具体的Gsom解析数据的过程,首先我们在服务器端定义了四种数据:分别是Person对象,List<Person>,List<String>,List<Map<String,Object>>
public class JsonService { public JsonService() { // TODO Auto-generated constructor stub } public Person getPerson(){ Person person =new Person(1001,"呆呆","成都双流"); return person; } public List<Person> getlistperson(){ List<Person> list =new ArrayList<>(); Person person1 =new Person(1001, "哈哈", "广东"); Person person2 =new Person(1002, "呵呵", "成都"); list.add(person1); list.add(person2); return list; } public List<String> getListString(){ List<String> list =new ArrayList<>(); list.add("北京"); list.add("成都"); list.add("双流"); return list; } public List<Map<String, String>> getListMaps(){ List<Map<String, String>> list =new ArrayList<>(); Map<String, String> map1 =new HashMap<String, String>(); map1.put("id", "1001"); map1.put("name", "呆呆"); map1.put("address", "成都"); Map<String, String> map2 =new HashMap<String, String>(); map2.put("id", "1002"); map2.put("name", "好痒"); map2.put("address", "双流"); list.add(map1); list.add(map2); return list; }知道了服务器上的具体数据之后,我们新建一个Android工程,定义四个按钮,分别实现对Person 对象,List<Person>,List<String>,List<Map<String,Object>>的解析功能。具体的xml布局代码这里就不做演示,读者自行创建。
因为Gson是使用的第三方框架,所以我们需要在工程项目的lib文件夹下导入相应的jar文件,这里我们使用的gson-2.2.1.jar。因为从服务器获取数据需要用到网络,我们需要在AndroidMainfest.xml文件中获取网络请求权限:
<uses-permission android:name="android.permission.INTERNET"/>创建相应的Person类,类中包含了id、name、address的set/get方法,以及一个tostring方法还有构造函数,具体代码不做详细描述。
想要获取网络上的数据,就需要一个网络访问类,打开网络访问连接获取具体的数据:(若对其中某些代码有疑惑可以查看上一篇XML文件解析,有具体的代码解释这里不做赘述)
public class HttpUtils { public HttpUtils() { } public static String getJsonContent(String url_path) { try { //定义http的链接,设置链接时长为3s,使用get方法获取数据 URL url = new URL(url_path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(3000); connection.setRequestMethod("GET"); connection.setDoInput(true); int code = connection.getResponseCode(); if (code == 200) { return changeInputStrean(connection.getInputStream()); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } //把字符串从outputString流里面写入ByteArrayOutputStream中,转换成字节数组,在构建一个新的字符串 private static String changeInputStrean(InputStream inputStream) { String jsonString = null; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); int len = 0; byte[] data = new byte[1024]; try { while ((len = inputStream.read(data)) != -1) { outputStream.write(data, 0, len); } jsonString = new String(outputStream.toByteArray()); } catch (IOException e) { e.printStackTrace(); } return jsonString; } }所有东西准备就绪,接下来需要做的就是定义Gson的工具类了,在这里我们要明白的是服务器将具体的数据对象使用Gson转换成了Json字符串,那么客户端需要做的就是将json字符串还原成原来的对象,那么我们这里定义的Gson工具类,一定是要能够满足各种数据对象的,也就是说不管服务器传递什么样的对象,作为客户端只需要知道对象的类型就可以将对象还原,所以在这里我们使用了泛型T的方式来定于
public class GsonTools { public GsonTools() { } //使用泛型,不需要知道服务器端返回的是什么对象,服务器端gson解析成字符串返回后,都会解析成原来的对象 /** * * @param jsonstring * @param cls * @param <T> 服务器端的对象使用Gson解析成json字符串,客户端将json字符串解析还原成原来的对象,如想提取成工具 * 类,无论服务器端传递的是什么对象,客户端只需知道对象类型就可以解析,因此在此使用泛型T * @return */ public static <T> T getperson(String jsonstring, Class<T> cls) { T t = null; Gson gson = new Gson(); t = gson.fromJson(jsonstring, cls); return t; } /** * 使用Gson进行解析List<Person>对象 * TypeToken 官方提供的反射机制,详见api说明文档 * * * @param jsonstring * @param cls * @param <T> * @return */ public static <T> List<T> getpersons(String jsonstring, Class<T> cls) { List<T> list = new ArrayList<T>(); Gson gson = new Gson(); //TypeToken把对象T中属性的值通过反射机制映射出来,再从jsonstring字符串中取出来的值放进去 //TypeToken<List<T>>(){}.getType()该方法表示把jsonstring字符串里面的值取出来之后封装到list中,然后分别从T中取出所有的类型 list = gson.fromJson(jsonstring, new TypeToken<List<T>>() { }.getType()); return list; } public static List<String> getList(String jsonString) { List<String> list = new ArrayList<>(); Gson gson = new Gson(); list = gson.fromJson(jsonString, new TypeToken<List<String>>() { }.getType()); return list; } public static List<Map<String, Object>> getlistmap(String jsonstring) { List<Map<String, Object>> list = new ArrayList<>(); Gson gson = new Gson(); list = gson.fromJson(jsonstring, new TypeToken<List<Map<String, Object>>>() { }.getType()); return list; } }剩下的事情就是我们实现具体的点击事件的功能了,因为这里使用API的版本不支持在主线程中访问网络请求,这里为了方便起见,我就直接定义了一个线程进行访问,在具体的代码实现过程中,大家可以根据需要使用不同的方法:
case R.id.gsonperson: new Thread(){ @Override public void run() { String path5 ="http://192.168.199.247:8080/jsonProject1/JsonAction?action_flag=person"; String jsonstring = HttpUtils.getJsonContent(path5); Person person = GsonTools.getperson(jsonstring,Person.class); Log.i(TAG,person.toString()); } }.start(); break; case R.id.gsonpersons: new Thread(){ @Override public void run() { String path6 ="http://192.168.199.247:8080/jsonProject1/JsonAction?action_flag=persons"; String jsonstring = HttpUtils.getJsonContent(path6); List<Person> list = GsonTools.getpersons(jsonstring, Person.class); Log.i(TAG,list.toString()); } }.start(); break; case R.id.gsonliststring: new Thread(){ @Override public void run() { String path7 ="http://192.168.199.247:8080/jsonProject1/JsonAction?action_flag=liststring"; String jsonstring = HttpUtils.getJsonContent(path7); List<String> list = GsonTools.getList(jsonstring); Log.i(TAG,list.toString()); } }.start(); break; case R.id.gsonlistmap: new Thread(){ @Override public void run() { String path8 ="http://192.168.199.247:8080/jsonProject1/JsonAction?action_flag=listmap"; String jsonstring = HttpUtils.getJsonContent(path8); List<Map<String,Object>> list =GsonTools.getlistmap(jsonstring); Log.i(TAG,list.toString()); } }.start(); break; }这里只是将关键代码写出,其余代码,可以自己补充!