使用 Json Schema 定义 API

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

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

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

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

properties

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

好比,对于此 Json Schema MyObject.jsonjson

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

咱们执行 jsonschema2pojo 任务后,能够生成对应的 Java 类:ide

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

type

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

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.

相关文章
相关标签/搜索