Feign中Post请求自动转为Get踩坑记录

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值