Создайте пользовательское исключение при десериализации поля Date, используя Джексона в Java - PullRequest
0 голосов
/ 17 марта 2019

DTO:

@Getter
@Setter
@ToString
public class TestDto {

    @NotNull
    private String id;

    @NotNull
    @DateTimeFormat(pattern = "YYYY-MM-DD'T'hh:mm:ss.SSSZ")
    private Instant timestamp;
}

Когда я даю этот ввод

{"timestamp":"4/23/2018 11:32 PM","id":"132"}

Это дает BAD_REQUEST (что и должно), но я хочу обработать эту искаженную дату и выдать исключение с моим пользовательским исключением.

Как я могу добавить это?

1 Ответ

1 голос
/ 17 марта 2019

Так как запрошенная функция OP еще не поддерживается: https://github.com/FasterXML/jackson-annotations/issues/130

Попытка сделать то же самое с более длинным подходом с помощью пользовательского десериализатора для поля timestamp

Пользовательское исключениекласс:

import com.fasterxml.jackson.core.JsonProcessingException;

public class MyException extends JsonProcessingException {
    public MyException(String message) {
        super(message);
    }
}

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

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
public class InstantDeserializer extends StdDeserializer<Instant> {

public InstantDeserializer() {
    this(null); 
} 

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

private SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD'T'hh:mm:ss.SSS'Z'");

@Override
public Instant deserialize(JsonParser jp, DeserializationContext ctxt)
  throws IOException, JsonProcessingException {
    JsonNode node = jp.getCodec().readTree(jp);
    Date date = null;
    try {
        date = sdf.parse(node.asText());
    } catch (Exception e) {
        throw new MyException("Instant field deserialization failed");
    }
    return date.toInstant();
}
}

Обновлен класс TestDto:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotNull;
import java.time.Instant;

@Getter
@Setter
@ToString
public class TestDto {

    @NotNull
    private String id;

    @NotNull
    @JsonDeserialize(using = InstantDeserializer.class)
    @DateTimeFormat(pattern = "YYYY-MM-DD'T'hh:mm:ss.SSS'Z'")
    private Instant timestamp;
}

Неверный запрос на ввод:

{"timestamp":"4/23/2018 11:32 PM","id":"132"}

Ответ:

{
    "timestamp": 1552845180271,
    "status": 400,
    "error": "Bad Request",
    "message": "JSON parse error: Instant field deserialization failed; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Instant field deserialization failed (through reference chain: TestDto[\"timestamp\"])"
}

Допустимый запрос ввода:

{"timestamp":"2018-04-23T11:32:22.213Z","id":"132"}

Ответ:

{
    "id": "132",
    "timestamp": {
        "epochSecond": 1514700142,
        "nano": 213000000
    }
}

Если вам не нравится, как поле метки времени десериализуется, и вы хотели бычтобы изменить это, этот ТАК пост будет полезен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...