大家好,我是冰河~~最近在使用SpringBoot+K8S开发微服务系统。由于我用的是K8S,所以不想用SpringCloud。为什么,因为K8S本身就提供了非常多的服务注册与发现、限流、熔断、负载均衡等微服务需要用到的6种技术,为什么还需要接入SpringCloud呢?嗯,说的很多,我真正使用SpringBoot+K8S技术栈的时候,也会遇到一些问题。比如我不需要用SpringCloud的时候,我调用其他服务的时候,我用的是原生的OpenFegin,调用其他服务我用的是OpenFegin。这时候遇到了一个大坑。OpenFeign请求返回的LocalDateTime异常。今天就来说说这个坑吧!好了,开始吧~~项目集成OpenFeginIntegrationOpenFeginDependency首先说一下项目的配置和整个项目。SpringBoot版本为2.2.6,OpenFegin原生使用11.0。我们在pom.xml中引入OpenFegin如下。UTF-8false1.811.0io.github.openfeignfeign-core${openfegin.version}io.github.openfeignfeign-jackson${openfegin.version}这里,我省略了一些其他配置项。接下来,我开始使用OpenFegin在我的项目中调用远程服务。具体步骤如下。实现远程调用首先,创建OpenFeignConfig类并配置OpenFegin使用的默认合约。@ConfigurationpublicclassOpenFeignConfig{@BeanpublicContractuseFeignAnnotations(){returnnewContract.Default();}}接下来,我们写一个通用工厂类来获取OpenFeign客户端。这个类也比较简单。本质上,它使用一个HashMap来缓存所有的FeginClients。这个FeginClient本质上就是我们自定义的Fegin接口,缓存中的Key是请求连接的baseURL,缓存的Value就是我们定义的FeginClient接口。publicclassFeginClientFactory{/***缓存所有Fegin客户端*/privatevolatilestaticMapfeginClientCache=newHashMap<>();/***从Map获取数据*@return*/@SuppressWarnings("unchecked")publicstaticTgetFeginClient(Classclazz,StringbaseUrl){if(!feginClientCache.containsKey(baseUrl)){synchronized(FeginClientFactory.class){if(!feginClientCache.containsKey(baseUrl)){TfeginClient=Feign.builder().decoder(newJacksonDecoder()).encoder(newJacksonEncoder()).target(clazz,baseUrl);feginClientCache.put(baseUrl,feginClient);}}}return(T)feginClientCache.get(baseUrl);}}接下来,我们定义一个FeginClient界面。publicinterfaceFeginClientProxy{@Headers("Content-Type:application/json;charset=UTF-8")@RequestLine("POST/user/login")UserLoginVologin(UserLoginVologinVo);}接下来,我们创建一个SpringBoot测试类。@RunWith(SpringRunner.class)@SpringBootTestpublicclassIcpsWeightStarterTest{@TestpublicvoidtestUserLogin(){ResponseMessageresult=FeginClientFactory.getFeginClient(FeginClientProxy.class,"http://127.0.0.1").login(newUserLoginVo("zhangsan","123456",1));System.out.println(JsonUtils.bean2Json(result));}}万事俱备,运行测试。马丹,出事了。主要问题是OpenFeign请求返回的LocalDateTime字段会出现异常!!!注意:此时出现异常时,我们在LocalDateTime字段中添加的注解如下。importjava.time.LocalDateTime;importcom.baomidou.mybatisplus.annotation.FieldField;importcom.baomidou.mybatisplus.annotation.TableField;importcom.fasterxml.jackson.annotation.JsonFormat;@TableField(value="CREATE_TIME",fill=FieldFill.INSERT)@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss",locale="zh",timezone="GMT+8")privateLocalDateTimecreateTime;解决问题问题描述SpringBoot通过原生OpenFeign客户端调用HTTP接口,如果返回值包含LocalDateTime类型(包括JSR-310中java.time包的其他时间类),可能会出现反序列化失败的错误在客户端。报错信息如下:Causedby:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:Cannotconstructinstanceof`java.time.LocalDateTime`(noCreators,likedefaultconstruct,exist):noString-argumentconstructor/factorymethodtodeserializefromStringvalue('2020-10-07T11:04:32')问题分析从客户端调用fegin相当于传递了一个URL参数,相当于进行了一次JSON转换。从数据库中取出'2020-10-07T11:04:32'的数据。此时的数据是时间类型的。进入JSON后,变成了String类型,T变成了字符,不再是特殊字符,所以String的字符串“2020-10-07T11:04:32”反序列化会失败。问题已解决将依赖项添加到项目中。com.fasterxml.jackson.datatypejackson-datatype-jsr3102.9.9注意:如果是使用SpringBoot,并且明确指定了SpringBoot版本。引入jackson-datatype-jsr310时,不需要指定版本号。接下来,将以下注释添加到POJO类的LocalDateTime类型字段。importcom.fasterxml.jackson.databind.annotation.JsonDeserialize;importcom.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;添加后的效果如下。importjava.time.LocalDateTime;importcom.baomidou.mybatisplus.annotation.FieldFill;importcom.baomidou.mybatisplus.annotation.TableField;importcom.fasterxml.jackson.annotation.JsonFormat;importcom.fasterxml.jackson.databind.annotation.JsonDeserialize;importcom.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;@TableField(value="CREATE_TIME",fill=FieldFill.INSERT)@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss",locale="zh",timezone="GMT+8")@JsonDeserialize(using=LocalDateTimeDeserializer.class)privateLocalDateTimecreateTime;这时再次调用远程接口,问题解决。