【json的处理】一、Gson处理
目前处理json的方法有很多,这里主要总结四种方法
1. Gson方式处理json 【json的处理】一、Gson处理
2. FastJson方式处理json 【json的处理】三、FastJson的处理
3. Jackson方式处理json 【json的处理】二、Jackson的处理
4. json-flattener方式处理json 【json的处理】四、json-flattener的处理
本文主要介绍Gson的方式
Gson提供了十几个fromJson()和toJson()方法,前者实现反序列化,后者实现了序列化。尽量要2.4版本以上的,因为alternate需要2.4版本。下面会介绍alternate。
话不多说,直接上干货
前言:
下面主要通过几个方面来介绍gson:
1. json对象的处理
2. json数组的处理
3. json对象套json数组的处理
需要引入依赖
<!-- 这里需要引入Gson的依赖 --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency>
一、json对象的处理
//一个没有层级关系的普通的json对象. { "name": "张三", "age": "22", "email": "1432299080@qq.com", "sex": "男", "height": "178" } //一个User实体类,名称与json串中的名称完全一样. @Data public class User { private String name; private String age; private String email; private String sex; private String height; } //测试方法 public class gsonTest { public static void main(String[] args) { //定义一个json对象格式的字符串 String jsonStr = "{\n" + " \"name\": \"张三\",\n" + " \"age\": \"22\",\n" + " \"email\": \"1432299080@qq.com\",\n" + " \"sex\": \"男\",\n" + " \"height\": \"178\"\n" + "}"; //使用gson的fromJson方法将字符串转化成对象 Gson gson = new Gson(); User user = gson.fromJson(jsonStr, User.class); //User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178) System.out.println(user); } }
2. 那么json串中key名与user实体类名称不一致该怎么办呢?
(1)如果继续执行上面的测试代码会发现最终输出的结果为://User(name=null, age=null, email=null, sex=null, height=null)
(2)处理办法为:使用SerializedName注解的value属性来处理,value:别名
//准备json串 { "t_name": "张三", "t_age": "22", "t_email": "1432299080@qq.com", "t_sex": "男", "t_height": "178" } //准备实体类 @Data public class User { @SerializedName(value = "t_name") private String name; @SerializedName(value = "t_age") private String age; @SerializedName(value = "t_email") private String email; @SerializedName(value = "t_sex") private String sex; @SerializedName(value = "t_height") private String height; } //测试类 public class gsonTest { public static void main(String[] args) { //定义一个json对象格式的字符串 String jsonStr = "{\n" + " \"t_name\": \"张三\",\n" + " \"t_age\": \"22\",\n" + " \"t_email\": \"1432299080@qq.com\",\n" + " \"t_sex\": \"男\",\n" + " \"t_height\": \"178\"\n" + "}"; //使用gson的fromJson方法将字符串转化成对象 Gson gson = new Gson(); User user = gson.fromJson(jsonStr, User.class); //User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178) System.out.println(user); } }
3. 那么如果是好多家接口同时传递过来不同名称的json串,又该如何处理呢?
现在想要程序可以同时识别s和t开头的key。处理办法:只需要修改下实体类即可,使用@SerializedName的value和alternate 注解来处理,这里要注意value属性指定的就是类中的名字,而alternate 属性是接收一个String数组。
//json串 { "s_name": "张三", "s_age": "22", "s_email": "1432299080@qq.com", "s_sex": "男", "s_height": "178" } { "t_name": "张三", "t_age": "22", "t_email": "1432299080@qq.com", "t_sex": "男", "t_height": "178" } //实体类 @Data public class User { //alternate需要2.4版本 @SerializedName(value = "name",alternate = {"t_name","s_name"}) private String name; @SerializedName(value = "age",alternate = {"t_age","s_age"}) private String age; @SerializedName(value = "email",alternate = {"t_email","s_email"}) private String email; @SerializedName(value = "sex",alternate = {"t_sex","s_sex"}) private String sex; @SerializedName(value = "height",alternate = {"t_height","s_height"}) private String height; } //测试类 public class gsonTest { public static void main(String[] args) { //定义一个json对象格式的字符串 String jsonStr = "{\n" + " \"t_name\": \"张三\",\n" + " \"t_age\": \"22\",\n" + " \"t_email\": \"1432299080@qq.com\",\n" + " \"t_sex\": \"男\",\n" + " \"t_height\": \"178\"\n" + "}"; //使用gson的fromJson方法将字符串转化成对象 Gson gson = new Gson(); User user = gson.fromJson(jsonStr, User.class); //User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178) System.out.println(user); //定义一个json对象格式的字符串 String jsonStr2 = "{\n" + " \"s_name\": \"张三\",\n" + " \"s_age\": \"22\",\n" + " \"s_email\": \"1432299080@qq.com\",\n" + " \"s_sex\": \"男\",\n" + " \"s_height\": \"178\"\n" + "}"; //使用gson的fromJson方法将字符串转化成对象 Gson gson2 = new Gson(); User user2 = gson.fromJson(jsonStr2, User.class); //User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178) System.out.println(user2); } }
二、 json数组的处理
一个没有层级的json对象组成的json数组
使用gson提供的数据类型转换器TypeToken来处理,这里要提一下,它可以支持各种数据集合类型转换
//json串 [ { "t_name": "张三", "t_age": "22", "t_sex": "男", "t_email": "12345677890@qq.com", "t_height": "178" }, { "t_name": "小红", "t_age": "22", "t_sex": "女", "t_email": "1987654321@qq.com", "t_height": "165" } ] //实体类 @Data public class User { @SerializedName(value = "name",alternate = {"t_name","s_name"}) private String name; @SerializedName(value = "age",alternate = {"t_age","s_age"}) private String age; @SerializedName(value = "email",alternate = {"t_email","s_email"}) private String email; @SerializedName(value = "sex",alternate = {"t_sex","s_sex"}) private String sex; @SerializedName(value = "height",alternate = {"t_height","s_height"}) private String height; } //测试类 public class gsonTest { public static void main(String[] args) { String jsonStr = "[\n" + " {\n" + " \"t_name\": \"张三\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"男\",\n" + " \"t_email\": \"12345677890@qq.com\",\n" + " \"t_height\": \"178\"\n" + " },\n" + " {\n" + " \"t_name\": \"小红\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"女\",\n" + " \"t_email\": \"1987654321@qq.com\",\n" + " \"t_height\": \"165\"\n" + " }\n" + "]"; Gson gson = new Gson(); Type type = new TypeToken<List<User>>() {}.getType(); List<User> userList = gson.fromJson(jsonStr, type); //[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178), // User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)] System.out.println(userList); } }
三、json对象套json数组的处理
1. 一般我们在开发的过程中,数据往往都没有上面那么整齐,那么针对整体是一个json对象,里面有json数组的情况该如何处理呢?
//准备一个特殊的json串,json对象中包含json数组且有且仅有一个数据头 { "user": [ { "t_name": "张三", "t_age": "22", "t_sex": "男", "t_email": "12345677890@qq.com", "t_height": "178" }, { "t_name": "小红", "t_age": "22", "t_sex": "女", "t_email": "1987654321@qq.com", "t_height": "165" } ] } //实体类 @Data public class User { @SerializedName(value = "name",alternate = {"t_name","s_name"}) private String name; @SerializedName(value = "age",alternate = {"t_age","s_age"}) private String age; @SerializedName(value = "email",alternate = {"t_email","s_email"}) private String email; @SerializedName(value = "sex",alternate = {"t_sex","s_sex"}) private String sex; @SerializedName(value = "height",alternate = {"t_height","s_height"}) private String height; } //测试类 public static void main(String[] args) { String jsonStr = "{\n" + " \"user\": [\n" + " {\n" + " \"t_name\": \"张三\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"男\",\n" + " \"t_email\": \"12345677890@qq.com\",\n" + " \"t_height\": \"178\"\n" + " },\n" + " {\n" + " \"t_name\": \"小红\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"女\",\n" + " \"t_email\": \"1987654321@qq.com\",\n" + " \"t_height\": \"165\"\n" + " }\n" + " ]\n" + "}"; //先转换成json对象 JsonObject jsonObject = new JsonParser().parse(jsonStr).getAsJsonObject(); //再获取数据头并转换成json数组 JsonArray jsonArray = jsonObject.getAsJsonArray("user"); //方法1 ------------------------------------------------------------------ Gson gson = new Gson(); Type type = new TypeToken<List<User>>() {}.getType(); List<User> userList = gson.fromJson(jsonArray.toString(), type); //[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178), // User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)] System.out.println(userList); //方法2 ------------------------------------------------------------------ Gson gson2 = new Gson(); ArrayList<User> userList2 = new ArrayList<>(); //循环遍历 for (JsonElement user : jsonArray) { //通过反射 得到UserBean.class User userTemp = gson.fromJson(user, new TypeToken<User>() {}.getType()); userList2.add(userTemp); } //[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178), // User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)] System.out.println(userList2); }
2. 那么如果是json对象中同时包含普通字符串和json数组呢?
解决办法:这里需要修改下实体类了,即按照json的格式来处理
//准备json { "roles": "学生", "auth": "上课", "user": [ { "t_name": "张三", "t_age": "22", "t_sex": "男", "t_email": "12345677890@qq.com", "t_height": "178" }, { "t_name": "小红", "t_age": "22", "t_sex": "女", "t_email": "1987654321@qq.com", "t_height": "165" } ] } //实体类 @Data public class JsonTest { private String roles; private String auth; private List<User> user; } @Data public class User { @SerializedName(value = "name",alternate = {"t_name","s_name"}) private String name; @SerializedName(value = "age",alternate = {"t_age","s_age"}) private String age; @SerializedName(value = "email",alternate = {"t_email","s_email"}) private String email; @SerializedName(value = "sex",alternate = {"t_sex","s_sex"}) private String sex; @SerializedName(value = "height",alternate = {"t_height","s_height"}) private String height; } //测试类 public class gsonTest { public static void main(String[] args) { String jsonStr = "{\n" + " \"roles\": \"学生\",\n" + " \"auth\": \"上课\",\n" + " \"user\": [\n" + " {\n" + " \"t_name\": \"张三\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"男\",\n" + " \"t_email\": \"12345677890@qq.com\",\n" + " \"t_height\": \"178\"\n" + " },\n" + " {\n" + " \"t_name\": \"小红\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"女\",\n" + " \"t_email\": \"1987654321@qq.com\",\n" + " \"t_height\": \"165\"\n" + " }\n" + " ]\n" + "}"; JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class); //JsonTest(roles=学生, auth=上课, //user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178), //User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)]) System.out.println(jsonTest); } }
3. 那么如果再复杂一点呢?比如说json对象里面同时含有字符串、json对象、json数组呢?
处理办法:仍然是修改实体类
其实从这几种情况来看,如果json格式发生了变化,那么处理办法就是修改总的jsonTest类。
//准备json { "roles": "学生", "auth": "上课", "teacher": { "name": "张老师", "age": "40" }, "user": [ { "t_name": "张三", "t_age": "22", "t_sex": "男", "t_email": "12345677890@qq.com", "t_height": "178" }, { "t_name": "小红", "t_age": "22", "t_sex": "女", "t_email": "1987654321@qq.com", "t_height": "165" } ] } //实体类 @Data public class JsonTest { private String roles; private String auth; private Course course; private List<User> user; } @Data public class Course { private String name; private String type; } @Data public class User { @SerializedName(value = "name",alternate = {"t_name","s_name"}) private String name; @SerializedName(value = "age",alternate = {"t_age","s_age"}) private String age; @SerializedName(value = "email",alternate = {"t_email","s_email"}) private String email; @SerializedName(value = "sex",alternate = {"t_sex","s_sex"}) private String sex; @SerializedName(value = "height",alternate = {"t_height","s_height"}) private String height; } //测试类 public static void main(String[] args) { String jsonStr = "{\n" + " \"roles\": \"学生\",\n" + " \"auth\": \"上课\",\n" + " \"course\": {\n" + " \"name\": \"高数\",\n" + " \"type\": \"数学\"\n" + " },\n" + " \"user\": [\n" + " {\n" + " \"t_name\": \"张三\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"男\",\n" + " \"t_email\": \"12345677890@qq.com\",\n" + " \"t_height\": \"178\"\n" + " },\n" + " {\n" + " \"t_name\": \"小红\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"女\",\n" + " \"t_email\": \"1987654321@qq.com\",\n" + " \"t_height\": \"165\"\n" + " }\n" + " ]\n" + "}"; JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class); //JsonTest(roles=学生, auth=上课, course=com.winterchen.model.Course@41975e01, //user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178), //User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)]) System.out.println(jsonTest); }
4. 下面补充一个特殊情况:json对象中有json数组,json数组中还有json数组
//准备json { "roles": "学生", "auth": "上课", "course": { "name": "高数", "type": "数学" }, "user": [ { "t_name": "张三", "t_age": "22", "t_sex": "男", "t_email": "12345677890@qq.com", "t_height": "178", "family": [ { "f_name": "张大三", "f_relation": "父亲" }, { "f_name": "刘女士", "f_relation": "母亲" } ] }, { "t_name": "小红", "t_age": "22", "t_sex": "女", "t_email": "1987654321@qq.com", "t_height": "165" } ] } //准备实体类 @Data public class JsonTest { private String roles; private String auth; private Course course; private List<User> user; } @Data public class Course { private String name; private String type; } @Data public class Family { private String f_name; private String f_relation; } @Data public class User { @SerializedName(value = "name",alternate = {"t_name","s_name"}) private String name; @SerializedName(value = "age",alternate = {"t_age","s_age"}) private String age; @SerializedName(value = "email",alternate = {"t_email","s_email"}) private String email; @SerializedName(value = "sex",alternate = {"t_sex","s_sex"}) private String sex; @SerializedName(value = "height",alternate = {"t_height","s_height"}) private String height; @SerializedName(value = "family",alternate = {"t_family","s_family"}) private List<Family> family; } //测试类 public static void main(String[] args) { String jsonStr = "{\n" + " \"roles\": \"学生\",\n" + " \"auth\": \"上课\",\n" + " \"course\": {\n" + " \"name\": \"高数\",\n" + " \"type\": \"数学\"\n" + " },\n" + " \"user\": [\n" + " {\n" + " \"t_name\": \"张三\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"男\",\n" + " \"t_email\": \"12345677890@qq.com\",\n" + " \"t_height\": \"178\",\n" + " \"t_family\": [\n" + " {\n" + " \"f_name\": \"张大三\",\n" + " \"f_relation\": \"父亲\"\n" + " },\n" + " {\n" + " \"f_name\": \"刘女士\",\n" + " \"f_relation\": \"母亲\"\n" + " }\n" + " ]\n" + " },\n" + " {\n" + " \"t_name\": \"小红\",\n" + " \"t_age\": \"22\",\n" + " \"t_sex\": \"女\",\n" + " \"t_email\": \"1987654321@qq.com\",\n" + " \"t_height\": \"165\"\n" + " }\n" + " ]\n" + "}"; JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class); //JsonTest(roles=学生, auth=上课, course=Course(name=高数, type=数学), // user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178, // family=[Family(f_name=张大三, f_relation=父亲), Family(f_name=刘女士, f_relation=母亲)]), // User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165, family=null)]) System.out.println(jsonTest); }
持续更新!!!!