• JSONObject的底层原理&&常见方法的使用以及项目中的使用场景


    1、JSONObject的底层原理

    JSONObject是由阿里的com.alibaba.fastjson的工具包提供

    1、JSONObject底层维护的是Map,通过查看构造函数可以查看默认的map初始容量为16,并且判断是否维护无序还是有序分别创建的Map为HashMap和LinkedHashMap

    public JSONObject() {
        this(16, false);
      }
    public JSONObject(int initialCapacity) {
        this(initialCapacity, false);
      }
    public JSONObject(int initialCapacity, boolean ordered) {
        if (ordered) {
          this.map = new LinkedHashMap(initialCapacity);
        } else {
          this.map = new HashMap(initialCapacity);
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、JSONObject常使用的方法基本都是调用map来实现的

    举几个常见的方法:

    获取的是Object类型的,之后需要进行强制类型转换

    public Object get(Object key) {
      Object val = this.map.get(key);
      if (val == null && key instanceof Number) {
        val = this.map.get(key.toString());
      }
      return val;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    觉得麻烦的话JSONObject提供了多种类型去获取值的方式来避免不必要的类型转换导致可能存在精度丢失的风险

    最常见的就是使用getString,这也是我们在工作中经常使用的方式,可以发现最终都是通过map来完成一些列操作

    public String getString(String key) {
        Object value = this.get(key);
        return value == null ? null : value.toString();
      }
    
    • 1
    • 2
    • 3
    • 4

    如果想转换为我们自定义的类,可以使用

    public <T> T getObject(String key, Class<T> clazz) {
      Object obj = this.map.get(key);
      return TypeUtils.castToJavaBean(obj, clazz);
    }
    
    • 1
    • 2
    • 3
    • 4

    2、常见JSONObject的使用

    1、实体转JSON

    Article article = new Article();
    article.setTag("123456").setTitle("小爽帅到拖网速");
    Article article2 = new Article();
    article2.setTag("654321").setTitle("小爽帅到拖网速");
    String beanToJson = JSONObject.toJSONString(article);
    System.out.println(beanToJson);
    String bean2ToJson = JSONObject.toJSONString(article2);
    System.out.println(bean2ToJson);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意:JSONObject是用{}包裹一个对象,对象里边每一个冒号(:)前是属性,后是指,可以与map中的k=v联系在一起,逗号用来区分每对键值对的

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uXBXkVBX-1660006772808)(qinlin-thirdparty_government.assets/image-20220808181319470.png)]

    2、JSONObject中添加JSONObject

    JSONObject中是可以无限套娃的,只是每嵌套一次,就需要给除最外面的JSONObject以外的其他JSONObject中添加唯一的key,如果key重复了,会按照Map的处理方式去解决,一般都是判断如果key的hashCode相同,并且equals返回true,则会新值替换旧值,并且返回旧值,所以这里涉及到了数据覆盖的问题,需谨慎处理key是否相同的情况

    Article article = new Article();
    article.setTag("123456").setTitle("小爽帅到拖网速");
    Article article2 = new Article();
    article2.setTag("654321").setTitle("小爽帅到拖网速");
    String beanToJson = JSONObject.toJSONString(article);
    System.out.println(beanToJson);
    String bean2ToJson = JSONObject.toJSONString(article2);
    System.out.println(bean2ToJson);
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("beanToJson",beanToJson);
    jsonObject.put("beanToJson2",bean2ToJson);
    System.out.println(jsonObject.toJSONString());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FbJoThjg-1660006772809)(qinlin-thirdparty_government.assets/image-20220808181941616.png)]

    取值:

    Article article = new Article();
    article.setTag("123456").setTitle("小爽帅到拖网速");
    Article article2 = new Article();
    article2.setTag("654321").setTitle("小爽帅到拖网速");
    String beanToJson = JSONObject.toJSONString(article);
    System.out.println(beanToJson);
    String bean2ToJson = JSONObject.toJSONString(article2);
    System.out.println(bean2ToJson);
    
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("beanToJson",beanToJson);
    jsonObject.put("beanToJson2",bean2ToJson);
    // 可以发现{}里边包裹了两个JSONObject,每个JSONObject都有自己的{}
    System.out.println(jsonObject.toJSONString());
    // 根据对应的key取出value,类型还是为JSONObject
    System.out.println("beanToJson:"+jsonObject.get("beanToJson"));
    // 根据key取出JSON字符串后解析为Bean
    System.out.println("beanToJson:"+JSONObject.parseObject(jsonObject.getString("beanToJson"),Article.class));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N0QB3oTZ-1660006772810)(qinlin-thirdparty_government.assets/image-20220808182746503.png)]

    3、JSON转bean

    Article article = new Article();
    article.setTag("123456").setTitle("小爽帅到拖网速");
    String beanToJson = JSONObject.toJSONString(article);
    System.out.println(beanToJson);
    System.out.println(JSONObject.parseObject(beanToJson, Article.class));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    4、集合与JSON的互转

    方式一:

    String listToJson = JSONObject.toJSONString(articles);
    System.out.println("list转jsonStr:" + listToJson);
    JSONArray objects = JSONObject.parseArray(listToJson);
    System.out.println(objects.toString());
    Arrays.stream(objects.toArray()).forEach(System.out::println);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方式二:推荐

    String listToJson = JSONObject.toJSONString(articles);
    List<Article> articleList = JSONArray.parseArray(listToJson, Article.class);
    articleList.stream().forEach(System.out::println);
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    3、项目中使用场景

    很多业务项目中实体类bean跟数据库表中的字段并不是一一对应的,通常使用持久化技术mybatis来完成实体bean与数据库表中的字段进行映射,通常有两种方式来解决表中字段与实体bean属性名不一致而导致映射失败的问题

    1. 将查询出来的字段使用别名(映射的实体属性)
    2. 使用mybatis提供的resultMap完成属性映射

    往往基于业务限制和映射我们需要创建对应的实体DTO,但是如果该实体DTO使用场景单一,或者说只在一次完成的业务请求链路中使用,我们往往可以通过使用JSONObject来提供本次的服务调用

    注意:该方法思路只局限与单体对象,不建议使用JSONObject的数组去嵌套数据,会导致后期从json反解list,以及获取JSONObject中的属性时会比较繁琐

    使用JSONObject作为mapper接口的返回值,在sql查询出来的列名对应key,值对应value,存进JSONObject底层维护的Map,具体使用如下

    Service中调用mapper

    JONObject jsonObject = baseMapper.selectCommunityCode(id);
    
    • 1

    xxxMapper.xml

    <select id="selectACode" resultType="com.alibaba.fastjson.JSONObject">
            select
                a_code  aCode,
                address,
                a_id       aId,
                a_name aName,
                a_code  aCode
            from
                a_community
            where
                is_deleted = 0
                and a_id = #{id}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    使用时根据对应的k获取对应的value

    JSONObject communityCode = cacheComponent.getCommunityCode(message.getCommunityId());
    if (null != communityCode) {
        userLog.setFwbm(communityCode.getString("aCode"));
        userLog.setAzdz(communityCode.getString("address"));
        userLog.setXqid(communityCode.getString("aId"));
        userLog.setJlx(communityCode.getString("aName"));
        userLog.setMlph(communityCode.getString("aCode"));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    以上是个人的一些拙见,如果有什么问题欢迎在评论区下多多沟通交流!

  • 相关阅读:
    通信原理板块——利用香农公式对连续信道的信道容量计算
    tkinter绘制组件(31)——支点标题
    springboot整合es
    【紫光同创国产FPGA教程】【PGC1/2KG第六章】密码锁实验例程
    redis 事务,深入解读
    基于STM32结合CubeMX学习Free-RT-OS的源码之深入学习软件定时器实现过程
    Python配置OpenCV
    前端uniapp生成海报绘制canvas画布并且保存到相册【实战/带源码/最新】
    美摄科技匿名化处理解决方案,包含模糊、同色、马赛克、效果遮挡等各种形式
    SpringMVC 12 登录拦截验证、文件上传和下载
  • 原文地址:https://blog.csdn.net/weixin_46195957/article/details/126240352