前端時間元件清空後傳值“null“怎麼處理?
技術標籤:開發常見問題javaelementuimybatis
前端時間元件清空後傳值"null"怎麼處理?
最近使用mybatis-plus的過程中,最近遇到一個讓我比較無語的問題
就是這個❌號
本來條件查詢都是沒有問題的,但就在我點完❌,清空已選擇的時間後,出現了錯誤!
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'accident' on field 'startTime': rejected value [null]; codes [typeMismatch.accident.startTime,typeMismatch.startTime,typeMismatch.java.time.LocalDateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [accident.startTime,startTime]; arguments []; default message [startTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'startTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.format.annotation.DateTimeFormat @com.fasterxml.jackson.annotation.JsonFormat java.time.LocalDateTime] for value 'null'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [null]] at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:164) at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
Failed to convert property value of type ‘java.lang.String’ to required type ‘java.time.LocalDateTime’ for property 'startTime’
經過我的認真排查,我發現:
原來在我點完❌後,前端給我傳過來了個“null”!
不是空!是一個String型的null!
所以產生了型別轉換異常!
可能大家覺得型別轉化一下不就可以了嗎?
先給大家看下當時的場景:
entity層:
/**
* 事故開始時間
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss" )
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;
/**
* 事故結束時間
*/
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime endTime;
Controller層
@GetMapping ("/accident")
public ObjectResponseResult listAccident(Page<Accident> page, Accident accident) {
return new ObjectResponseResult(CommonCode.SUCCESS, accidentService.page(page, Wrappers.<Accident>lambdaQuery()
.like(nonNull(accident.getName()),Accident::getName,accident.getName())
.like(nonNull(accident.getType()),Accident::getType,accident.getType())
.like(nonNull(accident.getLevel()),Accident::getLevel,accident.getLevel())
.between(nonNull(accident.getStartTime()),Accident::getStartTime,accident.getStartTime(),accident.getEndTime())
));
}
由於資料庫中的型別定義的是timestamp,所以我一早就將實體類定義成了LocalDateTime(以前我用的Stirng)
而且Controller層接收的時候是整個實體類接收的,因此,這個報錯是在未進入我的Controller就產生的,是因為實體類型別( LocalDateTime)與傳參型別(String)不匹配造成的,所以,我也沒有辦法在Controller層進行型別轉換。
而且由於這張表與其他表之間關聯較大,我也不能修改資料庫中或實體類中的事件型別。
那麼該如何解決呢?
首先
我先複製這個實體類(Accident),將其中的時間型別變成了Stirng,新實體類名為 AccidentExample
然後
我用AccidentExample作為引數接收前端資料,並進行了判斷轉換,將String型別的null變成了null,
然後使用 BeanUtils.copyProperties,將accidentExample接收到的引數賦值給accident
這樣就避免了報錯的產生。
@GetMapping("/accident")
public ObjectResponseResult listAccident(Page<Accident> page, AccidentExample accidentExample) {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
Accident accident = new Accident();
if("null".equals(accidentExample.getStartTime()) ||
"null".equals(accidentExample.getEndTime())){
BeanUtils.copyProperties(accidentExample,accident);
accident.setEndTime(null);
accident.setStartTime(null);
}else {
LocalDateTime start = LocalDateTime.parse(accidentExample.getStartTime(),df);
LocalDateTime end = LocalDateTime.parse(accidentExample.getEndTime(),df);
System.out.println("String型別的時間轉成LocalDateTime:"+start);
BeanUtils.copyProperties(accidentExample,accident);
accident.setStartTime(start);
accident.setEndTime(end);
}
return new ObjectResponseResult(CommonCode.SUCCESS, accidentService.page(page, Wrappers.<Accident>lambdaQuery()
.like(nonNull(accident.getName()),Accident::getName,accident.getName())
.like(nonNull(accident.getType()),Accident::getType,accident.getType())
.like(nonNull(accident.getLevel()),Accident::getLevel,accident.getLevel())
.between(nonNull(accident.getStartTime()),Accident::getStartTime,accident.getStartTime(),accident.getEndTime())
));
}
雖然問題解決了,但是感覺這個方法比較笨,歡迎大家指導!
另外,如果有後端朋友遇到這樣的問題,可以直接給前端提issue,其實這個時間選擇器清空後傳值“null”的問題不算是後端的問題,主要是新來的前端同事不會處理,我在後端幫忙處理了一下,如果有前端朋友看到這篇文章,親參考這位作者的文章 https://blog.csdn.net/lixinhua_man/article/details/109257316,有詳細的處理過程。
如有轉載,請標明出處,謝謝!