首先假设有一个实体对象user:
private Integer UserId;
private Integer getUserId (){
return UserId;
}
private Integer setUserId(Integer UserId){
this.UserId = UserId;
}
用的是com.alibaba.fastjson.JSON的包,用的是toJSON方法
在实体对象的每个get方法上添加@JSONField(name=“UserId”)
就可以有效避免,首字母小写的问题
@JSONField(name="UserId")
private Integer getUserId (){
return UserId;
}
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"}
//把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
方法才能直接输出对象里面的每个属性。
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]
有如下泛型对象:
@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);
注意
:如果用的是阿里的json
类的话,JSONObject
是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"}
//把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);
使用TypeReference
对象获得解析泛型对象
有如下泛型对象:
@Data
public class PageList<T> {
public List<T> body;
}
可以使用如下方法解析:
//此处的result是json字符串
Result<PageList<User> result = JSONObject.parseObject(result, new TypeReference<Result<PageList<User>>>() {});
简单说,重复引用就是一个集合/对象中的多个元素/属性同时引用同一对象,循环引用就是集合/对象中的多个元素/属性存在相互引用导致循环
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)
// 循环引用的特殊情况,自引用
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
,对于循环引用,最好的解决办法还是养成良好编程习惯