@GetMapping("get/localDateTime")
@ApiOperation(value = "get 请求 localDateTime 作为参数赋值", produces = "application/json")
public BaseResponse get(LocalDateTime localDateTime) {
return BaseResponse.success(LocalDateTimeUtils.format(localDateTime, DateFromatEnum.YYYY_MM_DD_HH_MM_SS));
}
@GetMapping("get/localDateTime/2")
@ApiOperation(value = "get 请求 localDateTime 作为参数赋值", produces = "application/json")
public BaseResponse getRequestParam(@RequestParam LocalDateTime localDateTime) {
return BaseResponse.success(LocalDateTimeUtils.format(localDateTime, DateFromatEnum.YYYY_MM_DD_HH_MM_SS));
}
@PostMapping("post/localDateTime")
@ApiOperation(value = "post 请求 localDateTime 作为参数赋值", produces = "application/json")
public BaseResponse post(LocalDateTime localDateTime) {
return BaseResponse.success(LocalDateTimeUtils.format(localDateTime, DateFromatEnum.YYYY_MM_DD_HH_MM_SS));
}
@PostMapping("post/localDateTime/2")
@ApiOperation(value = "post 请求 localDateTime 作为参数赋值", produces = "application/json")
public BaseResponse postRequestParam(@RequestParam LocalDateTime localDateTime) {
return BaseResponse.success(LocalDateTimeUtils.format(localDateTime, DateFromatEnum.YYYY_MM_DD_HH_MM_SS));
}
org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: 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 [java.time.LocalDateTime] for value '2020-06-18 11:00:00'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2020-06-18 11:00:00]
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:133)
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:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
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:503)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:763)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1631)
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:226)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at brave.servlet.TracingFilter.doFilter(TracingFilter.java:67)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.boot.web.servlet.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:54)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at cn.zhangfusheng.base.server.fileter.ProjectBaseFilter.doFilter(ProjectBaseFilter.java:55)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter.doFilter(ExceptionLoggingFilter.java:50)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at brave.servlet.TracingFilter.doFilter(TracingFilter.java:84)
at org.springframework.cloud.sleuth.instrument.web.LazyTracingFilter.doFilter(TraceWebServletAutoConfiguration.java:138)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
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.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:549)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1610)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1363)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:489)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1580)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1278)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:500)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:547)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:375)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value '2020-06-18 11:00:00'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2020-06-18 11:00:00]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:129)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:53)
at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:693)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:125)
... 73 common frames omitted
Caused by: java.lang.IllegalArgumentException: Parse attempt failed for value [2020-06-18 11:00:00]
at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:223)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
... 79 common frames omitted
Caused by: java.time.format.DateTimeParseException: Text '2020-06-18 11:00:00' could not be parsed at index 2
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at org.springframework.format.datetime.standard.TemporalAccessorParser.parse(TemporalAccessorParser.java:75)
at org.springframework.format.datetime.standard.TemporalAccessorParser.parse(TemporalAccessorParser.java:46)
at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:217)
... 80 common frames omitted
package cn.zhangfusheng.base.server.converter;
import cn.zhangfusheng.util.base.date.LocalDateTimeUtils; // 自定义的时间格式化工具
import cn.zhangfusheng.util.base.exception.GlobalException; // 自定义的全局异常
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.convert.converter.Converter;
import java.time.LocalDateTime;
/**
* @description : 自定义类型转换器
* @author: fusheng.zhang
* @date: 2019/5/17 11:10
*/
@Slf4j
public class TypeConverter {
/**
* @description : LocalDateTime 类型转换器
* @author: fusheng.zhang
* @date: 2019/5/17 10:54
*/
public static class LocalDateTimeConvert implements Converter {
@Override
public LocalDateTime convert(String source) {
if (StringUtils.isBlank(source)) {
throw new NullPointerException();
}
return LocalDateTimeUtils.parseMatches(source);
}
}
}
package cn.zhangfusheng.base.server.config;
import cn.zhangfusheng.base.server.converter.TypeConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @description :
* @author: fusheng.zhang
* @date: 2019/5/17 11:33
*/
@Slf4j
@Configuration
public class TypeConfig implements WebMvcConfigurer {
/**
* 添加类型转换器
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
log.debug("加载处理时间请求参数的Convert");
registry.addConverter(new TypeConverter.LocalDateTimeConvert());
}
}
package cn.zhangfusheng.user.server.controller;
import java.time.LocalDateTime;
public class LocalDateTimeModel {
private LocalDateTime createTime;
private LocalDateTime updateTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
}
@PostMapping("post/model/localDateTime")
@ApiOperation(value = "post 请求 localDateTime 作为参数赋值", produces = "application/json")
public BaseResponse<Object> postRequestBody(@RequestBody LocalDateTimeModel model) {
return BaseResponse.success(model);
}
前端传递如下请求参数:
{ “createTime”: “2020-06-18T03:50:06.024Z”, “updateTime”: “2020-06-18T03:50:06.024Z”}
接口可以正常接收到参数
传递如下格式的参数
{ “createTime”: “2020-06-18 03:55:02”, “updateTime”: “2020-06-18 03:55:02”}
发生如下异常
at [Source: (PushbackInputStream); line: 2, column: 17] (through reference chain: cn.zhangfusheng.user.server.controller.LocalDateTimeModel["createTime"])
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.time.LocalDateTime` from String "2020-06-18 03:55:02": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2020-06-18 03:55:02' could not be parsed at index 10; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDateTime` from String "2020-06-18 03:55:02": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2020-06-18 03:55:02' could not be parsed at index 10
at [Source: (PushbackInputStream); line: 2, column: 17] (through reference chain: cn.zhangfusheng.user.server.controller.LocalDateTimeModel["createTime"])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:245)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:227)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:205)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:158)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:131)
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:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
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.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:523)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:763)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1631)
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:226)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at brave.servlet.TracingFilter.doFilter(TracingFilter.java:67)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.boot.web.servlet.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:54)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at cn.zhangfusheng.base.server.fileter.ProjectBaseFilter.doFilter(ProjectBaseFilter.java:55)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter.doFilter(ExceptionLoggingFilter.java:50)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at brave.servlet.TracingFilter.doFilter(TracingFilter.java:84)
at org.springframework.cloud.sleuth.instrument.web.LazyTracingFilter.doFilter(TraceWebServletAutoConfiguration.java:138)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
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.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1618)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:549)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1610)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1363)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:489)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1580)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1278)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:500)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:547)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:135)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDateTime` from String "2020-06-18 03:55:02": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2020-06-18 03:55:02' could not be parsed at index 10
at [Source: (PushbackInputStream); line: 2, column: 17] (through reference chain: cn.zhangfusheng.user.server.controller.LocalDateTimeModel["createTime"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1698)
at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:947)
at com.fasterxml.jackson.datatype.jsr310.deser.JSR310DeserializerBase._handleDateTimeException(JSR310DeserializerBase.java:129)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:102)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:39)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:371)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:164)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4482)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3487)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:239)
... 76 common frames omitted
Caused by: java.time.format.DateTimeParseException: Text '2020-06-18 03:55:02' could not be parsed at index 10
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:100)
... 83 common frames omitted
package cn.zhangfusheng.base.server.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @description :
* @author: fusheng.zhang
* @date: 2019/5/17 11:33
*/
@Slf4j
@Configuration
public class TypeConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}
{
"result": 200,
"msg": null,
"data": {
"createTime": [
2020,
6,
18,
3,
55,
2
],
"updateTime": [
2020,
6,
18,
3,
55,
2
]
}
}
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 序列化
javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
package cn.zhangfusheng.util.base.date.enumeration;
import java.time.format.DateTimeFormatter;
/**
* @Description 时间类型常量
* @author fusheng.zhang
* @create 2019-08-26 17:11:00
*/
public enum DateFromatEnum {
/**
* yyyy-MM-dd HH:mm:ss
*/
YYYY("yyyy"),
YYYY_MM("yyyy-MM"),
YYYY_MM_1("yyyy/MM"),
YYYY_MM_2("yyyyMM"),
YYYY_MM_DD("yyyy-MM-dd"),
YYYY_MM_DD_1("yyyy/MM/dd"),
YYYY_MM_DD_2("yyyyMMdd"),
HH_MM_SS("HH:mm:ss"),
HH_MM_SS_1("HH/mm/ss"),
HH_MM_SS_2("HHmmss"),
YYYY_MM_DD_HH("yyyy-MM-dd HH"),
YYYY_MM_DD_HH_1("yyyy/MM/dd HH"),
YYYY_MM_DD_HH_2("yyyyMMdd HH"),
YYYY_MM_DD_HH_MM("yyyy-MM-dd HH:mm"),
YYYY_MM_DD_HH_MM_1("yyyy/MM/dd HH/mm"),
YYYY_MM_DD_HH_MM_2("yyyyMMdd HHmm"),
YYYY_MM_DD_HH_MM_SS("yyyy-MM-dd HH:mm:ss"),
YYYY_MM_DD_HH_MM_SS_1("yyyy/MM/dd HH/mm/ss"),
YYYY_MM_DD_HH_MM_SS_2("yyyyMMdd HHmmss"),
;
private transient DateTimeFormatter formatter;
DateFromatEnum(String pattern) {
formatter = DateTimeFormatter.ofPattern(pattern);
}
public DateTimeFormatter getFormatter() {
return formatter;
}
public void setFormatter(DateTimeFormatter formatter) {
this.formatter = formatter;
}
}
package cn.zhangfusheng.util.base.date.enumeration;
import java.time.temporal.ChronoUnit;
/**
* @Description
* @author fusheng.zhang
* @create 2019-08-29 17:16:00
*/
public enum DateAddEnum {
/**
* 年
*/
YEARS("YEARS"),
MONTHS("MONTHS"),
DAYS("DAYS"),
HOURS("HOURS"),
MINUTES("MINUTES"),
SECONDS("SECONDS"),
WEEKS("WEEKS"),
;
private transient ChronoUnit chronoUnit;
DateAddEnum(String pattern) {
chronoUnit = ChronoUnit.valueOf(pattern);
}
public ChronoUnit getChronoUnit() {
return chronoUnit;
}
public void setChronoUnit(ChronoUnit chronoUnit) {
this.chronoUnit = chronoUnit;
}
}
package cn.zhangfusheng.util.base.date;
import cn.zhangfusheng.util.base.date.enumeration.DateAddEnum;
import cn.zhangfusheng.util.base.date.enumeration.DateFromatEnum;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
/**
* 是否需要添加 synchronized 关键字
* @author fusheng.zhang
*/
public final class LocalDateTimeUtils {
private final static String[] WEEKS = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
/**
* 获取当前时间
* @return
*/
public static String nowTime(DateFromatEnum dateFromatEnum) {
return LocalDateTimeUtils.format(LocalDateTime.now(), dateFromatEnum);
}
/**
* Date转LocalDateTime
* @param date Date对象
* @return
*/
public static LocalDateTime dateToLocalDateTime(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
/**
* LocalDateTime转换为Date
* @param dateTime LocalDateTime对象
* @return
*/
public static Date localDateTimeToDate(LocalDateTime dateTime) {
return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
}
/**
* 格式化时间
* @param localDateTime LocalDateTime对象
* @param dateFromatEnum 格式化表达式
* @return
*/
public static String format(LocalDateTime localDateTime, DateFromatEnum dateFromatEnum) {
return localDateTime.format(dateFromatEnum.getFormatter());
}
/**
* 反序列化
* 注意
* @param dateTime 字符串时间
* @param dateFromatEnum 格式化方式
* @return
*/
public static LocalDateTime parse(String dateTime, DateFromatEnum dateFromatEnum) {
if (DateFromatEnum.YYYY.equals(dateFromatEnum)) {
return Year.parse(dateTime, dateFromatEnum.getFormatter()).atDay(1).atStartOfDay();
} else if (DateFromatEnum.YYYY_MM.equals(dateFromatEnum) || DateFromatEnum.YYYY_MM_1.equals(dateFromatEnum) || DateFromatEnum.YYYY_MM_2.equals(dateFromatEnum)) {
return YearMonth.parse(dateTime, dateFromatEnum.getFormatter()).atDay(1).atStartOfDay();
} else if (DateFromatEnum.YYYY_MM_DD.equals(dateFromatEnum) || DateFromatEnum.YYYY_MM_DD_1.equals(dateFromatEnum) || DateFromatEnum.YYYY_MM_DD_2.equals(dateFromatEnum)) {
return LocalDate.parse(dateTime, dateFromatEnum.getFormatter()).atStartOfDay();
} else {
return LocalDateTime.parse(dateTime, dateFromatEnum.getFormatter());
}
}
/**
* 通过匹配正则表达式反序列化时间
* @param dateTime
* @return
*/
public static LocalDateTime parseMatches(String dateTime) {
if (dateTime.matches("^\\d{4}")) {
return parse(dateTime, DateFromatEnum.YYYY);
} else if (dateTime.matches("^\\d{4}-\\d{1,2}$")) {
return parse(dateTime, DateFromatEnum.YYYY_MM);
} else if (dateTime.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
return parse(dateTime, DateFromatEnum.YYYY_MM_DD);
} else {
return parse(dateTime, DateFromatEnum.YYYY_MM_DD_HH_MM_SS);
}
}
/**
* 获取当天的开始时间
* @param localDateTime 时间
* @return
*/
public static LocalDateTime getStartTime(LocalDateTime localDateTime) {
return localDateTime.toLocalDate().atStartOfDay();
}
/**
* 日期计算
* 根据时间单位计算
* @param localDateTime 时间
* @param amountToAdd 增值 + -
* @param dateAddEnum 时间单位 具体参考枚举 ChronoUnit
* @return
*/
public static LocalDateTime plus(LocalDateTime localDateTime, long amountToAdd, DateAddEnum dateAddEnum) {
return localDateTime.plus(amountToAdd, dateAddEnum.getChronoUnit());
}
/**
* 获取周几
* @param localDateTime
* @return
*/
public static String getWeek(LocalDateTime localDateTime) {
return WEEKS[localDateTime.getDayOfWeek().getValue()];
}
/**
* 获取本月有多少天
* @param localDateTime
* @return
*/
public static int getMonthDays(LocalDateTime localDateTime) {
return localDateTime.getMonth().length(localDateTime.toLocalDate().isLeapYear());
}
/**
* 判断今年是否是闰年
* @param localDateTime
* @return
*/
public static boolean isLeapYear(LocalDateTime localDateTime) {
return localDateTime.toLocalDate().isLeapYear();
}
/**
* 获取某天的开始时间00:00:00
* @param dateTime 某天时间
* @return
*/
public static LocalDateTime getDayStart(LocalDateTime dateTime) {
return dateTime.with(LocalTime.MIN);
}
/**
* 获取某天的结束时间23:59:59
* @param dateTime
* @return
*/
public static LocalDateTime getDayEnd(LocalDateTime dateTime) {
return dateTime.with(LocalTime.MAX);
}
/**
* 获取某月第一天的00:00:00
* @param dateTime LocalDateTime对象
* @return
*/
public static LocalDateTime getFirstDayOfMonth(LocalDateTime dateTime) {
return dateTime.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
}
/**
* 获取某月最后一天的23:59:59
* @param dateTime LocalDateTime对象
* @return
*/
public static LocalDateTime getLastDayOfMonth(LocalDateTime dateTime) {
return dateTime.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
}
/**
* 获取毫秒时间戳
* @param localDateTime
* @return
*/
public static long getMilli(LocalDateTime localDateTime) {
return localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
}
/**
* 获取周一
* @param localDate
* @return
*/
public static LocalDate getFirtWeek(LocalDate localDate) {
return localDate.with(DayOfWeek.MONDAY);
}
/**
* 获取周一
* @param localDate
* @return
*/
public static LocalDateTime getFirtWeek(LocalDateTime localDate) {
return localDate.with(DayOfWeek.MONDAY);
}
/**
* 获取一周的周日
* @param localDate
* @return
*/
public static LocalDate getEndWeek(LocalDate localDate) {
return localDate.with(DayOfWeek.SUNDAY);
}
/**
* 获取一周的周日
* @param localDateTime
* @return
*/
public static LocalDateTime getEndWeek(LocalDateTime localDateTime) {
return localDateTime.with(DayOfWeek.SUNDAY);
}
/**
* 获取时间戳
* @return
*/
public static Long getMillis() {
return System.currentTimeMillis();
}
}
package cn.zhangfusheng.base.server.converter;
import cn.zhangfusheng.util.base.date.LocalDateTimeUtils;
import cn.zhangfusheng.util.base.exception.GlobalException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.convert.converter.Converter;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @description : 自定义类型转换器
* @author: fusheng.zhang
* @date: 2019/5/17 11:10
*/
@Slf4j
public class TypeConverter {
/**
* Date 类型转换器
*
* @author zhanghang
* @date 2018/1/11
*/
public static class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
if (StringUtils.isBlank(source)) {
throw new NullPointerException();
}
return LocalDateTimeUtils.localDateTimeToDate(LocalDateTimeUtils.parseMatches(source));
}
}
/**
* @description : LocalDateTime 类型转换器
* @author: fusheng.zhang
* @date: 2019/5/17 10:54
*/
public static class LocalDateTimeConvert implements Converter<String, LocalDateTime> {
@Override
public LocalDateTime convert(String source) {
if (StringUtils.isBlank(source)) {
throw new NullPointerException();
}
return LocalDateTimeUtils.parseMatches(source);
}
}
}
package cn.zhangfusheng.base.server.config;
import cn.zhangfusheng.base.server.converter.TypeConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @description :
* @author: fusheng.zhang
* @date: 2019/5/17 11:33
*/
@Slf4j
@Configuration
public class TypeConfig implements WebMvcConfigurer {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 序列化
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// 反序列化
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
/**
* 添加类型转换器
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
log.debug("加载处理时间请求参数的Convert");
registry.addConverter(new TypeConverter.DateConverter());
registry.addConverter(new TypeConverter.LocalDateTimeConvert());
}
}