Как предоставить LocalDateTime для запроса jpa / hibernate? - PullRequest
3 голосов
/ 19 февраля 2020

Я создаю запрос в моем @ RepositoryRestResource

, где запрос выглядит так:

@Query("Select DISTINCT comp from InsuranceCompany comp " +
            "LEFT JOIN comp.orders ord " +
            "wHERE ord.invoiced = false " +
            "and (:date is null or :date >= ord.completionTime)"
    )
public Page<InsuranceCompany> method(LocalDateTime date, Pageable pageable);

Но он выдает следующее исключение

Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value '2020-02-14T15:50:24'

когда я вызываю конечную точку с помощью:

GET /method?date=2020-02-14T15:50:24

Ответы [ 3 ]

3 голосов
/ 26 февраля 2020

Пометьте его @DateTimeFormat, чтобы Spring преобразовал его правильно:

public Page<InsuranceCompany> method(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime date, 
                                     Pageable pageable);
2 голосов
/ 26 февраля 2020

Spring по умолчанию не может преобразовать параметры REST в LocalDateTime. Вам необходимо предоставить информацию о формате даты, на уровне параметра с аннотацией @DateTimeFormat или глобально, используя DateTimeFormatterRegistrar.

В этой статье рассматриваются две альтернативы: https://www.baeldung.com/spring-date-parameters

1 голос
/ 03 марта 2020

Опция 1: глобальная настройка формата даты / времени для всех конечных точек REST приложения Spring Boot

Можно настроить глобальную настройку Spring для использования определенного формата даты / времени для конечных точек REST. Предполагая, что вы используете Джексона по умолчанию для обработки сопоставления JSON, вы можете создать класс конфигурации следующим образом, в котором вы зададите форматы:

@Configuration
public class DateTimeSerializationConfiguration implements Jackson2ObjectMapperBuilderCustomizer {

    private static final DateTimeFormatter DATE_FORMATTER = ISO_LOCAL_DATE;
    private static final DateTimeFormatter DATE_TIME_FORMATTER = ISO_DATE_TIME;
    private static final DateTimeFormatter TIME_FORMATTER = ofPattern("HH:mm");

    @Bean
    public Formatter<LocalDate> localDateFormatter() {
        return new Formatter<LocalDate>() {
            @Override
            public LocalDate parse(String text, Locale locale) {
                return LocalDate.parse(text, DATE_FORMATTER);
            }

            @Override
            public String print(LocalDate object, Locale locale) {
                return DATE_FORMATTER.format(object);
            }
        };
    }

    @Bean
    public Formatter<LocalDateTime> localDateTimeFormatter() {
        return new Formatter<LocalDateTime>() {
            @Override
            public LocalDateTime parse(String text, Locale locale) {
                return LocalDateTime.parse(text, DATE_TIME_FORMATTER);
            }

            @Override
            public String print(LocalDateTime object, Locale locale) {
                return DATE_TIME_FORMATTER.format(object);
            }
        };
    }

    @Bean
    public Formatter<LocalTime> localTimeFormatter() {
        return new Formatter<LocalTime>() {
            @Override
            public LocalTime parse(String text, Locale locale) {
                return LocalTime.parse(text, TIME_FORMATTER);
            }

            @Override
            public String print(LocalTime object, Locale locale) {
                return TIME_FORMATTER.format(object);
            }
        };
    }

    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        jacksonObjectMapperBuilder.serializers(
            new LocalDateSerializer(DATE_FORMATTER),
            new LocalDateTimeSerializer(DATE_TIME_FORMATTER),
            new LocalTimeSerializer(TIME_FORMATTER));
        jacksonObjectMapperBuilder.deserializers(
            new LocalDateDeserializer(DATE_FORMATTER),
            new LocalDateTimeDeserializer(DATE_TIME_FORMATTER),
            new LocalTimeDeserializer(TIME_FORMATTER));
    }

}

Затем вы можете создать методы контроллера следующим образом:

@RestController
public class BookingController {

    private final YourService yourService;

    @Autowired
    public BookingController(YourService yourService) {
        this.yourService = yourService;
    }

    @GetMapping("/your/api/endpoint")
    public YourObject yourControllerMethod(@RequestParam LocalDate date, Pageable pageable) {
        return yourService.yourServiceMethod(date, pageable);
    }

    // Or: with LocalDateTime

    @GetMapping("/your/api/endpoint")
    public YourObject yourControllerMethod(@RequestParam LocalDateTime dateTime, Pageable pageable) {
        return yourService.yourServiceMethod(dateTime, pageable);
    }
}

Вариант 2: Установка формата даты / времени для каждой конечной точки REST индивидуально

Если вы предпочитаете устанавливать формат для каждой конечной точки индивидуально, вы должны аннотировать параметр запроса с помощью @DateTimeFormat и укажите ожидаемый формат. В приведенном ниже примере показаны различные примеры того, как выполнить sh this:

@RestController
public class BookingController {

    private final YourService yourService;

    @Autowired
    public BookingController(YourService yourService) {
        this.yourService = yourService;
    }

    @GetMapping("/your/api/endpoint")
    public YourObject yourControllerMethod(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, Pageable pageable) {
        return yourService.yourServiceMethod(date, pageable);
    }

    // Or: with LocalDateTime

    @GetMapping("/your/api/endpoint")
    public YourObject yourControllerMethod(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime dateTime, Pageable pageable) {
        return yourService.yourServiceMethod(dateTime, pageable);
    }

    // Or: with your custom pattern

    @GetMapping("/your/api/endpoint")
    public YourObject yourControllerMethod(@RequestParam @DateTimeFormat(pattern = "dd.MM.yyyy") LocalDate date, Pageable pageable) {
        return yourService.yourServiceMethod(date, pageable);
    }
}
...