springboot 解析前端传来的时间字符串后端LocalDateTime解析失败 could not be parsed, unparsed text found at index 10
springboot 解析前端传来的时间字符串后端LocalDateTime解析失败 could not be parsed, unparsed text found at index 10
·
问题还原
前端通过GET请求后端接口 参数如下
http://XXX/station/line/goods?to=lts&startTime=2022-10-17 00:00:00&endTime=2022-10-17 23:59:59&fs=11&ss=197,11,193&page=0
后端接收代码
@GetMapping(value = {"/station/line/goods"})
public WebAsyncTask<ResponseResult> stationSearch(SearchParamDTO searchParamDTO
, Pageable pageRequest
, SessionInfo sessionInfo) {
}
SearchParamDTO 实体对象
package com.cqbxzc.go.sale.goods.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import live.jialing.util.time.ClockUtil;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
* 检索条件
*
* @author baizt
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString(callSuper = true)
public class SearchParamDTO implements Serializable {
/**
* 商品供应商ID集合
*/
private List<Long> ss;
/**
* 商品类目编码集合
*/
private List<String> ds;
/**
* 线路名称或编码
*/
private String line;
/**
* 线路编码
*/
private String lc;
/**
* 线路名称
*/
private String ln;
/**
* 线路ID
*/
private Long l;
/**
* 班次号
*/
private String lrc;
/**
* 班次ID
*/
private Long lrd;
/**
* 微信小程序的appId
*/
private String w;
/**
* 起点:名称或助记码
*/
private String from;
/**
* 起点:班次经停站点ID
*/
private Long fromId;
/**
* 起点:场站(商户)ID
*/
private Long fs;
/**
* 起点:区/县级行政编码
*/
private String fa;
/**
* 起点:乡镇/街道行政编码
*/
private String ft;
/**
* 起点:经度
*/
private Double fromLon;
/**
* 起点:纬度
*/
private Double fromLat;
/**
* 终点:名称或助记码
*/
private String to;
/**
* 终点:班次经停站点ID
*/
private Long toId;
/**
* 终点:场站(商户)ID
*/
private Long ts;
/**
* 终点:区/县级行政编码
*/
private String ta;
/**
* 终点:乡镇/街道行政编码
*/
private String tt;
/**
* 终点:经度
*/
private Double toLon;
/**
* 终点:纬度
*/
private Double toLat;
/**
* 发车时间:开始 2018-01-11 09:45:01
*/
@DateTimeFormat(pattern = ClockUtil.LOCAL_DATE_TIME_FORMATTER_PATTERN)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = ClockUtil.LOCAL_DATE_TIME_FORMATTER_PATTERN, timezone = ClockUtil.DEFAULT_TIME_ZONE)
private LocalDateTime startTime;
/**
* 发车时间:结束 2018-01-11 09:45:02
*/
@DateTimeFormat(pattern = ClockUtil.LOCAL_DATE_TIME_FORMATTER_PATTERN)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = ClockUtil.LOCAL_DATE_TIME_FORMATTER_PATTERN, timezone = ClockUtil.DEFAULT_TIME_ZONE)
private LocalDateTime endTime;
}
调用结果
GET - /yesgs/station/line/goods
18:02:25.371 [http-nio-8081-exec-1] ERROR c.c.b.w.h.ControllerExceptionHandler - org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'searchParamDTO' on field 'endTime': rejected value [2022-10-17 23:59:59]; codes [methodInvocation.searchParamDTO.endTime,methodInvocation.endTime,methodInvocation.java.time.LocalDateTime,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [searchParamDTO.endTime,endTime]; arguments []; default message [endTime]]; default message [Property 'endTime' threw exception; nested exception is java.time.format.DateTimeParseException: Text '2022-10-17 23:59:59' could not be parsed, unparsed text found at index 10]
Field error in object 'searchParamDTO' on field 'startTime': rejected value [2022-10-17 00:00:00]; codes [methodInvocation.searchParamDTO.startTime,methodInvocation.startTime,methodInvocation.java.time.LocalDateTime,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [searchParamDTO.startTime,startTime]; arguments []; default message [startTime]]; default message [Property 'startTime' threw exception; nested exception is java.time.format.DateTimeParseException: Text '2022-10-17 00:00:00' could not be parsed, unparsed text found at index 10]
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'searchParamDTO' on field 'endTime': rejected value [2022-10-17 23:59:59]; codes [methodInvocation.searchParamDTO.endTime,methodInvocation.endTime,methodInvocation.java.time.LocalDateTime,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [searchParamDTO.endTime,endTime]; arguments []; default message [endTime]]; default message [Property 'endTime' threw exception; nested exception is java.time.format.DateTimeParseException: Text '2022-10-17 23:59:59' could not be parsed, unparsed text found at index 10]
Field error in object 'searchParamDTO' on field 'startTime': rejected value [2022-10-17 00:00:00]; codes [methodInvocation.searchParamDTO.startTime,methodInvocation.startTime,methodInvocation.java.time.LocalDateTime,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [searchParamDTO.startTime,startTime]; arguments []; default message [startTime]]; default message [Property 'startTime' threw exception; nested exception is java.time.format.DateTimeParseException: Text '2022-10-17 00:00:00' could not be parsed, unparsed text found at index 10]
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)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at com.cqbxzc.gateway.security.filter.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.cqbxzc.boot.webmvc.context.filter.LogFilter.doFilterInternal(LogFilter.java:59)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
18:02:25.482 [http-nio-8081-exec-1] INFO c.c.g.s.RequestIdempotentInterceptor - Response . 耗时 248 毫秒
问题解决
通过百度找资料一直没有找到,没有办法只有更具断点调试springMvc源码
最终发现如果配置@InitBinde属性编辑器spring会自动取你配置的属性编辑器来解析对应类型的属性
PropertyEditor editor=this.customEditors.get(requiredType);
该方法存在于PropertyEditorRegistrySupport类中
@Nullable
private PropertyEditor getCustomEditor(@Nullable Class<?> requiredType) {
if (requiredType == null || this.customEditors == null) {
return null;
}
// Check directly registered editor for type.
//在次方法获取的属性编辑器
PropertyEditor editor = this.customEditors.get(requiredType);
if (editor == null) {
// Check cached editor for type, registered for superclass or interface.
if (this.customEditorCache != null) {
editor = this.customEditorCache.get(requiredType);
}
if (editor == null) {
// Find editor for superclass or interface.
for (Iterator<Class<?>> it = this.customEditors.keySet().iterator(); it.hasNext() && editor == null;) {
Class<?> key = it.next();
if (key.isAssignableFrom(requiredType)) {
editor = this.customEditors.get(key);
// Cache editor for search type, to avoid the overhead
// of repeated assignable-from checks.
if (this.customEditorCache == null) {
this.customEditorCache = new HashMap<>();
}
this.customEditorCache.put(requiredType, editor);
}
}
}
}
return editor;
}
发现果然配置LocalDateTime属性解析器
*/
@InitBinder
protected void initBinder(WebDataBinder binder) {
// Double
binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class, true));
// Date
SimpleDateFormat sdf = new SimpleDateFormat(ClockUtil.LOCAL_DATE_FORMATTER_PATTERN);
// 这个的功能是不把1996-13-3 转换为1997-1-3
// 这样输入1996-2-31这样的数据也会验证出来错误的,但是前提是要设置Lenient为false
sdf.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
// LocalDateTime 等
binder.registerCustomEditor(LocalDateTime.class, new LocaleDateTimeEditor(LocalDateTime.class, "yyyy-MM-dd", true));
binder.registerCustomEditor(LocalDate.class, new LocaleDateTimeEditor(LocalDate.class, "yyyy-MM-dd", true));
binder.registerCustomEditor(LocalTime.class, new LocaleDateTimeEditor(LocalTime.class, "HH:mm:ss", true));
}
最后去掉了 binder.registerCustomEditor(LocalDateTime.class, new LocaleDateTimeEditor(LocalDateTime.class, “yyyy-MM-dd”, true));
问题解决
更多推荐
已为社区贡献3条内容
所有评论(0)