目录

  • 目录
  • json简介
  • 服务端校验参数需求分析
  • json参数检验简单而繁琐方式
  • Json Schema
    • Json Schema 入门
  • Json Schema 表达式
    • string
    • Numeric types
    • object
    • array
    • boolean
    • null
  • 实战演习
  • 总结
  • 原文地址
  • 参考文献

json简介

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。
举个栗子:

{ "an": [ "arbitrarily", "nested" ], "data": "structure" }

服务端校验参数需求分析

参数检测是服务器端拿到参数的第一步操作,后续的一系列操作都完全信任数据的可靠安全性。可以准确的说,前端的参数校验是为了适当的保护服务端,为了更好的用户体验,但服务端万万不可信任前端传递的参数,所有的参数一定要进行校验,确保输入数据是合法正确性,这是服务端程序员的基本准则。常见的参数检验包括非空,最大长度检测,大小检测等等。应用在执行业务逻辑之前,必须通过校验保证接受到的输入数据是合法正确的,但很多时候同样的校验出现了多次,在不同的层,不同的方法上,导致代码冗余,浪费时间。

json参数检验简单而繁琐方式

可以针对每个字段,进行一系列的参数校验,然后完成该json参数的检验。
举个栗子:

dict = { "an": [ "arbitrarily", "nested" ], "data": "structure" }
if dict.get(data, '')=='':return 'key data is no null'
if len(dict.get(data, ''))>30:return "data is too long"
other verify

就是这样不断的针对每一个字段进行校验,确保输入的数据的可靠、安全性。
缺点:很多时候同样的校验出现了多次,在不同的层,不同的方法上,导致代码冗余,浪费时间。比如校验是否为空,检验长度对大等等大量重复代码,效率很低。

Json Schema

相信用过flask-wtf的同学都会很喜欢这样的校验工具,自动对每个字段进行,而且效率还很高,不用写大量的重复代码,开发效率会得到大大的提升。反正我在用html的表单提交时都会使用flask-wtf,只能说,你用过一次就会爱上它。
那么当前端提交的数据不是form而是json时怎么办呢?如果不想像上面一样每个字段或者每个数据都一一检测,这时候你可以尝试使用json schema,很像flask-wtf的一个开源框架,专门用来校验json或者可以转换成json的dict。

Json Schema 入门

先举个栗子,大致说一下json schema怎么用

>>> from jsonschema import validate>>> # A sample schema, like what we'd get from json.load()
>>> schema = {
...     "type" : "object",
...     "properties" : {
...         "price" : {"type" : "number"},
...         "name" : {"type" : "string"},
...     },
... }>>> # If no exception is raised by validate(), the instance is valid.
>>> validate({"name" : "Eggs", "price" : 34.99}, schema)>>> validate(
...     {"name" : "Eggs", "price" : "Invalid"}, schema
... )                                   # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):...i
ValidationError: 'Invalid' is not of type 'number'

你可以使用validate来验证输入的json是否符合你需要的模式,如果不符合要求会抛出ValidationError异常,ValidationError.message 会提示不符合哪个要求或哪个要求出错,ValidationError.instance会提示是不符合该要求的字段的内容或者实例是什么。具体的schema 的表达式该怎么写后面会介绍到。

Json Schema 表达式

json schema的表达式在这里就讲点基本的好了,其实基本的已经够用了,如果要想更深入学习,可以到官网json schema进行学习。
json schema能支持的类型有string,Numeric types,object,array,boolean,null。接下来会一一解释。

string

举个例子来说明:

{"type": "string","minLength": 2,"maxLength": 3
}
'A' is wrong,  'aa' is ok, 'aaa' is ok ,'aaaasf' is wrong

这表明它需要一个string字段,其中string 有的属性有:

  • minLength
  • maxLength
  • pattern (正则表达式验证)
  • format (目前支持:”date-time”,”email”,”hostname”,”ipv4”,”ipv6”,”uri”, 如果没有你需要的格式,你可以用pattern 的正则表达式来完成)

Numeric types

老惯例,上来举个例子:

{"type": "number","minimum": 0,"maximum": 100,"exclusiveMaximum": true
}
ok:
0
10
99
wrong:
-1
100
101

这表明它需要一个Numeric types字段,其中number有的属性有:

  • type(integer,number)
  • multipleOf(要求该数字是这个数的整数倍)
  • minimum 、exclusiveMinimum 、maximum 、exclusiveMaximum (最大值、最小值以及是否包含该最大最小值)

object

在Python中,object类似于dict类型,”type”:”object”就是声明需要dict类。举个例子,就能大致理解了:

{"type": "object","properties": {"number":      { "type": "number" },"street_name": { "type": "string" },"street_type": { "type": "string","enum": ["Street", "Avenue", "Boulevard"]}}
}
ok:
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }
{ "number": 1600, "street_name": "Pennsylvania" }
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" }
wrong:
{ "number": "1600", "street_name": "Pennsylvania", "street_type": "Avenue" }

这表明它需要dict的类型。object具有的属性有:

  • additionalProperties: 是否可以需要多其它的字典关键字。例如”additionalProperties”: { “type”: “string” }表明允许多的关键字必须是string类型,additionalProperties:false则表明不允许多其它的关键字。
  • required:表明必须要有该关键字,例如 “required”: [“number”, “street_name”] 必须要有这number和street_name这两个key。
  • minProperties,maxProperties 表明这个字典最少、最多拥有多少个keys。
  • dependencies:依赖属性,例如 “dependencies”: { “credit_card”:[“billing_address”]}表明有credit_card是必须有billing_address这个key。
  • patternProperties:key为正则表达式。例如”patternProperties”: {“^S_”: { “type”: “string” }},需要S_开头key

    array

    array对应python里的[],可以是列表也可以是原组,举个例子:

{"type": "array","items": [{"type": "number"},{"type": "string"},{"type": "string","enum": ["Street", "Avenue", "Boulevard"]},{"type": "string","enum": ["NW", "NE", "SW", "SE"]}]
}
则
[1600, "Pennsylvania", "Avenue", "NW"] is ok“Drive” is not one of the acceptable street types:
[24, "Sussex", "Drive"] is wrongThis address is missing a street number
["Palais de l'Élysée"] is wrongIt’s okay to not provide all of the items:
[10, "Downing", "Street"] is okAnd, by default, it’s also okay to add additional items to end:
[1600, "Pennsylvania", "Avenue", "NW", "Washington"] is ok

item具有的属性是:
- additionalItems :该additionalItems关键字控制是否有效有超出了所定义的数组中的其他项目items。在这里,我们将重用上面的示例模式,但设置 additionalItems为false,这会导致不允许数组中的额外项。
- minItems、maxItems:minItems和 maxItems关键字指定数组的长度。每个关键字的值必须是非负数。
- Uniqueness:模式可以确保数组中的每个项都是唯一的。只需将uniqueItems关键字设置为true。

boolean

在Python中,“boolean”类似于bool。请注意,在JSON中, true它false是小写的,而在Python中它们是大写的(True和False)。
举个例子:

{ "type": "boolean" }
OK:
true
false
wrong:
"true"
0

布尔类型只匹配两个特殊值:true和 false。请注意,架构不接受评估为true或的值false,例如1和0

null

在Python中,null类似于None。

{ "type": "null" }
ok:
null
wrong:
false
0
""

null类型通常用于表示缺失值。当模式指定a type时null,它只有一个可接受的值:null

实战演习

USERS_SCHEMA = {"type": "object","required": ["users"],"properties": {"users": {"type": "array","items": {"type": "object","required": ["name", "email"],"properties": {"name": {"type": "string","minLength": 1,"maxLength": 30,},"primary_sector": {"type": "string","maxLength": 60,},"second_sector": {"type": "string","maxLength": 60,},"tertiary_sector": {"type": "string","maxLength": 60,},"email": {"type": "string","minLength": 1,"maxLength": 60,"pattern":  '^([a-zA-Z0-9]+[-_.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[-_.]?)*'\'[a-zA-Z0-9]+\.[a-zA-Z]{2,6}$',}},},},},
}

用来对应的符合要求的json是

{"users":{[{"name": "hello","primary_sector": "一级部门","second_sector": "二级部门","tertiary_sector": "三级部门","email" : "邮箱",}],[{"name": "hello1","primary_sector": "一级部门","second_sector": "二级部门","tertiary_sector": "三级部门","email" : "邮箱",}],}
}

可以一次性验证json里含有多有输入用户资料的json,也可以验证一个或者多个user。

总结

Json Schema给人感觉比较像在写json正则表达式,按着基本的帮助文档和知道,通过组合基本就能写出你需要的json验证格式,然后验证的时候只需要一句validate()就可以了,如果验证失败会抛出异常。建议以后验证json格式还是习惯使用这种验证方式,会大大提高开发效率。
上面是我的一些个人理解和看法,如果有错误,请多指教。

原文地址

原文地址:https://blog.csdn.net/aizenggege/article/details/82709790

参考文献

https://json-schema.org/understanding-json-schema/reference/null.html
http://imweb.io/topic/56b1b4bb5c49f9d377ed8ee9
http://taobaofed.org/blog/2016/01/25/jsonschema/
https://cloud.tencent.com/developer/article/1005810

服务端json参数校验神器Json Schema相关推荐

  1. 在Android中调用KSOAP2库访问webservice服务出现的服务端传入参数为null的问题解决

    在Android中调用KSOAP2库访问webservice服务出现的服务端传入参数为null的问题解决 参考文章: (1)在Android中调用KSOAP2库访问webservice服务出现的服务端 ...

  2. 浅析web api的json参数校验

    前言 以前api接口大家用得比较多的是表单方式传值,现在越来越流行使用json参数类型. 正文 下面从php.golang两个语言在json的使用上做一些说明. php的处理json的两个方法名叫: ...

  3. 腾讯应用宝米大师直购模式支付流程以及服务端php回调校验

    一. 米大师简介 1.米大师(Midas)为腾讯官方唯一虚拟支付平台. 2.YSDK已经内置了米大师(Midas)支付模块,游戏开发者接入YSDK后,可以通过相应的配置开启米大师的支付功能,并调用YS ...

  4. OPPO手机支付流程以及服务端php回调校验

    OPPO手机支付流程如下: 1.前端拉起商品列表 用户登录app后,进入商品购买页面,前端请求app商品列表api接口,获取商品列表信息并展示 2.下单 用户点击'购买'操作,发送给服务端一条当前商品 ...

  5. 解决 -- java 调用webservice 服务端收到参数为null

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 我的客户端和服务端都写的很简单,只是调用服务的时候, 服务端得不到参数,后来发现只改一个地方就可以了 ...

  6. springboot+dubbo+validation 进行 rpc 参数校验

    注意:本文dubbo 版本 2.8.4 springboot 版本 2.0.4.RELEASE 项目结构 test-rest (前端消费着,controller 层,springboot+maven项 ...

  7. 校验json格式_不来学一下SpringBoot统一参数校验?

    微服务架构之春招总结:SpringCloud.Docker.Dubbo与SpringBoot 一个SpringBoot问题就干趴下了?我却凭着这份PDF文档吊打面试官. 金三银四第一天,啃透这些Spr ...

  8. 华为内支付流程以及服务端php校验

    一.简介 华为应用内支付服务(In-App Purchases,IAP)为App提供便捷的应用内支付体验和简便的接入流程.App通过集成华为应用内支付SDK,再调用SDK接口启动IAP收银台,即可实现 ...

  9. boot spring 对参数检测_【springboot】@Valid参数校验

    转自: https://blog.csdn.net/cp026la/article/details/86495659 扯淡: 刚开始写代码的时候对参数的校验要么不做.要么写很多类似 if( xx == ...

最新文章

  1. 参考文献必备神器:这个插件能快速知道收藏的论文是否靠谱
  2. yolov5和yolov5-face nms比较
  3. 吴恩达《Machine Learning》精炼笔记 9:PCA 及其 Python 实现
  4. tp3.2php开启事务,ThinkPHP 3.2.2实现事务操作的方法
  5. POJ 2967 (水题,考察putchar()按位输入)
  6. Kubernetes-卷/存储卷(emptyDir/hostPath/pv/pvc)(十)
  7. 马化腾朋友圈晒微信支付分:835;爱奇艺回应用户隐私话题;Firefox 77.0 发布| 极客头条...
  8. linux终端中书名号,Linux双引号、单引号和反向单引号
  9. Mac 查找本机的ip
  10. [Linux] RIO C++封装
  11. Restorator 导致win8或win8.1 打开程序提示不支持此接口的解决方法
  12. java voip 的sip服务器搭建_SIP协议开源SIP服务器搭建和客户端安装
  13. LibVLC —— Qt下OpenGL播放rtsp/rtmp流,每帧图像基于OpenCv处理
  14. 计算某天是星期几-泽勒算法
  15. 计算机图形学坐标系的作用,坐标系的概念和坐标系之间的变换
  16. 视频呼叫可视对讲门铃高清双向呼叫视频对讲屏
  17. smbcontrol - 向smbd或nmbd进程发送消息
  18. supervisor 同时开启多个进程 numprocs 1
  19. Inserting Data Into Tables Using Direct-Path INSERT
  20. 书评:由乍得·福勒撰写的《热情的程序员》

热门文章

  1. XML和JSON的区别
  2. 【超详细】LightGBM介绍与应用
  3. burp的配置及抓包百度的过程
  4. 在Visual C++中如何利用UDL文件来建立ADO连接
  5. CodeIgniter 框架
  6. 5种主流的PCBA(PCB)电路板测试方法
  7. 12代酷睿安装18.04ubuntu无法识别硬盘
  8. 机器学习信息熵和热力学定律中的熵有关系吗?
  9. 巨头IPO光环下的嘀嗒出行: 起个大早二度递表 营收不足滴滴0.6%
  10. 大厂笔试都考什么题?超详细的笔试试题【附带解析】数据分析