Джексон отключить аннотацию @JsonFormat - PullRequest
0 голосов
/ 30 сентября 2019

Я использую библиотеку Джексона, и я столкнулся с ситуацией, когда я хочу отключить аннотацию @JsonFormat с помощью objectmapper при сериализации / десериализации.

Мой код Api находится в сторонней библиотеке, поэтому я не могу удалить/ добавьте любую аннотацию, поэтому objectMapper - единственный выбор.

Класс API:

public class ApiClass {

  @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
  private DateTime time;

}

Мой код:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(Feature.ALLOW_COMMENTS, true);
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setSerializationInclusion(Include.NON_ABSENT);
objectMapper.registerModule(new JodaModule());
objectMapper.registerModule(new JavaTimeModule());

String str = " {\"time\": \"2012-05-01\"}";

ApiClass msg = objectMapper.readValue(str, ApiClass.class);

Я хочу, чтобы это преобразование прошло успешно.

В настоящее время я получаю: com.fasterxml.jackson.databind.JsonMappingException: Неверный формат: "2012-05-01" слишком короткое

Пожалуйста, помогите мне здесь.

Заранее спасибо

Ответы [ 5 ]

0 голосов
/ 04 октября 2019

Ниже приведен код, который специально отключит JsonFormat:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(Feature.ALLOW_COMMENTS, true);
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setSerializationInclusion(Include.NON_ABSENT);
objectMapper.registerModule(new JodaModule());
objectMapper.registerModule(new JavaTimeModule());

objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
    @Override
    protected <A extends Annotation> A _findAnnotation(final Annotated annotated,
        final Class<A> annoClass) {
      if (!annotated.hasAnnotation(JsonFormat.class)) {    //since we need to disable JsonFormat annotation.
        return super._findAnnotation(annotated, annoClass);
      }
      return null;
    }
  });


String str = " {\"time\": \"2012-05-01\"}";

ApiClass msg = objectMapper.readValue(str, ApiClass.class);
System.out.println(objectMapper.writeValueAsString(msg ));

Если нам нужно отключить несколько аннотаций (JsonFormat, JsonUnWrapped), тогда:

replace:

if (!annotated.hasAnnotation(JsonFormat.class)) {

с:

if (!annotated.hasOneOf(new Class[] {JsonFormat.class, JsonUnwrapped.class})) {

Спасибо всем.

0 голосов
/ 30 сентября 2019

Существует одно решение проблемы.

Пожалуйста, проверьте: https://www.baeldung.com/jackson-annotations Точка №. 9 Отключить аннотацию Джексона

objectMapper.disable(MapperFeature.USE_ANNOTATIONS);
ApiClass msg = objectMapper.readValue(str, ApiClass.class);

sout(msg.getTime()) //2012-05-01T00:00:00.000Z

Но это отключит все аннотации. Я просто хочу отключить аннотацию @JsonFormat. Пожалуйста, предложите.

0 голосов
/ 30 сентября 2019

Попробуйте использовать пользовательский десериализатор:

public class MyTest {
    @Test
    public void myTest() throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
        objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
        objectMapper.registerModule(new JavaTimeModule());

        String str = " {\"time\": \"2012-05-01\"}";


        SimpleModule module = new SimpleModule();
        module.addDeserializer(DateTime.class, new DateTimeDeserializer());
        objectMapper.registerModule(module);


        ApiClass msg = objectMapper.readValue(str, ApiClass.class);
        System.out.println(msg.getTime());
    }
}

class ApiClass {

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
    private DateTime time;

    public DateTime getTime() {
        return time;
    }

    public void setTime(DateTime time) {
        this.time = time;
    }
}

class DateTimeDeserializer extends StdDeserializer<DateTime> {

    public DateTimeDeserializer() {
        this(null);
    }

    public DateTimeDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public DateTime deserialize(JsonParser jp, DeserializationContext ctxt)
        throws IOException {
        JsonNode node = jp.getCodec().readTree(jp);
        String time = node.asText();
        return new DateTime(time);
    }
}
0 голосов
/ 30 сентября 2019

Вы можете использовать SimpleDateFormat для преобразования даты строкового типа в тип даты, как показано ниже

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    try {
        Date parse = simpleDateFormat.parse(String date);
        return parse;
    } catch (ParseException e) {
        e.printStackTrace();
    }
0 голосов
/ 30 сентября 2019

Попробуйте использовать приведенный ниже код перед использованием readValue метода

mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
...