springboot~對@RequestParam中Date參數的(de)適(shi)配
@RequestParam中的Date類型的參數,如果前端給一個2001-01-01在(zai)后端默認(ren)是不(bu)認(ren)的(de),我(wo)(wo)們在(zai)后端需要對這種情況進行適(shi)配(pei),我(wo)(wo)們可以通(tong)過@ControllerAdvice注(zhu)解來攔截請求(qiu),然后對Date參數進行轉(zhuan)換,最終(zhong)實(shi)現我(wo)(wo)們的(de)需求(qiu)。
- 實現org.springframework.core.convert.converter.Convert接口,來完成日期格式的轉換
public class CourseDateConverter implements Converter<String, Date> {
private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
private static final String dateFormata = "yyyy-MM-dd HH:mm:ss";
private static final String shortDateFormat = "yyyy-MM-dd";
private static final String shortDateFormata = "yyyy/MM/dd";
private static final String timeStampFormat = "^\\d+$";
@Override
public Date convert(String value) {
if (StringUtils.isEmpty(value)) {
return null;
}
value = value.trim();
try {
if (value.contains("-")) {
SimpleDateFormat formatter;
if (value.contains(":")) {
// yyyy-MM-dd HH:mm:ss 格式
formatter = new SimpleDateFormat(dateFormat);
} else {
// yyyy-MM-dd 格式
formatter = new SimpleDateFormat(shortDateFormat);
}
return formatter.parse(value);
} else if (value.matches(timeStampFormat)) {
//時間戳
Long lDate = new Long(value);
return new Date(lDate);
} else if (value.contains("/")) {
SimpleDateFormat formatter;
if (value.contains(":")) {
// yyyy/MM/dd HH:mm:ss 格式
formatter = new SimpleDateFormat(dateFormata);
} else {
// yyyy/MM/dd 格式
formatter = new SimpleDateFormat(shortDateFormata);
}
return formatter.parse(value);
}
} catch (Exception e) {
throw new RuntimeException(String.format("parser %s to Date fail", value));
}
throw new RuntimeException(String.format("parser %s to Date fail", value));
}
}
- 通過@InitBinder來注入轉換器
@InitBinder作用于@Controller中的方法,表示為當前控制器注冊一個屬性編輯器,對WebDataBinder進行初始化,且只對當前的Controller有效。 - @InitBinder執行時機
@InitBinder注解被解析的時機,是其所標注的方法,在該方法被請求執行之前。同時@InitBinder標注的方法是可以多次執行的,也就是說來一次請求就執行一次@InitBinder解析。 - @InitBinder執行原理
當某個Controller上的第一次請求,由SpringMVC前端控制器匹配到該Controller之后,根據Controller的 class 類型來查找所有標注了@InitBinder注解的方法,并且存入RequestMappingHandlerAdapter里的 initBinderCache 緩存中。等下一次請求執行對應業務方法之前,會先走initBinderCache緩存,而不用再去解析@InitBinder。
@ControllerAdvice
public class TimeControllerHandler {
@InitBinder
public void initBinder(WebDataBinder binder) {
GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService();
if (genericConversionService != null) {
genericConversionService.addConverter(new CourseDateConverter());
}
}
}
這樣,前端傳(chuan)入的日期(qi)參(can)數?fromDate=2001-01-01&endDate=2015-01-01,也是(shi)可以被(bei)后端成(cheng)功處理(li)的。