Spring Boot在两个日期之间搜索数据

时间:2019-01-03 11:02:20

标签: java spring spring-boot

我想在两个日期之间搜索数据,这是我的存储库

@Query("select mvt from Mouvements mvt where mvt.dateCompte between :x and :y")
public Page<Mouvements> getMouvementsByDate(@Param("x")LocalDate dateBefore, @Param("y")LocalDate dateAfter, Pageable pageable); 

这是我的控制器

@RequestMapping(value="/movementsByDate", method = RequestMethod.GET)
public Page<Mouvements> movementsByDate(
        @RequestParam(name= "dateBefore", defaultValue="")LocalDate dateBefore, 
        @RequestParam(name= "dateAfter", defaultValue="")LocalDate dateAfter, 
        @RequestParam(name= "page", defaultValue="0")int page, 
        @RequestParam(name= "size", defaultValue="5")int size){
    return mouvementsRepository.getMouvementsByDate(dateBefore, dateAfter, new PageRequest(page, size));
}

现在我的问题是当我使用以下URL测试此Web服务时:

http://localhost:8080/api/movement/movementsByDate?dateBefore=27/11/2015&dateAfter=03/01/2019&page=0&size=9

我遇到此错误

Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam java.time.LocalDate] for value '27/11/2015'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [27/11/2015]",

4 个答案:

答案 0 :(得分:1)

在Spring Boot中,默认的LocalDate转换格式为yyyy-MM-dd,并且您正在使用27/11/2015的{​​{1}}。

使用@DateTimeFormat为请求映射参数指定您自己的格式,或者在请求中使用默认格式。请注意,dd/MM/yyyy字符作为URL的一部分时应编码为/,您的示例无效,因此使用标准%2F会更容易。

Spring应该支持2015-11-27映射,因此以下应该可以工作:

Optional

答案 1 :(得分:1)

您可以全局更改LocalDate的格式:

@InitBinder
public void localDateBind(WebDataBinder binder) {
     binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
          @Override
          public void setAsText(String text) throws IllegalArgumentException {
            LocalDate.parse(text, DateTimeFormatter.ISO_DATE); //CUSTOM FORMAT
          }
     });
}

答案 2 :(得分:1)

最好将参数作为String接收,然后在控制器中将String转换为LocalDate。

@RequestMapping(value="/movementsByDate", method = RequestMethod.GET)
public Page<Mouvements> movementsByDate(
        @RequestParam(name= "dateBefore", defaultValue="")String dateBeforeString, 
        @RequestParam(name= "dateAfter", defaultValue="")String dateAfterString, 
        @RequestParam(name= "page", defaultValue="0")int page, 
        @RequestParam(name= "size", defaultValue="5")int size){

        LocalDate dateBefore = LocalDate.parse(dateBeforeString, DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        LocalDate dateAfter = LocalDate.parse(dateAfterString, DateTimeFormatter.ofPattern("dd/MM/yyyy"));

    return mouvementsRepository.getMouvementsByDate(dateBefore, dateAfter, new PageRequest(page, size));
}

答案 3 :(得分:0)

您必须这样做

@RequestMapping(value="/movementsByDate", method = RequestMethod.GET)
public Page<Mouvements> movementsByDate(
        @RequestParam(name= "dateBefore", defaultValue="") @DateTimeFormat(iso = ISO.DATE) LocalDate dateBefore, 
        @RequestParam(name= "dateAfter", defaultValue="") @DateTimeFormat(iso = ISO.DATE) LocalDate dateAfter, 
        @RequestParam(name= "page", defaultValue="0")int page, 
        @RequestParam(name= "size", defaultValue="5")int size){
    return mouvementsRepository.getMouvementsByDate(dateBefore, dateAfter, new PageRequest(page, size));
}

如果要全局进行这种类型的转换,可以使用Spring Converter类。

public class StringToLocalDateConverter implements Converter<String, LocalDate> {
    public LocalDateTime convert(String source) {
        DateTimeFormatter formatter = DateTimeFormatter.BASIC_ISO_DATE;
        return LocalDate.parse(source, formatter);
    }
}

别忘了注册