JSON的使用、利用正则表达式解决不定类型返回Json格式

来源:互联网 发布:怎样重新申请淘宝账号 编辑:程序博客网 时间:2024/06/03 22:03

介绍

作为移动端开发者,和服务器的通信是少不了了。下面我总结一我在开发中遇到有关json的问题

一般的Json

在我刚入门的时候,在公司的写代码当时的网络返回也不复杂,10个字段以内,基本上熟悉Json的固定格式,手动写Bean接收数据,只要用心字段名称和类型对应就不会出问题。
推荐的Json格式校验网站,http://json.parser.online.fr/

问题:就是如果字段复杂,就要花很多时间去校对字段,确认字段对象类型。

解决办法

其实校验Json格式这种没什么技术含量的事情,应该交给计算机去做。
所以网上有很多解决办法

在线解析生成Bean对象

网站在这里: http://www.bejson.com/json2javapojo/

GsonFormat插件

这是个一个能够直接在Android Studio运行的插件。输入Json字符串能够直接生成bean对象

  • 安装
    安装如下图:
    设置
    选择 Plugins->搜索GsonFormat
    选择
  • 使用
    快捷键 Alt+Instert 弹出GsonFormat
    复制Json字符串进去就OK了。

    不定格式的Json

    最近在写个项目,接口来自其他公司网络返回,有一个巨坑的问题,
    不定格式的Json内容。

  • 有时是avatar:{"对象类型"}

  • 有时是avatar:"String类型"
  • 其实就一个关键的url头像地址最重要。如果是对象类型,对象中就包含一些图片信息和url地址,如果是String类型就直接是一个url图片地址。
    直接使用定义为对象的话就会出现异常
    异常信息:参数异常,需要的解析的Bean该字段对应的是Object对象,但Json字符串中对应的是String对象。

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 14210 path $.pin.repins[1].user.avatar

非常非常的坑爹!!

思考

  • 从Json解析之后的Bean对象处理是不行的,因为一开始的解析就报错。
  • 想从Gson解析上看看有什么特别的功能,从文档上看没有有效的解决办法。有人找到的给个提示。

最终的解决办法

正则表达式
在网络数据还没解析成Bean对象之前,处理成字符串,用正则对该字符串进行处理。

正则表达式,在网络返回后将二进制流时转换成字符串,正则表达式匹配查找取出其中url关键数据,替换统一成avatar:"String类型"

下面贴一部分实现代码

说明:我的网络访问使用的是Retrofit,是Jack大神开发的REST风格的网络访问框架。以下代码关键是在retrofit.Converter.Factory上得到二进制网络返回体上做修改,其他网络框架也可以,只要能到网络访问体即可。

网络字节流转字符串

  @Override        public T convert(ResponseBody value) throws IOException {            Reader reader = value.charStream();//取出字节流            String result;            try {                BufferedReader in = new BufferedReader(reader);//读取                StringBuffer buffer = new StringBuffer();//构造buffer对象用于拼接                String line;                while ((line = in.readLine()) != null) {//读行                    buffer.append(line);//写入buffer                }                result = buffer.toString();            } finally {                Utils.closeQuietly(reader);//记得关闭流            }            return gson.fromJson(regexChange(result), type);//返回解析后的对象        }

正则表达式在Java的应用

 /**         * 对输入的字符串进行处理         * @param input 传入的需要处理的字符串         * @return         */        private String regexChange(String input) {            String result=input;            //匹配规则是当avatar是{}包装的对象            Pattern mPAvatar=Pattern.compile("\"avatar\":\\{([^\\}]*)\\}");            Matcher mMAvatar=mPAvatar.matcher(result);            while (mMAvatar.find()){//如果找到 开始替换                result=result.replaceFirst("\"avatar\":\\{([^\\}]*)\\}",getKey(mMAvatar.group()));            }            return result;        }/**         * 取出关键值返回            * @param group         * @return         */        private String getKey(String group) {            Matcher matcher=mPkey.matcher(group);            StringBuffer buffer=new StringBuffer();             buffer.append("\"avatar\":\"http:///");            while (matcher.find()){                buffer.append(matcher.group(1));            }            buffer.append("\"");            return buffer.toString();        }

完美解决~~

另一种解决办法

这在是一篇博客看到的,也是在Retrofit上应对不定格式的Json格式解析,思路也是在也是Converter.Factory的convert方法上做处理。思路是定义两个不同的Bean类型,捕捉异常,做二次解析。不符合我的项目使用,只做介绍。
具体实现看博客:http://blog.csdn.net/efan006/article/details/50544204

总结

  1. 以上就是我对Json在Android编程中的一些理解和实际应用。
  2. 运用工具快速开发,把时间花在业务逻辑处理而不是重复的劳动。
  3. 对问题能够换语言环境理解思考解决问题。
(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(  \n  ).length;var numbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(  hasnumbering  ).parent().append( numbering); for (i = 1; i
0 0
原创粉丝点击