Feign报错Method Not Allowed 405 5种解决方案

这篇具有很好参考价值的文章主要介绍了Feign报错Method Not Allowed 405 5种解决方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一,问题产生背景

Feign发送Get请求时,采用POJO传递参数 Method Not Allowed 405

@FeignClient("microservice-provider-user")
public interface UserFeignClient {

  @RequestMapping(value = "/user", method = RequestMethod.GET)
  public PageBean<User> get(User user);
  
}

二,问题产生原因

sun.net.www.protocol.http;

public class HttpURLConnection extends java.net.HttpURLConnection {

  // 这里很简单:只要你doOutput = true了,你是get请求的话也会强制给你转为POST请求
    private synchronized OutputStream getOutputStream0() throws IOException {
        try {
            if (!this.doOutput) {
                throw new ProtocolException("cannot write to a URLConnection if doOutput=false - call setDoOutput(true)");
            } else {
                if (this.method.equals("GET")) {
                    this.method = "POST";
                }
      }
      ...
  }
}

这段代码是在 HttpURLConnection 中发现的,jdk原生的http连接请求工具类,原来是因为Feign默认使用的连接工具实现类,所以里面发现只要你有body体对象,就会强制的把get请求转换成POST请求。

三,解决方案

1,方案一使用Map 接收参数

量大的话改的东西多

使用@Validated验证的时候不支持了,需要手动调用校验方法

@FeignClient("microservice-provider-user")
public interface UserFeignClient {
  //@RequestParam不要指定参数
  @RequestMapping(value = "/user", method = RequestMethod.GET)
  public PageBean<User> get(@RequestParam Map<String,Object> param);
  
}

2,方案二不用实体接收,改为单独的参数

量大的话改的东西多

@FeignClient("microservice-provider-user")
public interface UserFeignClient {
  @RequestMapping(value = "/user", method = RequestMethod.GET)
  public PageBean<User> get(@RequestParam("name") String name,@RequestParam("age") int age);
  
}

3,方案三修改feign的请求工具

默认的是jdk的,可以修改为okhttp 或者 httpclent

yml:

feign:
  httpclient:
    enabled: true

maven:文章来源地址https://www.toymoban.com/news/detail-773209.html

  <!--httpClient-->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.3</version>
            </dependency>

            <dependency>
                <groupId>com.netflix.feign</groupId>
                <artifactId>feign-httpclient</artifactId>
                <version>8.17.0</version>
            </dependency>

四,方案四添加RequestInterceptor 拦截器

package com.mugua.demo.config;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;

/**
 * GET 405
 *
 * @author liwenchao
 */
@Component
public class FeignRequestParamInterceptor implements RequestInterceptor {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    public void apply(RequestTemplate template) {
        // feign 不支持 GET 方法传 POJO, json body转query
        if ("GET".equals(template.method()) && template.requestBody() != null) {
            try {
                JsonNode jsonNode = OBJECT_MAPPER.readTree(template.requestBody().asBytes());
                template.body(Request.Body.empty());
                Map<String, Collection<String>> queries = new HashMap<>();
                buildQuery(jsonNode, "", queries);
                template.queries(queries);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void buildQuery(JsonNode jsonNode, String path, Map<String, Collection<String>> queries) {
        // 叶子节点
        if (!jsonNode.isContainerNode()) {
            if (jsonNode.isNull()) {
                return;
            }
            Collection<String> values = queries.computeIfAbsent(path, k -> new ArrayList<>());
            values.add(jsonNode.asText());
            return;
        }
        // 数组节点
        if (jsonNode.isArray()) {
            Iterator<JsonNode> it = jsonNode.elements();
            while (it.hasNext()) {
                buildQuery(it.next(), path, queries);
            }
        } else {
            Iterator<Map.Entry<String, JsonNode>> it = jsonNode.fields();
            while (it.hasNext()) {
                Map.Entry<String, JsonNode> entry = it.next();
                if (StringUtils.hasText(path)) {
                    buildQuery(entry.getValue(), path + "." + entry.getKey(), queries);
                } else {  // 根节点
                    buildQuery(entry.getValue(), entry.getKey(), queries);
                }
            }
        }
    }
}

5,方案五重写SpringMvcContract

package com.mugua.demo.config;

import feign.MethodMetadata;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import java.lang.annotation.Annotation;
import java.util.List;

/**
 * GET 405
 *
 * @author lwc
 */
@Component
public class SpringMvcPojoObjectQueryContract extends SpringMvcContract {

    public SpringMvcPojoObjectQueryContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors, ConversionService conversionService) {
        super(annotatedParameterProcessors, conversionService);
    }

    @Override
    protected boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {
        boolean httpAnnotation = super.processAnnotationsOnParameter(data, annotations, paramIndex);
        //在springMvc中如果是Get请求且参数中是对象 没有声明为@RequestBody 则默认为Param
        if (!httpAnnotation && "GET".equalsIgnoreCase(data.template().method())) {
            for (Annotation parameterAnnotation : annotations) {
                if (!(parameterAnnotation instanceof RequestBody)) {
                    return false;
                }
            }
            data.queryMapIndex(paramIndex);
            return true;
        }
        return httpAnnotation;
    }
}

到了这里,关于Feign报错Method Not Allowed 405 5种解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 项目启动Feign调用报错 The bean ‘xxx.FeignClientSpecification‘ could not be registered 的解决方案

    xxx.FeignClientSpecification无法注册 问题现象: xxx.FeignClientSpecification无法注册。已定义具有该名称的 Bean,并且已禁用覆盖。 解决方案:

    2024年02月16日
    浏览(43)
  • 【nginx】405 not allowed问题解决方法

    一、问题描述 首先看到的页面是nginx返回的页面,得知错误要从nginx上来解决 二、问题原因 因为这里请求的静态文件采用的是post方法,nginx是不允许post访问静态资源。题话外,试着post访问了下www.baidu.com发现页面也是报错,可以试着用get方式访问 三、解决办法(三种) (

    2024年02月16日
    浏览(43)
  • Nginx的405 not allowed错误解决

    1、问题情况 首先看到的页面是nginx返回的页面,得知错误要从nginx上来解决 2、问题原因 因为这里请求的静态文件采用的是post方法,nginx是不允许post访问静态资源。题话外,试着post访问了下www.baidu.com发现页面也是报错,可以试着用get方式访问 3、问题解决 现贴出三种解决方

    2024年02月11日
    浏览(39)
  • 解决nginx 部署前端post请求405 not allowed

    问题第一次部署前端,将vue生成的dist 文件部署到nginx后,进入页面后post请求查询数据时,出现405 not allowed,经查阅发现,nginx 静态资源访问不支持post请求。 解决方案

    2024年02月11日
    浏览(38)
  • Method *** Not Allowed 解决办法集锦

    使用DRF框架进行接口测试时,出现“method PUT(或\\\\DELETE) not allowed!”,经过多方搜索, 问题分析见: 最终发现无外乎以下操作可以尝试解决: 此时路径需要如下设置,不然会报下面四的问题: 1.默认的viewset和默认的router,但发送put、delete请求提示不支持 官方实现update方

    2024年02月16日
    浏览(43)
  • Mysql 报 java.sql.SQLException:null,message from server:“Host ‘‘ is not allowed to connect.解决方案

    这个错误i是因为mysql数据库没有放开远程访问权限引起的,以mysql8为例 首先进入Mysql 安装目录,然后输入命令: mysql -uroot -p ;具体参见下图: 再输入 use mysql; 回车执行, 接着输入, show tables; 回车执行 输入, select host from user; 回车执行,这里特别说明一下,我这个是已经放

    2024年04月28日
    浏览(42)
  • Spring Cloud Feign实战来袭:工程中配置断路器Hystrix报错NoClassDefFoundError:HystrixCommandAspect解决方案

    在Spring Cloud Feign工程中配置断路器Hystrix的时候,pom.xml文件已经加入Hystrix相关的jar: Application.java: 可以看出来是找不到HystrixCommandAspec.java这个类,于是在github上找到这个源文件: https://github.com/dmgcodevil/Hystrix/blob/958ec5d7b4bb967be077a4c2bbcdc71e7a7f5248/hystrix-contrib/hystrix-javanica/src/mai

    2024年02月16日
    浏览(48)
  • postman调用接口报{“detail“:“Method \“DELETE\“ not allowed.“}错误, 解决记录

    项目是python代码开发, urls.py 路由中访问路径代码如下: 对应view视图中代码如下: 上面代码可以看到我要执行的是一个删除操作, 使用的是python drf模型, 自己使用postman调用,界面参数如下: 会发现下面就报出了Method not allowed的错误提示信息, 经过查阅资料有说改什么windows电脑设置

    2024年02月04日
    浏览(45)
  • SpringBoot+Vue项目中遇到Not allowed to load local resource图片路径问题的两种解决方案(在后端映射本地路径或将图片转base64返回给前端)

    后端映射本地路径 转base64格式返回 如果是少量图片可以这么操作,不然图片多的话返回base64由于字符太长,传输速度很慢,会导致卡顿现象、加载慢、加载异常等情况出现。 图片转base64 base64转图片保存 headPhotoPath = “D:yangleProjectImageLocationheadPhoto” userPhotoPath = “nologin”

    2024年02月06日
    浏览(50)
  • node.js报错 ReferenceError require is not defined 解决方案

    从node.js 14版及以上版本中,require作为COMMONJS的一个命令已不再直接支持使用,所以我们需要导入createRequire命令才可以; 在使用 require 的地方需要加入以下代码:

    2024年01月18日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包