最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Java networknt json-schema-validator date-time pattern must be a valid RFC 3339 date-time - Stack Overflow

programmeradmin1浏览0评论

We have a JSON schema and generate POJOs from it. But with the same schema we run into an error when we try to validate an object that we created this way.

I can reproduce this error with this simple test:

import static .assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Set;

import .junit.jupiter.api.Test;
import .springframework.core.io.ClassPathResource;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import comworknt.schema.InputFormat;
import comworknt.schema.JsonSchema;
import comworknt.schema.JsonSchemaFactory;
import comworknt.schema.SpecVersion;
import comworknt.schema.ValidationMessage;

class ValidatorTest {

    @Test
    void validateTest() throws IOException {
        // prepare
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012);
        JsonSchema jsonSchema = schemaFactory
                .getSchema(new ClassPathResource("schema.json", this.getClass().getClassLoader()).getInputStream());

        // act
        Schema schema = new Schema(LocalDateTime.now());
        String jsonString = mapper.writeValueAsString(schema);
        Set<ValidationMessage> validate = jsonSchema.validate(jsonString, InputFormat.JSON);

        // assert
        assertThat(validate).isEmpty();
    }
}

and the JSON schema

{
  "$schema": ";,
  "title": "Schema",
  "type": "object",
  "properties": {
    "datetime": {
      "type": "string",
      "format": "date-time",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{1,9}$"
    }
  }
}

We get this java.lang.AssertionError: Expecting empty but was: [$.datetime: does not match the date-time pattern must be a valid RFC 3339 date-time]

We have a JSON schema and generate POJOs from it. But with the same schema we run into an error when we try to validate an object that we created this way.

I can reproduce this error with this simple test:

import static .assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Set;

import .junit.jupiter.api.Test;
import .springframework.core.io.ClassPathResource;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import comworknt.schema.InputFormat;
import comworknt.schema.JsonSchema;
import comworknt.schema.JsonSchemaFactory;
import comworknt.schema.SpecVersion;
import comworknt.schema.ValidationMessage;

class ValidatorTest {

    @Test
    void validateTest() throws IOException {
        // prepare
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012);
        JsonSchema jsonSchema = schemaFactory
                .getSchema(new ClassPathResource("schema.json", this.getClass().getClassLoader()).getInputStream());

        // act
        Schema schema = new Schema(LocalDateTime.now());
        String jsonString = mapper.writeValueAsString(schema);
        Set<ValidationMessage> validate = jsonSchema.validate(jsonString, InputFormat.JSON);

        // assert
        assertThat(validate).isEmpty();
    }
}

and the JSON schema

{
  "$schema": "http://json-schema./draft-07/schema#",
  "title": "Schema",
  "type": "object",
  "properties": {
    "datetime": {
      "type": "string",
      "format": "date-time",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{1,9}$"
    }
  }
}

We get this java.lang.AssertionError: Expecting empty but was: [$.datetime: does not match the date-time pattern must be a valid RFC 3339 date-time]

Share Improve this question edited Jan 30 at 16:13 Basil Bourque 340k122 gold badges934 silver badges1.3k bronze badges asked Jan 30 at 15:13 Patrick RodePatrick Rode 3393 silver badges16 bronze badges 3
  • 2 By the way, I cannot imagine a scenario where calling LocalDateTime.now is wise. That class represents only a date with time-of-day but lacks the context of a time zone or offset. To represent a moment, use Instant, OffsetDateTime, or ZonedDateTime. – Basil Bourque Commented Jan 30 at 16:12
  • In fact we would not have this problem if we used ZonedDateTime. I just tried that. But we still want to stick to LocalDateTime, as it is used in many places and we only use UTC as our timezone. Still a good comment, thank you! – Patrick Rode Commented Jan 31 at 11:50
  • Where you want to track a moment in UTC, use java.time.Instant. – Basil Bourque Commented Jan 31 at 17:13
Add a comment  | 

1 Answer 1

Reset to default 1

It works since I updated the $schema to "http://json-schema./draft/2020-12/schema#"

发布评论

评论列表(0)

  1. 暂无评论