JSON字符串和对象(泛型)互转并解决json对象首字母小写

文章目录

  • 1 JSON解析问题
    • 1.1 User实体
    • 1.2 转换为JSON对象后首字母小写
    • 1.3 json对象或json字符串与实体互转
      • 1.3.1 实体转json对象或字符串
      • 1.3.2 json对象或json字符串转换为实体对象
    • 1.4 Gson来解析和反解析json对象
      • 1.4.1 解析普通对象
      • 1.4.2 解析泛型对象
    • 1.5 JSONObject来解析和反解析
      • 1.5.1 转为json对象或json字符串
      • 1.5.2 反解析实体对象
        • 1.5.2.1 反解析普通实体对象
        • 1.5.2.2 反解析泛型实体对象
    • 1.6 JSON引用和重复引用
      • 1.6.1 重复引用
      • 1.6.2 循环引用

1 JSON解析问题

1.1 User实体

首先假设有一个实体对象user:

private Integer UserId;

private  Integer getUserId (){
	return UserId;
}
private Integer setUserId(Integer UserId){
this.UserId = UserId;
}

用的是com.alibaba.fastjson.JSON的包,用的是toJSON方法

1.2 转换为JSON对象后首字母小写

在实体对象的每个get方法上添加@JSONField(name=“UserId”)
就可以有效避免,首字母小写的问题

@JSONField(name="UserId")
private  Integer getUserId (){
	return UserId;
}

1.3 json对象或json字符串与实体互转

1.3.1 实体转json对象或字符串

User u = new User ();
u.setUserId(123);
//转换为json对象
JSON jsonObject = JSON.toJSON(u);
//转换为json字符串
String jsonString = JSON.toJSONString(u);

得到的结果是一样的,只是类型不同而已

jsonObject:{"UserId":123}
jsonString:{"UserId":"123"}

1.3.2 json对象或json字符串转换为实体对象

//把json对象转换为实体对象
User userObject =JSON.toJavaObject(jsonObject,User.class);
//把json字符串转换为实体对象
User userString = JSON.parseObject(jsonString,User.class);

如果不想建立实体对象,而只想从JSON对象中获取某一个字段可以这样操作:

//解析字符串
//第一个参数是json字符串,第二个参数是实体类
JSONObject json =JSON.parseObject(JSONObejct.toJSONString(u));
String userId= (String)json.get("UserId");
System.out.println(userId);

注意:实体bean里面需要重写写toString方法才能直接输出对象里面的每个属性。

1.4 Gson来解析和反解析json对象

1.4.1 解析普通对象

Gson是由Google提供的效率功能更强大

User u = new User ();
u.setUserId(123);
Gson gson = new Gson();
//把对象转换为json字符串
String userString = gson.toJson(u);
System.out.println(userString);
//把json字符串转换为实体bean对象
User user = gson.fromJson(userString,User.class);
System.out.println(user);

得到的结果:

{"userId":123}
User [userId=123]

1.4.2 解析泛型对象

有如下泛型对象:

@Data
public class PageList<T> {
    public List<T> body;
}

注意:必须引用构建谷歌的TypeToken对象

Gson gson = new Gson();
Type type = new TypeToken<PageList<User>>() {}.getType();
//此处的result是要解析的字符串
PageList<User> pageList = gson.fromJson(result, type);

1.5 JSONObject来解析和反解析

注意:如果用的是阿里的json类的话,JSONObjectJSON的子类

1.5.1 转为json对象或json字符串

User u = new User ();
u.setUserId(123);
//json对象
System.out.println(JSONObejct.toJSON(u));
//json字符串
System.out.println(JSONObejct.toJSONString(u));

得到的结果:

jsonObject:{"UserId":123}
jsonString:{"UserId":"123"}

1.5.2 反解析实体对象

1.5.2.1 反解析普通实体对象

//把json对象转换为实体对象
//第一个参数是JSON对象,第二个对象是要解析的实体类
User userObject =JSON.toJavaObject((JSON)JSONObejct.toJSON(u),User.class);
System.out.println(userObject);
//得到的结果
User{UserId=123}

//解析字符串
//第一个参数是json字符串,第二个参数是实体类
User userObject2 =JSON.parseObject(JSONObejct.toJSONString(u),User.class);
System.out.println(userObject2);
//得到的结果
User{UserId=123}

如果不想建立实体对象,而只想从JSONObject对象中获取某一个字段可以这样操作:

//解析字符串
//第一个参数是json字符串,第二个参数是实体类
JSONObject json =JSONObejct.parseObject(JSONObejct.toJSONString(u));
String userId= (String)json.get("UserId");
System.out.println(userId);

1.5.2.2 反解析泛型实体对象

使用TypeReference对象获得解析泛型对象
有如下泛型对象:

@Data
public class PageList<T> {
    public List<T> body;
}

可以使用如下方法解析:

//此处的result是json字符串
Result<PageList<User> result = JSONObject.parseObject(result, new TypeReference<Result<PageList<User>>>() {});

1.6 JSON引用和重复引用

简单说,重复引用就是一个集合/对象中的多个元素/属性同时引用同一对象,循环引用就是集合/对象中的多个元素/属性存在相互引用导致循环

1.6.1 重复引用

List<User> list = new ArrayList<>();
User user= new User();
list.add(user);
list.add(user);
System.out.println(JSONObject.toJSONString(list));
//得到的结果
[{"userId":"12"},{"$ref":"$[0]"}]

对于这个问题可以关闭json的引用检测:
JSONObject.toJSONString(list)里面添加SerializerFeature.DisableCircularReferenceDetect,如:JSONObject.toJSONString(list,SerializerFeature.DisableCircularReferenceDetect)

1.6.2 循环引用

// 循环引用的特殊情况,自引用
Map<String,Object> map = new HashMap<>();
map.put("map",map);
//
// map1引用了map2,而map2又引用map1,导致循环引用
Map<String,Object> map1 = new HashMap<>();
Map<String,Object> map2 = new HashMap<>();
map1.put("map",map2);
map2.put("map",map1);

对于循环引用,不能关闭json的引用检测,不然会报错java.lang.StackOverflowError,对于循环引用,最好的解决办法还是养成良好编程习惯

你可能感兴趣的:(java)