欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

feign調(diào)用中文參數(shù)被encode編譯的問題

 更新時間:2022年03月07日 08:38:42   作者:珍惜當下668  
這篇文章主要介紹了feign調(diào)用中文參數(shù)被encode編譯的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Feign調(diào)用中文參數(shù)被encode編譯

原因

在實現(xiàn)一個feign調(diào)用時使用了Post請求,并且拼接url參數(shù),name傳值為中文時被encode轉(zhuǎn)譯,且最終接取數(shù)據(jù)之前未被decode轉(zhuǎn)譯回,問題探索:

feign:

@FeignClient(name = "service-test")
public interface TestServiceApi {
? ? @PostMapping("/test/abc")
? ? public String getTestNo(@RequestParam("code") String code, @RequestParam("name") String name);
}

controller:

@RequestMapping("/test")
public interface TestController {
?? ?@Autowired
?? ?private TestService testService;
? ? @PostMapping("/abc")
? ? public String getTestNo(@RequestParam("code") String code, @RequestParam("name") String name) {
? ? ? ? return testService.query(code, name);?
? ? } ? ?
}

在controller中接到的中文參數(shù)被URIEncode轉(zhuǎn)譯了

測試 被轉(zhuǎn)譯成:%E6%B5%8B%E8%AF%95

找到feign的入口類ReflectiveFeign中拼裝RequestTemplate的方法:

? ? @Override
? ? public RequestTemplate create(Object[] argv) {
? ? ? RequestTemplate mutable = new RequestTemplate(metadata.template());
? ? ? if (metadata.urlIndex() != null) {
? ? ? ? int urlIndex = metadata.urlIndex();
? ? ? ? checkArgument(argv[urlIndex] != null, "URI parameter %s was null", urlIndex);
? ? ? ? mutable.insert(0, String.valueOf(argv[urlIndex]));
? ? ? }
? ? ? Map<String, Object> varBuilder = new LinkedHashMap<String, Object>();
? ? ? for (Entry<Integer, Collection<String>> entry : metadata.indexToName().entrySet()) {
? ? ? ? int i = entry.getKey();
? ? ? ? Object value = argv[entry.getKey()];
? ? ? ? if (value != null) { // Null values are skipped.
? ? ? ? ? if (indexToExpander.containsKey(i)) {
? ? ? ? ? ? value = expandElements(indexToExpander.get(i), value);
? ? ? ? ? }
? ? ? ? ? for (String name : entry.getValue()) {
? ? ? ? ? ? varBuilder.put(name, value);
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? ? // 組裝template的方法
? ? ? RequestTemplate template = resolve(argv, mutable, varBuilder);
? ? ? if (metadata.queryMapIndex() != null) {
? ? ? ? // add query map parameters after initial resolve so that they take
? ? ? ? // precedence over any predefined values
? ? ? ? template = addQueryMapQueryParameters(argv, template);
? ? ? }
? ? ? if (metadata.headerMapIndex() != null) {
? ? ? ? template = addHeaderMapHeaders(argv, template);
? ? ? }
? ? ? return template;
? ? }

在RequestTemplate類中如果是拼接在url后的param那么會被使用encodeValueIfNotEncoded都encode轉(zhuǎn)譯,但是不會走decode的方法 

 /**
? ?* Resolves any template parameters in the requests path, query, or headers against the supplied
? ?* unencoded arguments. <br> <br><br><b>relationship to JAXRS 2.0</b><br> <br> This call is
? ?* similar to {@code javax.ws.rs.client.WebTarget.resolveTemplates(templateValues, true)} , except
? ?* that the template values apply to any part of the request, not just the URL
? ?*/
? RequestTemplate resolve(Map<String, ?> unencoded, Map<String, Boolean> alreadyEncoded) {
? ? replaceQueryValues(unencoded, alreadyEncoded);
? ? Map<String, String> encoded = new LinkedHashMap<String, String>();
? ? for (Entry<String, ?> entry : unencoded.entrySet()) {
? ? ? final String key = entry.getKey();
? ? ? final Object objectValue = entry.getValue();
? ? ? String encodedValue = encodeValueIfNotEncoded(key, objectValue, alreadyEncoded);
? ? ? encoded.put(key, encodedValue);
? ? }
? ? String resolvedUrl = expand(url.toString(), encoded).replace("+", "%20");
? ? if (decodeSlash) {
? ? ? resolvedUrl = resolvedUrl.replace("%2F", "/");
? ? }
? ? url = new StringBuilder(resolvedUrl);
? ? Map<String, Collection<String>> resolvedHeaders = new LinkedHashMap<String, Collection<String>>();
? ? for (String field : headers.keySet()) {
? ? ? Collection<String> resolvedValues = new ArrayList<String>();
? ? ? for (String value : valuesOrEmpty(headers, field)) {
? ? ? ? String resolved = expand(value, unencoded);
? ? ? ? resolvedValues.add(resolved);
? ? ? }
? ? ? resolvedHeaders.put(field, resolvedValues);
? ? }
? ? headers.clear();
? ? headers.putAll(resolvedHeaders);
? ? if (bodyTemplate != null) {
? ? ? body(urlDecode(expand(bodyTemplate, encoded)));
? ? }
? ? return this;
? }

如果傳入的值在requestBody中,則不會被encode轉(zhuǎn)譯

? ? @Override
?? ?public void encode(Object requestBody, Type bodyType, RequestTemplate request)
?? ??? ??? ?throws EncodeException {
?? ??? ?// template.body(conversionService.convert(object, String.class));
?? ??? ?if (requestBody != null) {
?? ??? ??? ?Class<?> requestType = requestBody.getClass();
?? ??? ??? ?Collection<String> contentTypes = request.headers().get("Content-Type");
?? ??? ??? ?MediaType requestContentType = null;
?? ??? ??? ?if (contentTypes != null && !contentTypes.isEmpty()) {
?? ??? ??? ??? ?String type = contentTypes.iterator().next();
?? ??? ??? ??? ?requestContentType = MediaType.valueOf(type);
?? ??? ??? ?}
?? ??? ??? ?for (HttpMessageConverter<?> messageConverter : this.messageConverters
?? ??? ??? ??? ??? ?.getObject().getConverters()) {
?? ??? ??? ??? ?if (messageConverter.canWrite(requestType, requestContentType)) {
?? ??? ??? ??? ??? ?if (log.isDebugEnabled()) {
?? ??? ??? ??? ??? ??? ?if (requestContentType != null) {
?? ??? ??? ??? ??? ??? ??? ?log.debug("Writing [" + requestBody + "] as \""
?? ??? ??? ??? ??? ??? ??? ??? ??? ?+ requestContentType + "\" using ["
?? ??? ??? ??? ??? ??? ??? ??? ??? ?+ messageConverter + "]");
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?else {
?? ??? ??? ??? ??? ??? ??? ?log.debug("Writing [" + requestBody + "] using ["
?? ??? ??? ??? ??? ??? ??? ??? ??? ?+ messageConverter + "]");
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?FeignOutputMessage outputMessage = new FeignOutputMessage(request);
?? ??? ??? ??? ??? ?try {
?? ??? ??? ??? ??? ??? ?@SuppressWarnings("unchecked")
?? ??? ??? ??? ??? ??? ?HttpMessageConverter<Object> copy = (HttpMessageConverter<Object>) messageConverter;
?? ??? ??? ??? ??? ??? ?copy.write(requestBody, requestContentType, outputMessage);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?catch (IOException ex) {
?? ??? ??? ??? ??? ??? ?throw new EncodeException("Error converting request body", ex);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?// clear headers
?? ??? ??? ??? ??? ?request.headers(null);
?? ??? ??? ??? ??? ?// converters can modify headers, so update the request
?? ??? ??? ??? ??? ?// with the modified headers
?? ??? ??? ??? ??? ?request.headers(getHeaders(outputMessage.getHeaders()));
?? ??? ??? ??? ??? ?// do not use charset for binary data
?? ??? ??? ??? ??? ?if (messageConverter instanceof ByteArrayHttpMessageConverter) {
?? ??? ??? ??? ??? ??? ?request.body(outputMessage.getOutputStream().toByteArray(), null);
?? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ?request.body(outputMessage.getOutputStream().toByteArray(), Charset.forName("UTF-8"));
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?return;
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?String message = "Could not write request: no suitable HttpMessageConverter "
?? ??? ??? ??? ??? ?+ "found for request type [" + requestType.getName() + "]";
?? ??? ??? ?if (requestContentType != null) {
?? ??? ??? ??? ?message += " and content type [" + requestContentType + "]";
?? ??? ??? ?}
?? ??? ??? ?throw new EncodeException(message);
?? ??? ?}
?? ?}

綜合上述的調(diào)試,如果在Post中拼接參數(shù)那么會被encode轉(zhuǎn)譯,且不會被decode轉(zhuǎn)譯,如果使用body傳參,那么不會出現(xiàn)轉(zhuǎn)譯問題,如果必須使用拼接傳參,那么可以使用方法

1. @RequestLine的注解自定義參數(shù)的格式,具體參考該注解的使用方式。

2.在Feign的RequestInterceptor將傳遞的值decode的擴展方法。

記錄今天遇到的feign多參數(shù)問題

1.Post方式

錯誤寫法示例如下:

public int save(@RequestBody final User u, @RequestBody final School s);

錯誤原因:

fegin中可以有多個@RequestParam,但只能有不超過一個@RequestBody,@RequestBody用來修飾對象,但是既有@RequestBody也有@RequestParam,

那么參數(shù)就要放在請求的Url中,@RequestBody修飾的就要放在提交對象中。

注意?。?! 用來處理@RequestBody Content-Type 為 application/json,application/xml編碼的內(nèi)容

正確寫法示例如下:

public int save(@RequestBody final Person p,@RequestParam("userId") String userId,@RequestParam("userTel") String userTel);

2.Get方式

錯誤寫法示例如下:

@RequestMapping(value="/test", method=RequestMethod.GET) ?
Model test(final String name, ?final int age);?

錯誤原因:

異常原因:當使用Feign時,如果發(fā)送的是get請求,那么需要在請求參數(shù)前加上@RequestParam注解修飾,Controller里面可以不加該注解修飾,@RequestParam可以修飾多個,@RequestParam是用來修飾參數(shù),不能用來修飾整個對象。

注意:@RequestParam Content-Type 為 application/x-www-form-urlencoded 而這種是默認的

正確寫法示例如下:

@GetMapping("/getSchoolDetail")
? ? public ResultMap getSchoolDetail(@RequestParam("kSchoolId") LongkSchoolId,
? ? ?@RequestParam("kSchoolYearId") Long kSchoolYearId);

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • java動態(tài)代理實現(xiàn)代碼

    java動態(tài)代理實現(xiàn)代碼

    這篇文章主要介紹了java 動態(tài)代理的的相關資料,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下,希望能給你帶來幫助
    2021-07-07
  • 淺談在springboot中使用定時任務的方式

    淺談在springboot中使用定時任務的方式

    今天給大家?guī)淼氖顷P于Java的相關知識,文章圍繞著在springboot中使用定時任務的方式展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Spring?Boot項目抵御XSS攻擊實戰(zhàn)過程

    Spring?Boot項目抵御XSS攻擊實戰(zhàn)過程

    XSS攻擊又稱跨站腳本攻擊,通常指利用網(wǎng)頁開發(fā)時留下的漏洞,通過巧妙的方法注入惡意指令代碼到網(wǎng)頁,使用戶加載并執(zhí)行攻擊者惡意制造的網(wǎng)頁程序,下面這篇文章主要給大家介紹了關于Spring?Boot項目抵御XSS攻擊的相關資料,需要的朋友可以參考下
    2022-11-11
  • Dubbo本地調(diào)試的幾種方式總結(jié)

    Dubbo本地調(diào)試的幾種方式總結(jié)

    dubbo服務方啟動時需要加載的東西太多,如果跑單元測試把服務開啟會浪費不少時間,而且單元測試沒法保持服務一直開啟的狀態(tài),這篇文章主要給大家介紹了關于Dubbo本地調(diào)試的幾種方式,需要的朋友可以參考下
    2022-11-11
  • SWT(JFace) 打印功能

    SWT(JFace) 打印功能

    SWT(JFace)體驗之打印功能
    2009-06-06
  • java多線程處理執(zhí)行solr創(chuàng)建索引示例

    java多線程處理執(zhí)行solr創(chuàng)建索引示例

    這篇文章主要介紹了java多線程處理執(zhí)行solr創(chuàng)建索引示例,需要的朋友可以參考下
    2014-02-02
  • Java如何導出數(shù)據(jù)庫中的所有數(shù)據(jù)表到指定文件夾

    Java如何導出數(shù)據(jù)庫中的所有數(shù)據(jù)表到指定文件夾

    這篇文章主要介紹了Java導出數(shù)據(jù)庫中的所有數(shù)據(jù)表到指定文件夾,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • 用Java程序判斷是否是閏年的簡單實例

    用Java程序判斷是否是閏年的簡單實例

    下面小編就為大家?guī)硪黄肑ava程序判斷是否是閏年的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • Maven的pom.xml文件結(jié)構(gòu)中的build

    Maven的pom.xml文件結(jié)構(gòu)中的build

    本文主要介紹了Maven的pom.xml文件結(jié)構(gòu)中的build,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • AsyncHttpClient IOExceptionFilter異常過濾器

    AsyncHttpClient IOExceptionFilter異常過濾器

    這篇文章主要為大家介紹了AsyncHttpClient IOExceptionFilter異常過濾器代碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12

最新評論