您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)如何解決SpringCloud Feign傳輸Date類型參數(shù)存在誤差的問題,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
最近在項目開發(fā)過程中,前端傳遞過來的時間(Date類型)在A模塊是正確的,然后A模塊調(diào)用B模塊將時間(Date類型)作為參數(shù)傳過去,然后B模塊接收到的時間有誤差,天數(shù)會多一天,小時少10小時,這應(yīng)該是SpringCloud Feign組件造成的問題
我這里的解決辦法是在A模塊調(diào)用之前先將時間(Date類型)轉(zhuǎn)為String類型,B模塊接收到A模塊的參數(shù)后將時間由String類型再轉(zhuǎn)為Date類型就可以了
/** * 日期格式化為字符串 * * @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ù)存在誤差的問題完美解決。
請看下邊這段代碼
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)前時間是2019年7月22日8點48分,CST是中國的時區(qū)China Standard Time的簡稱,但是可以看到date2的輸入比實際時間多了14個小時。
CTS代表的時區(qū)其實有四個(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),同時表示美國,澳大利亞,中國,古巴四個國家的標(biāo)準(zhǔn)時間。
原因
new Date(date1.toString())
這個方法會調(diào)用Date.parse(String)方法,它傳的參數(shù)是Mon Jul 22 08:47:19 CST 2019,這個方法上有一段注釋
* <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會被當(dāng)作美國中部的時區(qū)Central Standard Time,即JVM認(rèn)為你傳入的時間是美國中部的時間,而當(dāng)date2調(diào)用toString方法的時候,它會檢測到系統(tǒng)的時區(qū)是中國,就會自動加14個小時(東八區(qū)與西六區(qū)的時差),就變成了Mon Jul 22 22:47:19 CST 2019
這個問題其實如果自己寫代碼的話很難出現(xiàn),因為所有的Java書籍都不會這么教,大多數(shù)都是通過SimpleDateFormat,進(jìn)行Date和String的轉(zhuǎn)換,畢竟new Date(date1.toString())這個方法已經(jīng)標(biāo)注為廢棄了
Feign客戶端在進(jìn)行通信時,會調(diào)用Date的toString方法轉(zhuǎn)為String類型,服務(wù)端在接受的時候,使用的就是new Date(String)這個方法,這里就會發(fā)生前邊介紹的問題,產(chǎn)生14個小時的時差
在客戶端添加代碼,規(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時的用的轉(zhuǎn)化器,讓轉(zhuǎn)化器知道我們在客戶端配置的參數(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; } } }
注意以上兩個配置類需要自己配置包掃描之類的把它們加到Spring環(huán)境中
關(guān)于“如何解決SpringCloud Feign傳輸Date類型參數(shù)存在誤差的問題”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。