2015-01-09 73 views
9

我有:從POJO生成JSON Schema

我從pojo生成JSON模式。我的代碼生成架構如下所示:

ObjectMapper mapper = new ObjectMapper(); 
TitleSchemaFactoryWrapper visitor = new TitleSchemaFactoryWrapper(); 
mapper.acceptJsonFormatVisitor(clazz, visitor); 
JsonSchema schema = visitor.finalSchema(); 
schemas.put(clazz, mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema)); 

我通過上面的代碼生成了幾個模式。其中的POJO的內部有一個嵌入式枚舉限制的可能值,就像這樣:

public class MyClass { 

    @JsonProperty("name") 
    private String name; 
    @JsonProperty("startDayOfWeek") 
    private MyClass.StartDayOfWeek startDayOfWeek; 
    /** 
    * The ID of a timezone returned by the timezones route. 
    * 
    */ 
    @JsonProperty("timezone") 
    private String timezone; 
    @JsonIgnore 
    private Map<String, Object> additionalProperties = new HashMap<String, Object>(); 

    /** 
    * 
    * @return 
    *  The startDayOfWeek 
    */ 
    @JsonProperty("startDayOfWeek") 
    public MyClass.StartDayOfWeek getStartDayOfWeek() { 
     return startDayOfWeek; 
    } 

    /** 
    * 
    * @param startDayOfWeek 
    *  The startDayOfWeek 
    */ 
    @JsonProperty("startDayOfWeek") 
    public void setStartDayOfWeek(MyClass.StartDayOfWeek startDayOfWeek) { 
     this.startDayOfWeek = startDayOfWeek; 
    } 

    public static enum StartDayOfWeek { 

     MONDAY("Monday"), 
     TUESDAY("Tuesday"), 
     WEDNESDAY("Wednesday"), 
     THURSDAY("Thursday"), 
     FRIDAY("Friday"), 
     SATURDAY("Saturday"), 
     SUNDAY("Sunday"); 
     private final String value; 
     private static Map<String, MyClass.StartDayOfWeek> constants = new HashMap<String, MyClass.StartDayOfWeek>(); 

     static { 
      for (MyClass.StartDayOfWeek c: values()) { 
       constants.put(c.value, c); 
      } 
     } 

     private StartDayOfWeek(String value) { 
      this.value = value; 
     } 

     @JsonValue 
     @Override 
     public String toString() { 
      return this.value; 
     } 

     @JsonCreator 
     public static MyClass.StartDayOfWeek fromValue(String value) { 
      MyClass.StartDayOfWeek constant = constants.get(value); 
      if (constant == null) { 
       throw new IllegalArgumentException(value); 
      } else { 
       return constant; 
      } 
     } 

    } 

} 

上面的代碼應限制在是圍繞傳遞到「星期一」,「星期二」的JSON數據可能的字符串值, 「星期三」等

當我運行有問題的代碼的模式發生器,我希望能得到類似下面的模式:

{ 
    "type" : "object", 
    "javaType" : "my.package.MyClass", 
    "properties": { 
    "startDayOfWeek" : { 
     "type" : "string", 
     "enum" : [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ] 
    } 
    } 
} 

而是我得到這個:

{ 
    "type" : "object", 
    "id" : "urn:jsonschema:my:package:MyClass", 
    "title" : "Lmy/package/MyClass;", 
    "properties" : { 
    "startDayOfWeek" : { 
     "type" : "string" 
    } 
    } 
} 

我已經在傑克遜模式模塊源代碼中做了一些挖掘,發現發生了什麼是傑克遜使用「.toString()」作爲枚舉類型的默認序列化方法,但是我需要它做什麼爲創建一個基於StartDayOfWeek.values()看起來像這樣的行:

"enum" : [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ] 

有誰知道該怎麼做?

+0

也許你想嘗試JJSchema代替。 – fge

+0

鑑於我在使用NPE的時候得到了一個N​​PE,事實上在6個月內沒有對該項目進行更新,而且事實上它仍然顯然處於測試狀態,所以我不認爲這是一個非常不錯的選擇 – StormeHawke

+0

您是否已經使用自定義的反序列化器正確反序列化(例如,作爲枚舉,而不是字符串)星期值? – user3159253

回答

2

暴風雨的回答引用org.codehaus,這是傑克遜的舊版本。以下是類似的,但使用fasterxml(較新版本)。

雙響炮:

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-core</artifactId> 
    <version>2.7.1</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-databind</artifactId> 
    <version>2.7.1</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-annotations</artifactId> 
    <version>2.7.1</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.module</groupId> 
    <artifactId>jackson-module-jsonSchema</artifactId> 
    <version>2.1.0</version> 
</dependency> 

代碼:

import ...TargetClass; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.SerializationFeature; 
import com.fasterxml.jackson.databind.jsonschema.JsonSchema; 

import java.io.IOException; 

public final class JsonSchemaGenerator { 

    private JsonSchemaGenerator() { }; 

    public static void main(String[] args) throws IOException { 
     System.out.println(JsonSchemaGenerator.getJsonSchema(TargetClass.class)); 
    } 

    public static String getJsonSchema(Class clazz) throws IOException { 
     ObjectMapper mapper = new ObjectMapper(); 
     mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true); 
     JsonSchema schema = mapper.generateJsonSchema(clazz); 
     return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema); 
    } 

} 
+1

請注意,這兩個org.codehaus。jackson和com.fasterxml.jackson將生成v3版本的json模式,而不是v4。更多詳情,請訪問 - https://github.com/FasterXML/jackson-module-jsonSchema/issues/9 –

11

它似乎不可能使用我發現使用數據綁定的說明。不過,我發現另一個傑克遜模塊似乎很好地做了這個技巧。奇怪的幾個對象被命名爲相同的。

TLDR:使用來自org.codehaus.jackson.map包而非com.fasterxml.jackson.databind包的對象。如果你按照this頁面上的說明,那麼你做錯了。只需使用jackson-mapper模塊。

下面是未來的Google代碼:

private static String getJsonSchema(Class clazz) throws IOException { 
    org.codehaus.jackson.map.ObjectMapper mapper = new ObjectMapper(); 
    //There are other configuration options you can set. This is the one I needed. 
    mapper.configure(SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, true); 

    JsonSchema schema = mapper.generateJsonSchema(clazz); 

    return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema); 
} 
+1

codehaus代表舊版本的傑克遜不是嗎? –

+0

我這麼認爲。我只知道這適用於我,其他嘗試沒有 – StormeHawke