Flutter实现json格式化输出

前言

自定义log时,往往需要我们把后台返回的json字符串格式化输出到控制台,方便我们调试。Android原生可以通过JSONObject等进行格式化,将字符串格式化。flutter中并没有那么便利的实现方式,因此需要我们手动转换。想直接看代码的可以直接点击 d_logger   github查看。这是本人编写的一个log日志管理,觉得对你有帮助的麻烦点个like,谢谢。

实现思路

在conver包下,dart为我们提供了json转换工具。可以利用这点,先把json字符串转换成相应的对象。由于json可能返回的是一个数组或对象,因此需要我们进行判断,获取正确的转换类型,再进行下一步转换操作。

if (json.startsWith("{")) { //is jsonObject
    Map<String, dynamic> decode = JsonCodec().decode(json);
    //...convert json
} else if (json.startsWith("[")) { //is jsonArray
    List decode = JsonCodec().decode(json);
    //...convert json
} 

由于转换对象的层级不确定,即map或list都可能相互嵌套。在此可以利用递归,对元素进行遍历输出。定义convert方法,传入待解析对象。判断传入的对象类型:Map、List、String、num、bool,以此对不同类型进行格式化。

解析Map或List时,需要返回考虑以下几种结果:

1.集合不是任何字段的结果 ;

2.集合为某个字段的结果,需要区分集合为空、不为空两种格式化。

请注意1和4处,集合不为任何字段内容时,首尾和内容都需要换行进行显示。而当集合为某个字段内容时(2和3),头部需要紧随字段内容,且当集合为空,则不需要重新换行,直接响应尾部。循环递归时,可根据传入对应的判断进行调控。

解析String时,需要把内容加上 "" 并返回内容。

解析num和bool时,直接返回当前内容即可。

需要注意,为了能够让结果清晰明了,不同层级之前都需要加上对应的空格。递归时传入当前递归深度,根据深度获取前置空格。

///获取缩进空白符
String getDeepSpace(int deep) {
  var tab = StringBuffer();
  for (int i = 0; i < deep; i++) {
    tab.write("\t");
  }
  return tab.toString();
}

按照以上思路,json格式化的最终代码如下:

/// [object]  解析的对象
/// [deep]  递归的深度,用来获取缩进的空白长度
/// [isObject] 用来区分当前map或list是不是来自某个字段,则不用显示缩进。单纯的map或list需要添加缩进
String _convert(dynamic object, int deep, {bool isObject = false}) {
  var buffer = StringBuffer();
  var nextDeep = deep + 1;
  if (object is Map) {
    var list = object.keys.toList();
    if (!isObject) {//如果map来自某个字段,则不需要显示缩进
      buffer.write("${getDeepSpace(deep)}");
    }
    buffer.write("{");
    if (list.isEmpty) {//当map为空,直接返回‘}’
      buffer.write("}");
    }else {
      buffer.write("\n");
      for (int i = 0; i < list.length; i++) {
        buffer.write("${getDeepSpace(nextDeep)}\"${list[i]}\":");
        buffer.write(_convert(object[list[i]], nextDeep, isObject: true));
        if (i < list.length - 1) {
          buffer.write(",");
          buffer.write("\n");
        }
      }
      buffer.write("\n");
      buffer.write("${getDeepSpace(deep)}}");
    }
  } else if (object is List) {
    if (!isObject) {//如果list来自某个字段,则不需要显示缩进
      buffer.write("${getDeepSpace(deep)}");
    }
    buffer.write("[");
    if (object.isEmpty) {//当list为空,直接返回‘]’
      buffer.write("]");
    }else {
      buffer.write("\n");
      for (int i = 0; i < object.length; i++) {
        buffer.write(_convert(object[i], nextDeep));
        if (i < object.length - 1) {
          buffer.write(",");
          buffer.write("\n");
        }
      }
      buffer.write("\n");
      buffer.write("${getDeepSpace(deep)}]");
    }
  } else if (object is String) {//为字符串时,需要添加双引号并返回当前内容
    buffer.write("\"$object\"");
  } else if (object is num || object is bool) {//为数字或者布尔值时,返回当前内容
    buffer.write(object);
  }  else {//如果对象为空,则返回null字符串
    buffer.write("null");
  }
  return buffer.toString();
}

如果有更好的实现方式欢迎留言讨论~

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值