Json协议参数校验在58APP上的设计与应用

Posted 58无线技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Json协议参数校验在58APP上的设计与应用相关的知识,希望对你有一定的参考价值。

背景

随着APP版本的迭代,Hybrid交互协议与页面跳转协议越来越多,带来了诸多问题。 如下:

  1. 协议文档平台更新不及时或者忘掉导致介入方使用时出现问题。

  2. server下发的协议信息出错导致hybrid调用或者页面跳转出错,无法统计线上协议出现的问题

  3. 对于必传参数没有合理的监控,导致有些必传参数会漏传

  4. 对Json协议解析成bean的解析器parser的重复编码,太过繁琐 针对以上各种问题,所以有了参数校验框架开发的初期思想。

方案探索

有了需要解决的问题,那么下一步就思考该如何解决这些问题。很快我们想到了第一套解决方案,注解方案。 自定义好注解,在工程里需要进行校验的数据bean上添加我们的注解。通过编译自动生成与bean对应的解析器parser,这个parer里注入了我们进行参数检查的代码。之后使用这套方案的时候发现与现在的工程兼容性不太好,具体的缺点下面会提到。 然后我们又想到了配置文件的方案,通过定义好配置文件作为参数检查的基准,下面详细介绍。

方案一

开始我们想到的注解方案像这样

public class JumpDemoParamsBen extends JumpParamsBaseBean{

    @JumpParams(key = "show",desc = "布尔")
    boolean show;

    @JumpParams(key = "string",desc = "string")
    String string;

    @JumpParams(key = "numbers",value = "[1,2,3,5,6]",desc = "数组")
    List<Integer> numbers;

    @JumpParams(key = "log",value = "{'log':'log1','log2':'log2'}",desc = "埋点数据")
    HashMap<String,String> hashMap;

    @JumpParams(key = "bean",desc = "bean")
    TabBean bean;

}

根据JumpParams注解生成Parser解析类动态生成解析方法,对解析异常信息进行记录埋点,对没有填充的字段设置默认值。然后通过反射调用生成的解析类。  

Json协议参数校验在58APP上的设计与应用

但是该方案不能做到通用,而且最大的问题是编译时注解使用的限制。如,编译时注解在编译期运行的生命周期通常扫描一个Lib库后生命周期就结束,这对于想要一次性获得所有库的注解信息变得非常难。以及再加上编译时注解对后期解析协议生成bean这一步骤约束非常大,同时Hybrid介入的时候需要对注解处理器做一些额外的处理,而且页面跳转与action触发频繁的反射调用parser也是不能接受的。由于这些原因所以直接导致我们放弃使用编译时注解方案,寻求新的解决方案。

方案二

方案一中我们把参数校验信息放在了注解中(包括每个参数字段名称,参数是否必传,参数默认值,参数字段的说明),然后根据注解信息为每个Json生成对应的解析类。但在开发后应用发现了比较多的缺点,所以为了避免这些缺点我们不得不另寻他路。最终我们提出了一个以配置文件校验参数的方案,我们需要一个json校验规则配置信息。我们编写的配置文件也需要一一对应如果使用Json做配置层级太深对开发者来说不好编写而且阅读性也不是很强。最终我们使用XML作为Json校验的配置文件规则

方案一主要是对Parser的自动处理开发者不用关心该过程只处理拿到Bean即可,有没有一种方案我们可以统一处理传过来的Json协议数据然后统一返回落地数据。我们小组经过思考和讨论确立了如下图的方案。

  1. 通过配置文件的方式作为参数校验的依据。

  2. 我们对输入的Json数据校验,完成校验之后把数据输出到Map,以数据在原Json的层级位置转成path存为key,值为校验后的值。

  3. 落地页通过path从map取值即可。 

Json协议参数校验在58APP上的设计与应用

方案二应用与实现

方案实现分三部分,第一部分ParamsCheck,校验参数的核心部分;第二部分主要是对参数校验的应用,目前会在{Action协议,跳转协议}用到

ParamsCheck

如何应用

1、定义Json协议

{
   "url":"http://www.58.com",
   "title":"58同城",
   "setting":{
      "showtitle":true,
      "pullRefresh":false
   }
}

2、根据协议配置XML文件

<?xml version="1.0" encoding="UTF-8"?>
<Action name ="common" desc="新Web载体页common">
    <param key="url" type="STRING" value="" level="1" desc="必填,加载url"/>
    <param key="title" type="STRING" value="" desc="选填,标题栏文案,默认为html页面内部的标题"/>
    <param key="setting" type="OBJECT" desc="UI展示设置">
         <param key="showtitle" value="true" type="BOOL" desc="是否展示标题栏"/>
         <param key="pullRefresh" value="false" type="BOOL" desc="是否支持下拉刷新"/>
    </param>
</Action>

如何校验

上面我们定义了一个协议,那参数校验框架是如何对协议进行校验的呢,下面我提出几个问题,然后对这几个问题逐个介绍。

我们可以做到哪些校验?

1、参数类型 如果参数类型与定义不符则记录

2、必传参数 如果在配置文件定义该参数为必传的,但协议数据没有传该参数,则记录

3、前端校验 在FE开发期间,如果没有必传参数可以及时给出提示。可以在开发期间避免必传参数没有

还有哪些我们期望做的校验但目前还不能做到的?

1、值的格式校验 目前只能做到协议key对应是否有值,而无法具体到值是什么样的格式

2、值的范围 假如对int类型的值定义了一个范围,不再范围以外的认为是错误的。

3、不同key的值相互具有关系 如果两个或多个key的值有一定关系,这种目前也无法办到

检测到问题是如何记录的?

在参数校验框架中发现问题并记录上报到应用方,记录的内容是具体出错的key,以所对应于协议中的路径keypath表示。应用方hybrid和跳转协议在app debug模式弹toatst提示,在release模式下以埋点方式上报到服务器,上报的信息包括出错的协议方或页面、error信息。

校验规则

关于校验规则我们更加注重统计出现错误的信息上报,这样APP上线后我们可以在后台及时发现server下发协议的问题并响应server及时的修改。

关于协议对于任何协议都会有必传字段和非必传字段。可以这么理解对于一个信息的详情页,信息的infoid就是一个必传字段跳转到详情页我们一定要给予一个infoid如果这个字段没有传的话或格式有误的话,跳转到详情也就无法正常展示。对于非必传字段表示协议可以不下发该字段,不下发的话我们会填充默认值。对于参数类型转换错误的我们会进行异常上报。以上即为参数校验的核心规则。

参数校验流程图

Json协议参数校验在58APP上的设计与应用


协议文档生成


Json协议参数校验在58APP上的设计与应用

由于我们配置了xml文件, 点击生成对应的业务线模块协议文档。 我们会匹配对应的xml生成改模块对应的json协议 ,然后上传到协议平台更新数据 。这样开发者就不需要每次手动去同步协议平台数据,在每次APP发版同步协议即可。

总结

使用该参数校验的好处

1、开发期间协议数据出错有提示,在开发期间就可以发现问题 2、动态协议的统计,如果同一协议规则有多个业务方在使用,那么可以记录具体是哪个业务方数据出错 3、确保必要的参数一定有 4、通过简单的操作可以使协议文档与具体实现保持统一,大大减小繁杂的协议文档维护成本

目前58app跳转中心与Hybrid框架已添加参数校验功能,对协议下发出错问题有了很好的把控。开发者不必在频繁的编写Parser和Bean,提升了开发效率。协议平台及时更新,让协议使用方能够正确的使用最新的协议。达到了我们的最终目的。

问题

目前该参数校验框架虽然已经基本达到最初的构思与目的,但是随着对参数校验和现在项目的结合上的理解加深,通过对应用该框架到现在项目上的付出成本和最终所获得的收益的比例不太符合我们的预期。所以目前不太适合在我们现有的项目上推广该框架。但是在新项目上还是推荐使用该框架。

以上是关于Json协议参数校验在58APP上的设计与应用的主要内容,如果未能解决你的问题,请参考以下文章

iOS中基于协议的路由设计

协议缓冲区如何比 XML 和 JSON 快?

接口安全校验

谁家的加密密钥,写死在代码里?(说的就是你)

UDP协议:UDP和TCP相比快在哪里?

请求参数完整性校验,解决流只能写一次的问题