2016-10-27 69 views
4

我使用Spring啓動並列入jackson-datatype-jsr310使用Maven:如何在Spring中使用LocalDateTime RequestParam?我得到「無法將字符串轉換爲LocalDateTime」

<dependency> 
    <groupId>com.fasterxml.jackson.datatype</groupId> 
    <artifactId>jackson-datatype-jsr310</artifactId> 
    <version>2.7.3</version> 
</dependency> 

當我嘗試使用RequestParam與Java 8日期/時間類型,

@GetMapping("/test") 
public Page<User> get(
    @RequestParam(value = "start", required = false) 
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime start) { 
//... 
} 

以及與此URL測試:

/test?start=2016-10-8T00:00 

我得到以下錯誤:

{ 
    "timestamp": 1477528408379, 
    "status": 400, 
    "error": "Bad Request", 
    "exception": "org.springframework.web.method.annotation.MethodArgumentTypeMismatchException", 
    "message": "Failed to convert value of type [java.lang.String] to required type [java.time.LocalDateTime]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam @org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime] for value '2016-10-8T00:00'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2016-10-8T00:00]", 
    "path": "/test" 
} 

回答

8

@RequestParam已足夠抓住=號後面提供的日期,但是,它作爲String進入方法。這就是爲什麼它拋出演員例外。

這將是更好的做這樣的事情:

@GetMapping("/test") 
public Page<User> get(@RequestParam(value="start", required = false) String start){ 

    //Create a DateTimeFormatter with your required format: 
    DateTimeFormatter dateTimeFormat = 
      new DateTimeFormatter(DateTimeFormatter.BASIC_ISO_DATE); 

    //Next parse the date from the @RequestParam, specifying the TO type as a TemporalQuery: 
    LocalDateTime date = dateTimeFormat.parse(start, LocalDateTime::from); 

    //Do the rest of your code... 
} 

側面說明,如果你使用了Spring啓動網絡,您可能要仔細檢查,如果它是@GetMapping("/url")@RequestMapping("/url"),如果你的目的是要從HTTP請求執行此方法。

+0

當然,但有一個主要問題 - 爲什麼使用自定義控制器,如果對於大多數請求您可以使用Spring JPA存儲庫?實際上這個錯誤的問題發生在這個地方;/ – thorinkor

+4

你也可以在簽名方法中使用這個解決方案:'@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)LocalDateTime start' – Anna

+0

@ Anna的解決方案非常適合我 – MatanRubin

2

我遇到了同樣的問題,發現我的解決方案here(不使用註釋)

...you must at least properly register a string to [LocalDateTime] Converter in your context, so that Spring can use it to automatically do this for you every time you give a String as input and expect a [LocalDateTime]. (A big number of converters are already implemented by Spring and contained in the core.convert.support package, but none involves a [LocalDateTime] conversion)

所以你的情況,你會做到這一點:

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

,然後就註冊你的bean:

<bean class="com.mycompany.mypackage.StringToLocalDateTimeConverter"/> 

With Annotations

它添加到您的ConversionService:

@Component 
public class SomeAmazingConversionService extends GenericConversionService { 

    public SomeAmazingConversionService() { 
     addConverter(new StringToLocalDateTimeConverter()); 
    } 

} 

最後你會那麼@Autowire在ConversionService:

@Autowired 
private SomeAmazingConversionService someAmazingConversionService; 

你可以閱讀更多關於這個帶彈簧(和格式)轉換site。預先警告說,它有大量的廣告,但我絕對認爲它是一個有用的網站和一個很好的主題介紹。

7

你做了一切正確的:)。 Here是一個示例,顯示你正在做什麼。 只需@DateTimeFormat註釋您的RequestParam。在控制器中不需要特殊的GenericConversionService或手動轉換。 This博客文章寫道。

@RestController 
@RequestMapping("/api/datetime/") 
final class DateTimeController { 

    @RequestMapping(value = "datetime", method = RequestMethod.POST) 
    public void processDateTime(@RequestParam("datetime") 
           @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime dateAndTime) { 
     //Do stuff 
    } 
} 

我想你有一個格式問題。在我的設置上一切正常。

2

就像我放在評論,你也可以使用在簽名方法此解決方案:@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime start

0

我找到了解決方法here

Spring/Spring Boot only supports the date/date-time format in BODY parameters.

這種配置類增加了支持日期/時間的查詢字符串:

@Configuration 
public class DateTimeFormatConfiguration extends WebMvcConfigurerAdapter { 

    @Override 
    public void addFormatters(FormatterRegistry registry) { 
     DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); 
     registrar.setUseIsoFormat(true); 
     registrar.registerFormatters(registry); 
    } 
} 

它的工作原理,即使你綁定多個請求參數某一類(@DateTimeFormat標註在這種情況下,無奈):

public class ReportRequest { 
    private LocalDate from; 
    private LocalDate to; 

    public LocalDate getFrom() { 
     return from; 
    } 

    public void setFrom(LocalDate from) { 
     this.from = from; 
    } 

    public LocalDate getTo() { 
     return to; 
    } 

    public void setTo(LocalDate to) { 
     this.to = to; 
    } 
} 

// ... 

@GetMapping("/api/report") 
public void getReport(ReportRequest request) { 
// ... 
相關問題