使用 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.

相關文章
相關標籤/搜索