使用FeignClient調用POST表單Body內沒有參數問題
FeignClient調用POST表單Body沒有參數
1、問題:在使用FeignClient調用第三方接口,對方是普通POST接口,但是調用返回400,后發(fā)現請求體沒有攜帶需要的參數。
2、查找資料發(fā)現,FeignClient默認POST請求發(fā)送參數為JSON格式,如需要使用表單形式,必須自定義設置。
3、附代碼
import com.lenovo.mt.config.FormFeignConfiguration; import com.lenovo.mt.remote.eservice.vo.EServiceToken; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; /** ?* @Description ?* @Author zhaoke ?* @Date 2019/12/16 10:42 ?**/ @FeignClient(name = "***", url = "${***}",configuration = FormFeignConfiguration.class, fallback = TokenFail.class) public interface ITokenRemote { ? ? @PostMapping(value = "***",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) ? ? EServiceToken getToken(@RequestParam("client_id")String clientId,@RequestParam("client_secret")String clientSecret,@RequestParam("grant_type")String grantType); }
其中主要設置在FormFeignConfiguration這個類中
import feign.codec.Encoder; import feign.form.FormEncoder; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Scope; import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; /** ?* @Description ?* @Author zhaoke ?* @Date 2019/12/17 13:05 ?**/ @Configuration public class FormFeignConfiguration { ? ? @Autowired ? ? private ObjectFactory<HttpMessageConverters> messageConverters; ? ? @Bean ? ? @Primary ? ? @Scope(SCOPE_PROTOTYPE) ? ? Encoder feignFormEncoder() { ? ? ? ? return new FormEncoder(new SpringEncoder(this.messageConverters)); ? ? } }
FeignClient參數問題
使用Get方式調用服務提供者
服務消費者,需要在所有參數前加上@RequestParam注解
服務消費者,指明是Get方式,如果不指明那么在滿足條件1 的情況下默認使用get方式
1和2都滿足才使用Get方式
使用Post方式調用服務提供者
在所有參數前面加上@RequestParam注解,并且指明使用的Post方式
在參數前面加上@RequestBody注解(有且只有一個@ RequestBody)或者什么也沒有(有多個參數其余參數前面都要加上@RequestParam)
1和2滿足一個就使用Post方式
三種情況(無參、單參、多參)
無參Get
如果發(fā)送無參的Get請求,可以不指定method,默認就是Get請求
無參Post
指定method是Post方式,否則就是Get請求
單參Get
指定該參數是@RequestParam修飾,這時候method默認是Get,也可以自己指定Get方式
單參Post
該參數前面加@RequestParam修飾,并且使用Post方式
或者
使用@RequestBody修飾該參數,或者沒使用@RequestParam和@RequestBody修飾該參數,再這個使用不論指定Post還是Get都會使用Post進行請求
注意:
在使用fegin消費服務的時候,如果參數前面什么也沒寫,默認是@RequestBody來修飾的
@RequestBody修飾的參數需要以Post方式來傳遞
在服務提供者的Controller中:
1.如果要接收@RequestBody指明的參數,那么對應方法的對應參數前一定要有@RequestBody;(如果沒有的話,收到的參數值就為null;如果寫成@RequestParam的話,那么feign調用會失敗)
2.如果接收@ RequestParam指明的參數,那么可以寫@ RequestParam也可以不寫,如果參數名稱一致不用,不一致需要寫
多參Get
需要在所有參數前面添加@ RequestParam注解,這時候可以加Get也可以不加Get
多參Post
服務消費者中,最多只能有一個參數是@RequestBody指明的,其余的參數必須使用@RequestParam指明
也可以在第一個參數前面什么也不寫(默認使用@RequestBody修飾)其余的參數都需要加@RequestParam
如果所有參數都是以@RequestParam修飾,并且使用的是Post方式,那么也是以Post方式來請求
在服務提供者的Controller中:
1.如果服務消費者傳過來參數時,全都用的是@RequestParam的話,那么服務提供者的Controller中對應參數前可以寫@RequestParam,也可以不寫(當兩邊參數名字一致時,可以省略不寫)
2. 如果服務消費者傳過來參數時,有@RequestBody的話,那么服務提供者的Controller中對應參數前必須要寫@RequestBody(如果是多參數的話,其余參數前視情況可以寫@RequestParam,也可以不寫)
@RequestBody和@RequestParam的區(qū)別
@RequestParam用來處理Content-Type: 為 application/x-www-form-urlencoded編碼的內容,在Http中如果不指定Content-Type則默認使用application/x-www-form-urlencoded類型
@ RequestBody,處理HttpEntity傳遞過來的數據,用來處理非Content-Type: application/x-www-form-urlencoded編碼格式的數據
Get請求沒有HttpEntity所以不用@ RequestBody
POST請求中,通過HttpEntity傳遞的參數,必須要在請求頭中聲明數據的類型Content-Type,SpringMVC通過使用HandlerAdapter 配置的HttpMessageConverters來解析HttpEntity中的數據,然后綁定到相應的bean上
總結:Get不能使用表單,只能在url中傳參,傳參方式只有這一種。 Post可以使用表單,也可以在url中傳參。使用表單時有幾種數據類型(表現為數據的存儲位置不同):
1、x-www-form-urlencoded 參數存儲在query中 用@RequestParam接收。
2、formdata 參數存儲在body中,用@RequestBody接收,文件類型用@RequestPart接收。
3、raw(josn,xml) 參數存儲在body中 用@RequetBody接收。
總結一下: 凡是放在body中的都可以用@RequestBody接收,文件類型的數據可以用@RequestPart接收。 凡是放在query中的都可以用@RequestParam接收,包括Get方式提交和Post(x-www-form-urlencoded)方式提交的
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Java中String類getBytes()方法詳解與完整實例
這篇文章主要給大家介紹了關于Java中String類getBytes()方法詳解與完整實例的相關資料,getBytes()是Java編程語言中將一個字符串轉化為一個字節(jié)數組byte[]的方法,需要的朋友可以參考下2023-10-10Spring如何利用@Value注解讀取yml中的map配置
這篇文章主要介紹了Spring如何利用@Value注解讀取yml中的map配置,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02SpringBoot?基于?MongoTemplate?的工具類過程詳解
MongoDB是一個高性能,開源,無模式的文檔型數據庫,是當前NoSql數據庫中比較熱門的一種,這篇文章主要介紹了SpringBoot基于MongoTemplate的工具類,需要的朋友可以參考下2023-09-09詳解SpringBoot中@PostMapping注解的用法
在SpringBoot中,我們經常需要編寫RESTful Web服務,以便于客戶端與服務器之間的通信,@PostMapping注解可以讓我們更方便地編寫POST請求處理方法,在本文中,我們將介紹@PostMapping注解的作用、原理,以及如何在SpringBoot應用程序中使用它2023-06-06spring boot2.0圖片上傳至本地或服務器并配置虛擬路徑的方法
最近寫了關于圖片上傳至本地文件夾或服務器,上傳路徑到數據庫,并在上傳時預覽圖片。本文通過實例代碼給大家分享spring boot2.0圖片上傳至本地或服務器并配置虛擬路徑的方法,需要的朋友參考下2018-12-12