1

I am using https://github.com/mbknor/mbknor-jackson-jsonSchema for generating json schema but when my object contains LocalDate, LocalDate will look like this:

   "LocalDate" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "year" : {
          "type" : "integer"
        },
        "month" : {
          "type" : "string",
          "enum" : [ "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER" ]
        },
        "era" : {
          "$ref" : "#/definitions/Era"
        },
        "dayOfYear" : {
          "type" : "integer"
        },
        "dayOfWeek" : {
          "type" : "string",
          "enum" : [ "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY" ]
        },
        "leapYear" : {
          "type" : "boolean"
        },
        "dayOfMonth" : {
          "type" : "integer"
        },
        "monthValue" : {
          "type" : "integer"
        },
        "chronology" : {
          "$ref" : "#/definitions/IsoChronology"
        }
      },
      "required" : [ "year", "dayOfYear", "leapYear", "dayOfMonth", "monthValue" ]
    },
    "Era" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "value" : {
          "type" : "integer"
        }
      },
      "required" : [ "value" ]
    },
    "IsoChronology" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "calendarType" : {
          "type" : "string"
        },
        "id" : {
          "type" : "string"
        }
      }
    }

Can someone help me how can I change LocalDate type to string and also add field format which will be date?

My code is in groovy since I am writing groovy plugin:

ObjectMapper mapper = new ObjectMapper()
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(mapper)
JsonNode schema = jsonSchemaGenerator.generateJsonSchema(MyClass.class)

I want my LocalDate field to look like this:

    "MyField": {
      "type": "string",
      "format": "date"
    }

Thank you for any help.

Druudik
  • 955
  • 1
  • 10
  • 32
  • 1
    What does a serialized LocalDate look like when you output your json? What is your code to invoke the schema generator? Is your code Java or Scala (the schema generator is in scala)? Basically, you can do this with the `classReMapping` parameter of the schema generator; you can remap `LocalDate` to `java.lang.String`. You can also provide a "format" keyword or do additional "pattern" validation; it depends on how you are outputting the LocalDate field. I can write an answer if you can fill in the details. – Erwin Bolwidt Feb 21 '19 at 21:13
  • @ErwinBolwidt I have updated my question. Thank you very much for your help. – Druudik Feb 22 '19 at 12:51

2 Answers2

1

You may configure a customer serializer and serialize the LocalDate inside that serializer. For example (I have copied a snippet from their github readme);

@JsonSerialize(using = MySpecialSerializer.class)
@JsonSchemaInject( json = "{\"//your schema here\"}" )
public class MyPojo {
  private LocalDate localDate;

  public LocalDate getLocalDate() {
    return localDate;
  }
  //and the rest the class
}
    public class MySpecialSerializer extends JsonSerializer<MyPojo>
    {

        @Override
        public void serialize(final MyPojo myPojo, 
                              final JsonGenerator gen, 
                              final SerializerProvider serializers) 
        throws IOException 
        {
           gen.writeObject(localDate.format(DateTimeFormatter.ISO_DATE));
           //and the other field serialization
        }

    }

You could also use jackson's java-8 date module if required.

Laksitha Ranasingha
  • 4,321
  • 1
  • 28
  • 33
1

You can tell the schema generator that you want to declare some type in the schema as if they were another type. So you can say that you want to declare each LocalDate as a String.

For that, you need to create a JsonSchemaConfig object and pass it to the JsonSchemaGenerator constructor.

In the classReMapping map you can remap types to other types.

Map<Class<?>, Class<?>> classTypeReMapping = new HashMap<>();
classTypeReMapping.put(LocalDate.class, String.class);

Optionally, in the typeToFormatMapping mapping, you can map types to format annotations. The format that you are using for LocalDate is exactly the format date as defined in the JSON schema specification:

Map<String, String> typeToFormatMapping = new HashMap<>();
typeToFormatMapping.put(LocalDate.class.getName(), "date");

Constructing a complete JsonSchemaConfig:

boolean autoGenerateTitleForProperties = false;
String defaultArrayFormat = null;
boolean useOneOfForOption = true;
boolean useOneOfForNullables = false;
boolean usePropertyOrdering = false;

boolean hidePolymorphismTypeProperty = false;
boolean disableWarnings = false;
boolean useMinLengthForNotNull = false;
boolean useTypeIdForDefinitionName = false;
boolean useMultipleEditorSelectViaProperty = false;
Set<Class<?>> uniqueItemClasses = Collections.emptySet();

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

Map<Class<?>, Class<?>> classTypeReMapping = new HashMap<>();
classTypeReMapping.put(LocalDate.class, String.class);
// #####****##### Add remapped types here 

Map<String, String> typeToFormatMapping = new HashMap<>();
typeToFormatMapping.put(LocalDate.class.getName(), "date");
// #####****##### (optional) Add format annotations for types here 

JsonSchemaConfig config = JsonSchemaConfig.create(
        autoGenerateTitleForProperties,
        Optional.ofNullable(defaultArrayFormat),
        useOneOfForOption,
        useOneOfForNullables,
        usePropertyOrdering,
        hidePolymorphismTypeProperty,
        disableWarnings,
        useMinLengthForNotNull,
        useTypeIdForDefinitionName,
        typeToFormatMapping,
        useMultipleEditorSelectViaProperty,
        uniqueItemClasses,
        classTypeReMapping,
        Collections.emptyMap()
)

Building a JsonSchemaGenerator:

JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(objectMapper, config);
Class<?> mainClassObject = ...;
JsonNode jsonSchema = jsonSchemaGenerator.generateJsonSchema(mainClassObject);
Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79