美文网首页
Fastjson 基础

Fastjson 基础

作者: Tinyspot | 来源:发表于2023-02-18 07:42 被阅读0次

    1. Fastjson 简介

    • 包:com.alibaba.fastjson.*
    • JSON 类里基本都是静态方法

    2. JSON 类

    image.png
    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 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 对象互转

    1. JSON串 --> JSONObject
      JSONObject jsonObj = JSON.parseObject(jsonStr);

    2. Java 对象 --> JSONObject
      JSONObject jsonObj = JSON.parseObject(JSON.toJSONString(order));

    3. JSONObject --> Java 对象
      Order order = JSON.parseObject(jsonStr, Order.class);

    4. 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

    1. JSON串 --> JSONArray
      JSONArray jsonArray = JSON.parseArray(jsonStr);

    2. JSON串 --> List
      List<Order> orderList = JSON.parseArray(jsonStr, Order.class);

    3. 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());
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Fastjson 基础

          本文链接:https://www.haomeiwen.com/subject/udxvkdtx.html