Jackson JSON Joda 日期时间模式生成器

Jackson JSON Schema generator for Joda date time

我正在使用 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"
        }
     }
  },

我不确定该模块中是否有任何支持或 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 生成的架构并添加了 string/date_time 格式。

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

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

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"}