為Spring Cloud Finchley的Feign 配置 FastJson

相關(guān)環(huán)境:

Spring Boot:2.0.5.RELEASE

Spring Cloud :Finchley.RELEASE

FastJson:1.2.54

配置代碼:

/**

* 單獨(dú)為feign配置fastjson

*/

@SpringBootConfiguration

public class FeignConfig {

@Bean

    public EncoderfeignEncoder() {

return new SpringEncoder(feignHttpMessageConverter());

    }

@Bean

    public DecoderfeignDecoder() {

return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));

    }

private ObjectFactoryfeignHttpMessageConverter() {

final HttpMessageConverters httpMessageConverters =

new HttpMessageConverters(getFastJsonConverter());

        return () ->httpMessageConverters;

    }

private FastJsonHttpMessageConvertergetFastJsonConverter() {

FastJsonHttpMessageConverter converter =

new FastJsonHttpMessageConverter();

        List supportedMediaTypes =new ArrayList<>();

//        MediaType mediaTypeJson =

//                MediaType.valueOf(MediaType.APPLICATION_JSON_UTF8_VALUE);

//        supportedMediaTypes.add(mediaTypeJson);

        MediaType mediaTypeJson =

MediaType.valueOf(MediaType.TEXT_PLAIN_VALUE +";charset=UTF-8");

        supportedMediaTypes.add(mediaTypeJson);

        converter.setSupportedMediaTypes(supportedMediaTypes);

        FastJsonConfig config =new FastJsonConfig();

        config.getSerializeConfig()

.put(JSON.class, new SwaggerJsonSerializer());

        config.setSerializerFeatures(

SerializerFeature.DisableCircularReferenceDetect);

        converter.setFastJsonConfig(config);

        return converter;

    }

}

原因:

我想大家對fastJsonHttpMessageConverters的配置應(yīng)該很熟悉了,網(wǎng)上的文章也是一大片,而我一開始也是如此只進(jìn)行了全局配置呛伴。然后在使用Feign調(diào)用服務(wù)測試時畦粮,報錯了:

feign.codec.DecodeException: Could not extract response: no suitable HttpMessageConverter found for response type [class java.lang.Object] and content type [text/plain;charset=UTF-8]

at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:169)

at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:133)

at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)

at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)

at com.sun.proxy.$Proxy92.hello(Unknown Source)

at com.example.test.TestDB.test(TestDB.java:26)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)

at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)

at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)

at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)

at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)

at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)

at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)

at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)

at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)

at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)

at org.junit.runners.ParentRunner.run(ParentRunner.java:363)

at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)

at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)

at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)

at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)

at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class java.lang.Object] and content type [text/plain;charset=UTF-8]

at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:119)

at org.springframework.cloud.openfeign.support.SpringDecoder.decode(SpringDecoder.java:60)

at org.springframework.cloud.openfeign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:45)

at feign.optionals.OptionalDecoder.decode(OptionalDecoder.java:23)

at feign.SynchronousMethodHandler.decode(SynchronousMethodHandler.java:165)

... 35 more

后來百度發(fā)現(xiàn)是Feign不和SpringMvc共用一個HttpMessageConverter绞吁,所以需要單獨(dú)配置哗脖。因為SpringMvc默認(rèn)使用的Jackson糊肠,所以我便看到了:

@SpringBootConfiguration

public class FeignByJacksonConfig {

@Bean

    public DecoderfeignDecoder() {

return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));

    }

public ObjectFactoryfeignHttpMessageConverter() {

final HttpMessageConverters httpMessageConverters =new HttpMessageConverters(new PhpMappingJackson2HttpMessageConverter());

        return new ObjectFactory() {

@Override

            public HttpMessageConvertersgetObject()throws BeansException {

return httpMessageConverters;

            }

};

    }

public class PhpMappingJackson2HttpMessageConverterextends MappingJackson2HttpMessageConverter {

PhpMappingJackson2HttpMessageConverter(){

List mediaTypes =new ArrayList<>();

            mediaTypes.add(MediaType.valueOf(MediaType.TEXT_PLAIN_VALUE +";charset=UTF-8")); //關(guān)鍵

            setSupportedMediaTypes(mediaTypes);

        }

}

}

他們通過繼承MappingJackson2HttpMessageConverter去改變MediaType闸盔,而結(jié)果也是成功的悯辙。但是為了和全局統(tǒng)一配置(也為了我的強(qiáng)迫癥),我便想著如何給Feign配置fastjson迎吵,后來找到了一篇文章(會在文末給出鏈接)躲撰,但使用后發(fā)現(xiàn)依然錯誤。百思不得其解之時击费,發(fā)現(xiàn)了SpringDecoder和SpringEncoder的不同:

FeignClientsConfiguration初始化配置中:

默認(rèn)Encoder類型為SpringEncoder拢蛋,功能為調(diào)用Spring的HttpMessageConverters處理參數(shù)。

默認(rèn)Decoder類型為ResponseEntityDecoder蔫巩,它包裝了SpringDecoder瓤狐,做的事情也就是調(diào)用Spring的HttpMessageConverters處理接口返回值。


@Bean

public EncoderfeignEncoder() {

return new SpringEncoder(feignHttpMessageConverter());

}

原來一開始配置的SpringEncoder只處理了請求時的參數(shù)批幌,對于返回值仍未作更改础锐,所以后來我加上了SpringDecoder后就成功了:

@Bean

public DecoderfeignDecoder() {

return new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()));

}

參考文章鏈接:

https://blog.csdn.net/synsdeng/article/details/78380552

http://www.reibang.com/p/5461eb5386a8

http://www.reibang.com/p/b3b93a32cb05

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市荧缘,隨后出現(xiàn)的幾起案子皆警,更是在濱河造成了極大的恐慌,老刑警劉巖截粗,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件信姓,死亡現(xiàn)場離奇詭異鸵隧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)意推,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門豆瘫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人菊值,你說我怎么就攤上這事外驱。” “怎么了腻窒?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵昵宇,是天一觀的道長。 經(jīng)常有香客問我儿子,道長瓦哎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任柔逼,我火速辦了婚禮蒋譬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘愉适。我一直安慰自己犯助,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布儡毕。 她就那樣靜靜地躺著也切,像睡著了一般扑媚。 火紅的嫁衣襯著肌膚如雪腰湾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天疆股,我揣著相機(jī)與錄音费坊,去河邊找鬼。 笑死旬痹,一個胖子當(dāng)著我的面吹牛附井,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播两残,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼永毅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了人弓?” 一聲冷哼從身側(cè)響起沼死,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎崔赌,沒想到半個月后意蛀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耸别,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年县钥,在試婚紗的時候發(fā)現(xiàn)自己被綠了秀姐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡若贮,死狀恐怖省有,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情兜看,我是刑警寧澤锥咸,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站细移,受9級特大地震影響搏予,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弧轧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一雪侥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧精绎,春花似錦速缨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至搁吓,卻和暖如春原茅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背堕仔。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工擂橘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人摩骨。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓通贞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恼五。 傳聞我的和親對象是個殘疾皇子昌罩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容