Joda日期时间的Jackson JSON Schema生成器

时间:2016-09-13 06:46:52

标签: java json jackson jsonschema jackson-modules

我正在使用Jackson JSON架构模块版本2.7.4为我的某些类生成JSON架构。在我的课程中,我使用了Joda DateTime对象。生成此对象的模式,并展开其所有属性(如下所示)。是否可以将其转换为DATE_TIME

"createdDate":{  
     "type":"object",
     "id":"urn:jsonschema:org:joda:time:DateTime",
     "properties":{  
        "weekOfWeekyear":{  
           "type":"integer"
        },
        "weekyear":{  
           "type":"integer"
        },
        "yearOfEra":{  
           "type":"integer"
        },
        "secondOfDay":{  
           "type":"integer"
        },
        "minuteOfDay":{  
           "type":"integer"
        },
        "yearOfCentury":{  
           "type":"integer"
        },
        "centuryOfEra":{  
           "type":"integer"
        },
        "millisOfDay":{  
           "type":"integer"
        },
        "monthOfYear":{  
           "type":"integer"
        },
        "hourOfDay":{  
           "type":"integer"
        },
        "minuteOfHour":{  
           "type":"integer"
        },
        "secondOfMinute":{  
           "type":"integer"
        },
        "millisOfSecond":{  
           "type":"integer"
        },
        "year":{  
           "type":"integer"
        },
        "dayOfMonth":{  
           "type":"integer"
        },
        "dayOfWeek":{  
           "type":"integer"
        },
        "era":{  
           "type":"integer"
        },
        "dayOfYear":{  
           "type":"integer"
        },
        "chronology":{  
           "type":"object",
           "id":"urn:jsonschema:org:joda:time:Chronology",
           "properties":{  
              "zone":{  
                 "type":"object",
                 "id":"urn:jsonschema:org:joda:time:DateTimeZone",
                 "properties":{  
                    "id":{  
                       "type":"string"
                    },
                    "fixed":{  
                       "type":"boolean"
                    }
                 }
              }
           }
        },
        "zone":{  
           "type":"object",
           "$ref":"urn:jsonschema:org:joda:time:DateTimeZone"
        },
        "millis":{  
           "type":"integer"
        },
        "afterNow":{  
           "type":"boolean"
        },
        "beforeNow":{  
           "type":"boolean"
        },
        "equalNow":{  
           "type":"boolean"
        }
     }
  },

2 个答案:

答案 0 :(得分:0)

我不确定该模块中是否有任何支持或Joda。 你可以做的是用自己的生成替换生成的Joda模式。像这样:

    private void replaceDateTime(JsonSchema schema, Class<?> clazz) {
        Field[] fields = ClazzFieldFinder.getAllFields(clazz);
        for (Field field : fields) {
            String fieldName = field.getName();
            if (field.getType().equals(DateTime.class)) {
                schema.asObjectSchema().getProperties().remove(fieldName);

                StringSchema stringSchemaDateTime = new StringSchema();
                stringSchemaDateTime.setFormat(JsonValueFormat.DATE_TIME);
                schema.asObjectSchema().getProperties().put(fieldName, stringSchemaDateTime);
            }
        }
    }

它删除了为Joda生成的模式,并添加了字符串/ date_time格式。

答案 1 :(得分:0)

我不知道这是否是正确的解决方案,但这是在另一个网站上建议的,这对我有用;因此,我将此作为答案发布。

在Jackson模式模块中,有VisitorContext的概念可以在ObjectMapper类中注册以生成模式。根据建议,我提供了一个实现:

public static class VisitorContextWithoutSchemaInlining extends VisitorContext {
  @Override
  public String addSeenSchemaUri(final JavaType aSeenSchema) {
    return getSeenSchemaUri(aSeenSchema);
  }

  @Override
  public String getSeenSchemaUri(final JavaType aSeenSchema) {
    return isEligibleForInlineSchema(aSeenSchema) ? javaTypeToUrn(aSeenSchema) : null;
  }

  private boolean isEligibleForInlineSchema(final JavaType type) {
    return type.getRawClass() != String.class
                && !isBoxedPrimitive(type)
                && !type.isPrimitive()
                && !type.isMapLikeType()
                && !type.isCollectionLikeType()
                && type.getRawClass() == DateTime.class
                ;
    }

    private boolean isBoxedPrimitive(final JavaType type) {
      return type.getRawClass() == Boolean.class
             || type.getRawClass() == Byte.class
             || type.getRawClass() == Long.class
             || type.getRawClass() == Integer.class
             || type.getRawClass() == Short.class
             || type.getRawClass() == Float.class
             || type.getRawClass() == Double.class
             ;
    }
}

要与ObjectMapper一起使用,我这样做了:

final ObjectMapper mapper = new ObjectMapper();
final ObjectWriter objectWriter = mapper.writer();

final SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
visitor.setVisitorContext(new VisitorContextWithoutSchemaInlining());

objectWriter.acceptJsonFormatVisitor(candidateClass, visitor);
final JsonSchema jsonSchema = visitor.finalSchema();
final String schemaJsonString = objectWriter.forType(JsonSchema.class).writeValueAsString(jsonSchema);

有了这个,我可以看到我的架构有createdDate

"createdDate":{"type":"object","$ref":"urn:jsonschema:org:joda:time:DateTime"}