Feign请求方式
在使用Feign的过程中,有时候会用到post请求和put请求,正常来说,这两种请求使用body传递参数不会有什么问题,但是如果使用@RequestParam传递参数的话,feign会将请求转为Get请求
同理,如果在使用Get请求的时候传递了body参数,那么,真实发送的其实是Post请求
如果在使用的过程中遇到类型的情况可以从这方面考虑下原因
示例
@PostMapping("/user/verifyOnly")
R<Boolean> verifyOnly(@RequestParam("phone") String phone);
// feign会按get请求发送
@GetMapping("/user/ancestor")
R<List<SysUser>> ancestorUsers(@RequestBody UserDTO userDTO);
// feign会按Post请求发送
也就是说,feign不会按Mapping的类型来进行发送请求,会根据参数类型自动转换为对应类型的请求,然后进行发送
解决方案
1、严格按照要求编写接口,Get请求中不加body参数,Post请求和Put请求需要加body参数
2、自定义拦截器,在拦截器中将body传递进去
package com.ralph.common.feign.config;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// 处理POST请求的时候转换成了GET的bug
if (HttpMethod.POST.name().equals(template.method()) && template.requestBody().length() == 0 && !template.queries().isEmpty()) {
// 获取请求头信息
Boolean isPost = Optional.of(template.headers()).map(item -> item.get("ralph-cus-header"))
.map(item -> item.contains("post"))
.orElse(false);
if (isPost){
StringBuilder builder = new StringBuilder();
Map<String, Collection<String>> queries = template.queries();
Iterator<String> queriesIterator = queries.keySet().iterator();
while (queriesIterator.hasNext()) {
String field = queriesIterator.next();
Collection<String> strings = queries.get(field);
// 由于参数已经做了url编码处理,这里直接拼接即可
builder.append(field + "=" + StringUtils.join(strings, ","));
builder.append("&");
}
template.body(Request.Body.encoded(builder.toString().getBytes(), template.requestCharset()));
template.queries(null);
}
}
}
}
这么使用的话,需要在feign中增加@RequestHeader("ralph-cus-header") String cusHeader
参数,值为post
👍 欢迎前往博客主页查看更多内容
👍 如果觉得不错,期待您的点赞、收藏、评论、关注
👍 如有错误欢迎指正!
👍 Gitee地址:https://gitee.com/ralphchen/ralph-cloud