SpringCloud?Feign?傳輸Date類型參數(shù)存在誤差的問題
Feign傳輸Date類型參數(shù)存在誤差
最近在項(xiàng)目開發(fā)過程中,前端傳遞過來的時(shí)間(Date類型)在A模塊是正確的,然后A模塊調(diào)用B模塊將時(shí)間(Date類型)作為參數(shù)傳過去,然后B模塊接收到的時(shí)間有誤差,天數(shù)會(huì)多一天,小時(shí)少10小時(shí),這應(yīng)該是SpringCloud Feign組件造成的問題
我這里的解決辦法是在A模塊調(diào)用之前先將時(shí)間(Date類型)轉(zhuǎn)為String類型,B模塊接收到A模塊的參數(shù)后將時(shí)間由String類型再轉(zhuǎn)為Date類型就可以了
時(shí)間轉(zhuǎn)換代碼如下
/** ?* 日期格式化為字符串 ?* ?* @param source ?* @return java.lang.String ?* @author zxzhang ?* @date 2020/2/9 ?*/ public Date string2date(String source) throws ParseException { ? ? SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ? ? return sdf.parse(source); } ? /** ?* 字符串解析為日期 ?* ?* @param source ?* @return java.lang.String ?* @author zxzhang ?* @date 2020/2/9 ?*/ public String date2String(Date source) { ? ? SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ? ? return sdf.format(source); }
到此 Feign 傳輸Date類型參數(shù)存在誤差的問題完美解決。
Feign傳輸date類型參數(shù),時(shí)間差14個(gè)小時(shí)
Java Date類型的時(shí)差問題
請(qǐng)看下邊這段代碼
public static void main(String[] args) throws Exception { ? ? Date date1 = new Date(); ? ? System.out.println("date1: " + date1.toString()); ? ? Date date2 = new Date(date1.toString()); ? ? System.out.println("date2: " + date2.toString()); }
執(zhí)行結(jié)果如下
date1: Mon Jul 22 08:47:19 CST 2019
date2: Mon Jul 22 22:47:19 CST 2019
當(dāng)前時(shí)間是2019年7月22日8點(diǎn)48分,CST是中國的時(shí)區(qū)China Standard Time的簡稱,但是可以看到date2的輸入比實(shí)際時(shí)間多了14個(gè)小時(shí)。
CTS代表的時(shí)區(qū)其實(shí)有四個(gè)(Central Standard Time (USA) UT-6:00、Central Standard Time (Australia) UT+9:30、China Standard Time UT+8:00、Cuba Standard Time UT-4:00),同時(shí)表示美國,澳大利亞,中國,古巴四個(gè)國家的標(biāo)準(zhǔn)時(shí)間。
原因
new Date(date1.toString())
這個(gè)方法會(huì)調(diào)用Date.parse(String)方法,它傳的參數(shù)是Mon Jul 22 08:47:19 CST 2019,這個(gè)方法上有一段注釋
* <li>Any word that matches <tt>EST, CST, MST</tt>, or <tt>PST</tt>, * ? ? ignoring case, is recognized as referring to the time zone in * ? ? North America that is five, six, seven, or eight hours west of * ? ? Greenwich, respectively. Any word that matches <tt>EDT, CDT, * ? ? MDT</tt>, or <tt>PDT</tt>, ignoring case, is recognized as * ? ? referring to the same time zone, respectively, during daylight * ? ? saving time.</ul><p>
可以看到CST會(huì)被當(dāng)作美國中部的時(shí)區(qū)Central Standard Time,即JVM認(rèn)為你傳入的時(shí)間是美國中部的時(shí)間,而當(dāng)date2調(diào)用toString方法的時(shí)候,它會(huì)檢測(cè)到系統(tǒng)的時(shí)區(qū)是中國,就會(huì)自動(dòng)加14個(gè)小時(shí)(東八區(qū)與西六區(qū)的時(shí)差),就變成了Mon Jul 22 22:47:19 CST 2019
解決方法
這個(gè)問題其實(shí)如果自己寫代碼的話很難出現(xiàn),因?yàn)樗械腏ava書籍都不會(huì)這么教,大多數(shù)都是通過SimpleDateFormat,進(jìn)行Date和String的轉(zhuǎn)換,畢竟new Date(date1.toString())這個(gè)方法已經(jīng)標(biāo)注為廢棄了
Feign客戶端的問題
Feign客戶端在進(jìn)行通信時(shí),會(huì)調(diào)用Date的toString方法轉(zhuǎn)為String類型,服務(wù)端在接受的時(shí)候,使用的就是new Date(String)這個(gè)方法,這里就會(huì)發(fā)生前邊介紹的問題,產(chǎn)生14個(gè)小時(shí)的時(shí)差
解決方法
在客戶端添加代碼,規(guī)定Feign在將Date參數(shù)轉(zhuǎn)化成String參數(shù)的格式:
import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.openfeign.FeignFormatterRegistrar; import org.springframework.core.convert.converter.Converter; import org.springframework.format.FormatterRegistry; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; ? @Slf4j @Component public class FeignDateFormatRegister implements FeignFormatterRegistrar { ? ? ? @Override ? ? public void registerFormatters(FormatterRegistry registry) { ? ? ? ? registry.addConverter(Date.class, String.class, new Date2StringConverter()); ? ? } ? ? ? private class Date2StringConverter implements Converter<Date, String> { ? ? ? ? @Override ? ? ? ? public String convert(Date source) { ? ? ? ? ? ? SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ? ? ? ? ? ? return sdf.format(source); ? ? ? ? } ? ? ? } }
在服務(wù)端添加代碼,規(guī)定SpringContext在String和Date時(shí)的用的轉(zhuǎn)化器,讓轉(zhuǎn)化器知道我們?cè)诳蛻舳伺渲玫膮?shù)格式:
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; ? import javax.annotation.PostConstruct; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; ? @Slf4j @Configuration public class FeignConfiguration { ? ? ? @Autowired ? ? private RequestMappingHandlerAdapter handlerAdapter; ? ? ? /** ? ? ?* ?增加字符串轉(zhuǎn)日期的功能 ? ? ?? ? ? ?*/ ? ? @PostConstruct ? ? public void initEditableValidation() { ? ? ? ? ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) handlerAdapter.getWebBindingInitializer(); ? ? ? ? if (initializer.getConversionService() != null) { ? ? ? ? ? ? GenericConversionService genericConversionService = (GenericConversionService) initializer.getConversionService(); ? ? ? ? ? ? genericConversionService.addConverter(String.class, Date.class, new String2DateConverter()); ? ? ? ? } ? ? } ? ? ? class String2DateConverter implements Converter<String, Date> { ? ? ? ? @Override ? ? ? ? public Date convert(String source) { ? ? ? ? ? ? SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? return simpleDateFormat.parse(source); ? ? ? ? ? ? } catch (ParseException e) { ? ? ? ? ? ? ? ? log.error("", e); ? ? ? ? ? ? } ? ? ? ? ? ? return null; ? ? ? ? } ? ? } }
注意以上兩個(gè)配置類需要自己配置包掃描之類的把它們加到Spring環(huán)境中
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringCloud使用Feign實(shí)現(xiàn)動(dòng)態(tài)路由操作
- 解決SpringCloud?Feign異步調(diào)用傳參問題
- SpringCloud基于Feign的可編程式接口調(diào)用實(shí)現(xiàn)
- springcloud使用feign調(diào)用服務(wù)時(shí)參數(shù)內(nèi)容過大問題
- SpringCloud?Feign請(qǐng)求頭刪除修改的操作代碼
- springcloud feign傳輸List的坑及解決
- Springcloud?feign傳日期類型參數(shù)報(bào)錯(cuò)的解決方案
- SpringCloud Feign多參數(shù)傳遞及需要注意的問題
- Spring Cloud超詳細(xì)i講解Feign自定義配置與使用
相關(guān)文章
Java簡單使用redis-zset實(shí)現(xiàn)排行榜
這篇文章主要介紹了Java簡單使用redis-zset實(shí)現(xiàn)排行榜,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12SpringBoot實(shí)現(xiàn)PDF添加水印的三種方法
本文主要介紹了SpringBoot實(shí)現(xiàn)PDF添加水印的三種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07springboot?實(shí)現(xiàn)接口灰度發(fā)布的實(shí)例詳解
這篇文章主要介紹了springboot?實(shí)現(xiàn)接口灰度發(fā)布,簡單來說就是能夠根據(jù)業(yè)務(wù)規(guī)則的調(diào)整交互上呈現(xiàn)不同的形式,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03使用?EasyCode生成springboot+mybatis基礎(chǔ)程序的實(shí)現(xiàn)示例
本文主要介紹了使用?EasyCode生成springboot+mybatis基礎(chǔ)程序的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01如何使用Spring Boot ApplicationRunner解析命令行中的參數(shù)
這篇文章主要介紹了使用Spring Boot ApplicationRunner解析命令行中的參數(shù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12Idea如何使用Fast Request接口調(diào)試
這篇文章主要介紹了Idea如何使用Fast Request接口調(diào)試問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11Springboot整合zookeeper實(shí)現(xiàn)對(duì)節(jié)點(diǎn)的創(chuàng)建、監(jiān)聽與判斷的案例詳解
這篇文章主要介紹了基于Springboot整合zookeeper實(shí)現(xiàn)對(duì)節(jié)點(diǎn)的創(chuàng)建、監(jiān)聽與判斷,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06