1. Fastjson 简介
- 包:com.alibaba.fastjson.*
- JSON 类里基本都是静态方法
2. JSON 类
image.pngpublic 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 String toJSONStringWithDateFormat(Object object, String dateFormat, SerializerFeature... features) {
return toJSONString(object, SerializeConfig.globalInstance, null, dateFormat, 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);
}
}
2.1 JSON串序列化与反序列化
@Test
public void test() {
// 序列化
String jsonStr = JSON.toJSONString(new Order(1001L, "R001"));
// 反序列化
Order order = JSON.parseObject(jsonStr, Order.class);
}
2.2 日期处理
toJSONString() 会将日期转成时间戳
@Test
public void test() {
Order order = new Order(1001L, "R001", new Date());
String jsonStr = JSON.toJSONString(order);
// 日期格式化
String jsonDateStr = JSON.toJSONStringWithDateFormat(order, "yyyy-MM-dd HH:mm:ss");
}
打印结果
jsonStr: {"code":"R001","date":1676694709297,"id":1001}
jsonDateStr: {"code":"R001","date":"2023-02-18 12:31:49","id":1001}
3. JSONObject
public abstract class JSON implements JSONStreamAware, JSONAware {
public static JSONObject parseObject(String text) {
}
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.1 对象互转
-
JSON串 --> JSONObject
JSONObject jsonObj = JSON.parseObject(jsonStr);
-
Java 对象 --> JSONObject
JSONObject jsonObj = JSON.parseObject(JSON.toJSONString(order));
-
JSONObject --> Java 对象
Order order = JSON.parseObject(jsonStr, Order.class);
-
JSON串 --> Java 对象(带泛型)
@Test
public void test() {
OrderDTO order = new OrderDTO(1001L, "R001", new Date());
ResultDTO<OrderDTO> resultDTO = new ResultDTO<>(order, true);
String jsonStr = JSON.toJSONString(resultDTO);
// {"data":{"code":"R001","date":1676695213857,"id":1001},"success":true}
// 带泛型
ResultDTO<OrderDTO> result = JSON.parseObject(jsonStr, new TypeReference<ResultDTO<OrderDTO>>() {});
}
@Data
@AllArgsConstructor
public class ResultDTO<T> {
private T data;
private boolean success;
}
@Data
@AllArgsConstructor
public class OrderDTO {
private Long id;
private String code;
private Date date;
}
3.2 JSONObject 源码
public class JSONObject extends JSON implements Map<String, Object>, Cloneable, Serializable, InvocationHandler {
private final Map<String, Object> map;
public JSONObject(){
this(DEFAULT_INITIAL_CAPACITY, false);
}
public JSONObject(int initialCapacity, boolean ordered){
if (ordered) {
map = new LinkedHashMap<String, Object>(initialCapacity);
} else {
map = new HashMap<String, Object>(initialCapacity);
}
}
public Object put(String key, Object value) {
return map.put(key, value);
}
}
JSONObject 实现 Map 接口,而且定义了一个map字段,在初始化的时候可根据是否需要有序来初始化为 LinkedHashMap 或者 HashMap
JSONObject 相当于一个 Map,当操作 JSONObject 的时候,其实是调用了Map的方法
4. JSONArray
-
JSON串 --> JSONArray
JSONArray jsonArray = JSON.parseArray(jsonStr);
-
JSON串 --> List
List<Order> orderList = JSON.parseArray(jsonStr, Order.class);
-
List --> JSONArray
@Test
public void test() {
List<String> list = Arrays.asList("aaa", "bbb");
JSONArray array = JSON.parseArray(JSON.toJSONString(list));
List<String> strings = JSON.parseArray(JSON.toJSONString(list), String.class);
}
4.2 反例
注意不要用 JSONObject.parseObject()
来转换 List
@Test
public void test() {
String jsonStr = "[{\"code\":\"R001\",\"date\":1676703926184,\"id\":1001},{\"code\":\"R002\",\"date\":1676703926184,\"id\":1002}]";
// Unchecked assignment: 'java.util.List' to 'java.util.List<com.example.concrete.starter.pojo.Order>'
List<Order> orderList = JSONObject.parseObject(jsonStr, List.class);
System.out.println(orderList + "; " + orderList.get(0)); // 正常打印
System.out.println(orderList.get(0).getCode()); // 异常
}
分析
orderList.get(0).getCode()
报错:java.lang.ClassCastException,因为 orderList 实际是 ArrayList<JSONObject>,并未转为真正需要的泛型 List<Order>
5. 泛型处理(TypeReference)
JSON串转为 Map,含有泛型的 JSON 反序列化
5.1 JSON串 --> Map<String, Object>
@Test
public void test() {
Map<String, Order> orderMap = new HashMap<String, Order>(){{
put("001", new Order(1001L, "T001"));
put("002", new Order(1002L, "T002"));
}};
String jsonStr = JSON.toJSONString(orderMap);
// 没有泛型 是不安全的
Map map = JSON.parseObject(jsonStr);
// TypeReference 但构造方法是protected,所以使用它的子类
// 用匿名内部类作为 TypeReference 子类
TypeReference<Map<String, Order>> typeReference = new TypeReference<Map<String, Order>>() {};
Map<String, Order> result = JSON.parseObject(jsonStr, typeReference);
}
5.2 JSON串 --> Map<String, List<Object>>
@Test
public void test() {
Map<Integer, List<Order>> data = new HashMap<Integer, List<Order>>() {{
put(2022001, Arrays.asList(new Order(1001L, "T001")));
put(2022002, Arrays.asList(new Order(1002L, "T002")));
}};
String jsonStr = JSON.toJSONString(data);
Map<Integer, List<Order>> map = JSON.parseObject(jsonStr, new TypeReference<Map<Integer, List<Order>>>() {});
// 方式一:使用 Type
Type type = new TypeReference<Map<Integer, List<Order>>>(){}.getType();
Map<Integer, List<Order>> resultMap = JSON.parseObject(jsonStr, type);
// 方式二
Map<Integer, List<Order>> integerListMap = JSON.parseObject(jsonStr, new TypeReference<Map<Integer, List<Order>>>() {});
}
5.3 解析泛型对象
@Test
public void test() {
String jsonStr = "{\"data\":{\"code\":\"R001\",\"date\":1676695213857,\"id\":1001},\"success\":true}";
ResultDTO<OrderDTO> result = JSON.parseObject(jsonStr, new TypeReference<ResultDTO<OrderDTO>>() {});
jsonStr = "{2022002:[{\"code\":\"T002\",\"id\":1002}],2022001:[{\"code\":\"T001\",\"id\":1001}]}";
Map<Integer, List<Order>> map = JSON.parseObject(jsonStr, new TypeReference<Map<Integer, List<Order>>>(){});
}
5.2 TypeReference 源码分析
public class TypeReference<T> {
// 构造方法是 protected,包外若要创建对象只能使用子类
protected TypeReference(){
Type superClass = getClass().getGenericSuperclass();
Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
Type cachedType = classTypeCache.get(type);
if (cachedType == null) {
classTypeCache.putIfAbsent(type, type);
cachedType = classTypeCache.get(type);
}
this.type = cachedType;
}
}
用匿名内部类作为 TypeReference 子类
TypeReference<Map<String, Object>> typeReference = new TypeReference<Map<String, Object>>() {};
5.3 对象拷贝
方式一:import org.springframework.beans.BeanUtils;
BeanUtils.copyProperties(dataDTO, dataTarget);
缺点:受限于属性类型,比如 Long 类型无法赋值给 String 类型
方式二:
DataTarget target = JSON.parseObject(JSON.toJSONString(dataDTO), DataTarget.class);
6. 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());
}
}
}
网友评论