本文地址:使用 Json Schema 定义 API

前面我们介绍了 Json Schema 的基本内容,这篇文章我们结合 jsonschema2pojo 工具深入分析如何使用 Json Schema 生成 API,学习更多关于 Json Schema 的关键字等知识。

jsonschema2pojo 该库提供了多种使用Json Schame文件生成 Java 类的方法,比如 Maven插件, Gradle插件, Ant任务, 以及直接使用命令行,甚至还可以在代码中直接使用,具体参照 jsonschema2pojo Getting Started

这里我直接采用 Mac 命令行的方式,在 Mac 下安装此命令的方式比较简单,直接运行 brew install jsonschema2pojo 安装即可。

properties

在一个类中,最关键的就是属性了,每个类都可能有多个属性,在 Json Schema 中就是通过 properties 来定义类的属性的, properties 中的每个条目都是所定义类的一个属性。

比如,对于此 Json Schema MyObject.json

{
"type" : "object",
"properties" : {
"foo" : {
"type" : "string"
}
}
}

我们执行 jsonschema2pojo 任务后,可以生成对应的 Java 类:

public class MyObject {
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}

type

像我们 Java 中有多种类型,那不同的类型在 Json Schema 中如何表示呢?一般通用的转换如下所示,这也是 jsonschema2pojo 工具默认使用的转换方式:

Schema Type | Java Type

:-: | :-:

string | java.lang.String

number | java.lang.Double

integer| java.lang.Integer

boolean| java.lang.Boolean

object | 自己生成的类

array | java.util.List

array(with “uniqueItems”:true)|java.util.Set

null | java.lang.object

any | java.lang.object

值的注意的是,如果我们增加了 usePrimitives 选项,对于 Integer, Double, Boolean 这三个包装类将会转换成基本类型 int, double, boolean

additionalProperties

我们平时开发中,为了类利于扩展,有时会给类增加一个Map类型的属性,这样当外部需要传更多的参数给我们时,不需要更改API,直接将参数放到这个 Map 里就可以快速实现。jsonschema2pojo同样也实现了这个功能,当我们没有指定additionalProperties属性为false或者没有指定additionalProperties属性时,jsonschema2pojo会为我们定义的类自动生成一个类型为MapadditionalProperties属性。

比如:

{
"type" : "object"
}

或者

{
"type" : "object",
"additionalProperties" : {}
}

生成的类:

public class MyObject {
private java.util.Map<String, Object> additionalProperties = new java.util.HashMap<String, Object>(); @org.codehaus.jackson.annotate.JsonAnyGetter
public java.util.Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
} @org.codehaus.jackson.annotate.JsonAnySetter
public void setAdditionalProperties(String name, Object value) {
this.additionalProperties.put(name, value);
}
}

items

items 用于指定我们定义 List 以及 Set 类型时的子元素详情,比如子元素的类型以及描述等。

例如:

{
"type" : "object",
"properties" : {
"myArrayProperty" : {
"type" : "array",
"items" : {
"type" : "string"
}
}
}
}

生成的属性:

List<String> myArrayProperty;

required

如果一个属性在required中指定了,那么这个属性会有一个 Required 的注解,表明该属性是必需的。

uniqueItems

这个就是我们上面表格中的用于区分 ListSet 的关键字了,如果我们定义的array中声明uniqueItemstrue,那么最终转换为的属性的类型就为Set

enum

对于枚举类型的定义需要使用到此关键字,比如:

{
"type" : "object",
"properties" : {
"myEnum" : {
"type" : "string",
"enum" : ["one", "secondOne", "3rd one"]
}
}
}

生成的枚举类:

@Generated("com.googlecode.jsonschema2pojo")
public static enum MyEnum { ONE("one"),
SECOND_ONE("secondOne"),
_3_RD_ONE("3rd one");
private final String value; private MyEnum(String value) {
this.value = value;
} @JsonValue
@Override
public String toString() {
return this.value;
} @JsonCreator
public static MyObject.MyEnum fromValue(String value) {
for (MyObject.MyEnum c: MyObject.MyEnum.values()) {
if (c.value.equals(value)) {
return c;
}
}
throw new IllegalArgumentException(value);
}
}

default

如果我们需要某个属性有默认值,可以加上此参数,生成类的属性会自动实例化。具体可参照下表:

Json Schema | Java

:-: | :-:

myString : { “type”:“string”, “default”:“abc”} | myString : { “type”:“string”, “default”:“abc”};

myInteger : { “type”:“integer”, “default”:“100”} | private Integer myInteger = 100;

myNumber : { “type”:“number”, “default”:“10.3”}|private Double myNumber = 10.3D;

myMillis : { “type”:“string”, “format”:“utc-millisec”, “default”:“500”}|private Long myMillis = 500L;

myDate : { “type”:“string”, “format”:“date-time”, “default”:“500”}|private Date myDate = new Date(500L);

myDate : { “type”:“string”, “format”:“date-time”, “default”:“2011-02-24T09:25:23.112+0000”}|private Date myDate = new Date(1298539523112L);

myList : { “type”:“array”, “default”:[“a”,“b”,“c”]}|private List myList = new ArrayList(Arrays.asList(“a”,“b”,“c”));

title && description

titledescription 用于描述一个属性,当我们指定了这两个参数时,jsonschema2pojo

会在属性的上面生成 Java 文档,并且titledescription之上。

format

formatjsonschema2pojo 提供给我们扩展更多类型的一个参数,在上面介绍的type中可以看到我们生成的 Java 类型并不多,像 Date 等这些参数都没有,但是当我们加上 jsonschema2pojo能识别的format参数后,就可以扩展我们的属性类型,具体参照:

Format value | Java Type

:-: | :-:

“date-time” | java.util.Date

“date” | String

“time” | String

“utc-millisec” | long

“regex” | java.util.regex.Pattern

“color” | String

“style” | String

“phone” | String

“uri” | java.net.URI

“email” | String

“ip-address” | String

“ipv6” | String

“host-name” | String

“uuid” | java.util.UUID

extends

使用extends关键字可以实现 Java 中的继承。

比如,我们定义 flower.json

{
"type" : "object"
}

然后定义 rose.json,使其继承自 flower

{
"type" : "object",
"extends" : {
"$ref" : "flower.json"
}
}

最终我们生成的 Rose.java 为以下内容:

public class Rose extends Flower {
....
}

$ref

$ref关键字用于指定某一个属性的引用来源,在jsonschema2pojo中支持以下协议:

  • http://, https://
  • file://
  • classpath:, resource:, java: (all synonyms used to resolve schemas from the classpath).

我们定义 API 的时候一般是需要引用到其他我们定义的 Json Schema 文档。比如:

{
"type" : "object",
"properties" : {
"loggedInUser" : {
"$ref" : "user.json"
}
}
}

表明loggedInUser属性的类型是一个由user.json定义的类型。

{
"description" : "Tree node",
"type" : "object",
"properties" : {
"children" : {
"type" : "array",
"items" : {
"$ref" : "#"
}
}
}
}

这个表明 children 属性引用的是该 object 自身,所以这可以生成一个 Tree 类型的类。

public class TreeNode {
public List<TreeNode> getChildren() {...} public void setChildren(List<TreeNode> children) {...}
}

更多

  • javaEnumNames

    {
    "type" : "object",
    "properties" : {
    "foo" : {
    "type" : "string",
    "enum" : ["H","L"],
    "javaEnumNames" : ["HIGH","LOW"]
    }
    }
    }

    生成的类:

    public enum Foo {
    HIGH("H"),
    LOW("L")
    ...
    }
  • javaInterfaces

    {
    "javaInterfaces" : ["java.io.Serializable", "Cloneable"],
    "type" : "object"
    }

    生成的类:

    public class FooBar implements Serializable, Cloneable
    {
    ...
  • javaName

    {
    "type": "object",
    "properties": {
    "a": {
    "javaName": "b",
    "type": "string"
    }
    }
    }

    生成的类:

    public class MyClass {
    @JsonProperty("a")
    private String b; @JsonProperty("a")
    public String getB() {
    return b;
    } @JsonProperty("a")
    public void setB(String b) {
    this.b = b;
    }
    }

声明

本文绝大部分内容是引用的 jsonschame2pojo 的文档,更多内容请看官方文档 jsonschema2pojo.

使用 Json Schema 定义 API的更多相关文章

  1. Json Schema简介

    1. 引言 什么是Json Schema? 以一个例子来说明 假设有一个web api,接受一个json请求,返回某个用户在某个城市关系最近的若干个好友.一个请求的例子如下: { "city ...

  2. Json Schema 是什么?

    本文地址:Json Schema 是什么? 简单说,Json Schema 其实就是一个标准的 Json 串,它以一个 Json 串来描述我们需要的数据规范,并且支持注释以及验证 Json 文档,即我 ...

  3. 技术那么多,你想看看JSON Schema的测试吗?

    目录 1. 什么是JSON Schema? 2. 如何定义一个JSON Schema 3. 如何测试JSON Schema a) 使用JSON Schema validator GUI b) 在Jav ...

  4. JSON Schema 校验实例

    JSON Schema 简介 JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. ...

  5. Understanding JSON Schema

    json schema 在线校验器 译自:Understanding JSON Schema { "type": "object", "propert ...

  6. Map传参优雅检验,试试json schema validator

    背景 笔者目前所在团队的代码年代已久,早年规范缺失导致现在维护成本激增,举一个深恶痛疾的例子就是方法参数使用Map"一撸到底",说多了都是泪,我常常在团队内自嘲"咱硬是把 ...

  7. Schema、API Schema与MFn

    大部分知识都是相通的,Maya和USD在设计上有很多相似之处,USD的Schema粗看很难理解,但实际上与Maya的MFn有着异曲同工之处.这篇文章会简单介绍一下这两个知识点,做个对比,了解下它们在各 ...

  8. Json Schema的使用

    直接上案例: 在Web Api通讯中,客户端发送json数据,服务端反序列化json(json与某个类形成对应关系),在某些情况下,需要校验其上传的json是否合法. 服务端是使用Json.net(n ...

  9. json与api- 天气api 博客词频分析

    一.json基础 1.1 json的介绍 json现在成为各种程序与语言之间交互的一种数据格式,本质是文本,字符串. json有两种格式: 1.  类似字典  {k:v,k,v} 2.  类似列表 { ...

随机推荐

  1. [BUUCTF]PWN——xdctf2015_pwn200

    xdctf2015_pwn200 附件 步骤 例行检查,32位程序,开启了nx保护 本地试运行一下程序,看看大概的情况 32位ida载入,习惯性的检索程序里的字符串,没有发现什么铭感的地方,直接看ma ...

  2. LuoguB2078 含 k 个 3 的数 题解

    Content 给定一个数 \(n\),判断其数位中是否恰好有 \(k\) 个 \(3\). 数据范围:\(1<n\leqslant 10^{15}\),\(1<k\leqslant 15 ...

  3. IO多路复用之select总结(转载)

    1.基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程.IO多路复用适用如下场合: (1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/ ...

  4. MAVEN项目打包报错:Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode) -> [Help 1]

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on pr ...

  5. cmake之if

    note if 要 与endif配对使用 语法含义 表达式 含义 if (not expression) 与 expression相反 if (var1 AND var2) var1与var2都为真时 ...

  6. win7(X64)+wdk7驱动环境搭建

    !!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!! 作者:mohist -----  蓝 屏 警 告 --- 加载驱动的操作请在虚拟机中完成, 可以有效避免物理机蓝 ...

  7. 【LeetCode】604. Design Compressed String Iterator 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 维护当前字符和次数 日期 题目地址:https://l ...

  8. 【LeetCode】383. Ransom Note 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Java解法 Python解法 日期 [LeetCo ...

  9. codeforce 595B-Pasha and Phone(数学)

    今天补题,昨天是我太猖狂了,在机房吹牛,然后说着说着忘了时间,后来楼长来了,我们走了,CF没打成. 不扯了,下面说题: 题目的意思是给你n和k, n代表最后得出的号码有n为,然后k能被n整除,就是把n ...

  10. 一、SQL高级语句

    摘抄别的博主的博客主要总去CSDN看不太方便自己整理一下加深记忆! 导入文件至数据库 #将脚本导入 source 加文件路径 mysql> source /backup/test.sql; se ...