1. JSON 基础
- https://www.json.org/json-en.html
- JSON Object
- JOSN Array
- JSON对象
- 键必须是字符串
- 值可以是对象、数组、数字、字符串或者三个字面值(false、true、null 字面值必须是小写英文字母)
- JSON 是一种数据格式,不支持注释
1.1 JSON 嵌套
[{}, {}]
{"key1":[], "key2":[]}
2. JSON 解析器
- Fastjson
- Gson
- Jackson
- Json-lib
2.1 Fastjson
- 在转化过程中使用到的对象,一定要有 get/set 方法和无参构造函数
2.2 Gson
2.3 Jackson
- SpringBoot 默认内置的是 Jackson
- 启动类 implements WebMvcConfigurer ,复写 configureMessageConverters
2.4 Json-lib
- 依赖很多第三方包
3. Fastjson
- com.alibaba.fastjson.*
3.1 JSON
- JSON 类的方法基本都是静态方法
-
toJSONString()
会将日期转成时间戳,要想将日期转化成指定格式的字符串,可以使用toJSONStringWithDateFormat()
public abstract class JSON implements JSONStreamAware, JSONAware {
public static String toJSONString(Object object) {
return toJSONString(object, emptyFilters);
}
public static String toJSONString(Object object, SerializerFeature... features) {
return toJSONString(object, DEFAULT_GENERATE_FEATURE, features);
}
public static <T> T parseObject(String text, TypeReference<T> type, Feature... features) {
return (T) parseObject(text, type.type, ParserConfig.global, DEFAULT_PARSER_FEATURE, features);
}
}
3.2 JSONObject
JSONObject 实现 Map 接口,而且定义了一个map字段,在初始化的时候可根据是否需要有序来初始化为 LinkedHashMap 或者 HashMap
JSONObject 相当于一个 Map,当操作JSONObject的时候,其实是调用了Map的方法
public class JSONObject extends JSON implements Map<String, Object>, Cloneable, Serializable, InvocationHandler {
private final Map<String, Object> map;
}
json 串序列化与反序列化
// 序列化
String str = JSON.toJSONString(new User("tinspot", 20));
// 反序列化
User user = JSON.parseObject(str, User.class);
3.3 JSONArray
JSONArray productArray = JSONArray.parseArray(payments);
List<User> userList = JSONArray.parseArray(jsonStr, User.class);
String jsonStr = "[{\"age\":20,\"name\":\"tinyspot\"},{\"age\":22,\"name\":\"echo\"}]";
// Unchecked assignment: 'java.util.List' to 'java.util.List<com.example.concrete.pojo.User>'
// 实际是 ArrayList<JSONObject>
List<User> list = JSONObject.parseObject(jsonStr, List.class);
// java.lang.ClassCastException
System.out.println(list.get(0).getAge());
// 正确方式
List<User> list2 = JSONObject.parseObject(jsonStr, new TypeReference<List<User>>() {});
List --> JSONArray
List<T> list = new ArrayList<T>();
JSONArray array = JSONArray.parseArray(JSON.toJSONString(list));
3.4 转化为 Map
- 含有泛型的 JSON 反序列化
public static void main(String[] args) {
String str = "{\"name\":\"Tinyspot\",\"age\":20}";
// 没有泛型 是不安全的
Map map = JSON.parseObject(str);
// 使用 TypeReference 但构造方法是 protected ,用子类 匿名内部类 new TypeReference<Map<Integer, User>>(){}
// TypeReference<Map<Integer, User>> typeReference = new TypeReference<Map<Integer, User>>() {};
Map<Integer, User> userMap = JSON.parseObject(str, new TypeReference<Map<Integer, User>>(){});
}
Map<Integer, List<User>> userMap = JSON.parseObject(JSON.toJSONString(userList), new TypeReference<Map<Integer, List<User>>>(){});
Type type = new TypeReference<Map<Integer, List<User>>>(){}.getType();
Map<Integer, List<User>> userMa2p = JSON.parseObject("{...}", type);
分析
public class TypeReference<T> {
// protected 类型的构造方法,包外若要创建对象只能使用子类
protected TypeReference() {}
}
3.5 JSON 遍历
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("key", "value");
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
}
for (String s : jsonObject.keySet()) {
}
String str = "{\"users\":[{\"name\":\"tinyspot\",\"age\":20},{\"name\":\"xing\",\"age\":25}]}";
Map<String, List<User>> userMap = JSON.parseObject(str, new TypeReference<Map<String, List<User>>>(){});
for (Map.Entry<String, List<User>> entry : userMap.entrySet()) {
for (User user : entry.getValue()) {
System.out.println(user.getName() + "; " + user.getAge());
}
}
}
3.6 SerializerFeature 枚举类
- 设置序列化特性
// SerializerFeature... features 可以传多个
public static String toJSONString(Object object, SerializerFeature... features) {
return toJSONString(object, DEFAULT_GENERATE_FEATURE, features);
}
public static void main(String[] args) {
String str = "{\"name\":\"Tinyspot\",\"age\":20}";
User user = new User();
user.setName("Tinyspot");
// user.setAge(20);
user.setBirthday(new Date());
// WriteMapNullValue 字段null 序列化为 null
String jsonStr = JSON.toJSONString(user, SerializerFeature.WriteMapNullValue);
// {"age":20,"name":null}
// WriteMapNullValue 字段null 序列化为""
jsonStr = JSON.toJSONString(user, SerializerFeature.WriteNullStringAsEmpty);
// {"age":20,"name":""}
// WriteMapNullValue 字段null 序列化为""
jsonStr = JSON.toJSONString(user, SerializerFeature.WriteNullNumberAsZero);
// {"age":0,"name":"Tinyspot"}
// 格式化日期
jsonStr = JSON.toJSONString(user, SerializerFeature.WriteDateUseDateFormat);
jsonStr = JSON.toJSONString(user, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.PrettyFormat);
System.out.println(jsonStr);
}
@Data
static class User {
private String name;
private Integer age;
private Boolean flag;
private Date birthday;
}
DisableCircularReferenceDetect 消除对同一对象循环引用的问题,默认为false
String s = JSON.toJSONString(user, SerializerFeature.DisableCircularReferenceDetect);
3.7 @JSONField
- name 指定序列化后的名字
- ordinal 指定序列化的顺序
- serialize 是否序列化
- deserialize 是否反序列化
- serialzeFeatures 序列化时的特性定义
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface JSONField {
}
@Data
public class User {
@JSONField(name = "userName", ordinal = 1)
private String name;
@JSONField(ordinal = 2)
private Integer age;
@JSONField(serialize = false)
private Boolean flag;
@JSONField(format = "yyyy-MM-dd")
private Date birthday;
}
3.8 @JSONType
- includes 要被序列化的字段
- orders 指定顺序
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface JSONType {
}
示例:
@JSONType(includes = {"name", "age"}, orders = {"name", "age"})
public class User {
private String name;
private Integer age;
private Boolean flag;
private Date birthday;
}
4. JSON 的优缺点
- 缺点
- 不支持注释
- 不支持多行字符串
网友评论