feign远程调用无法传递对象属性405的问题

目录
  • feign远程调用无法传递对象属性
    • get请求405错误
    • 使用feign请求远端
    • 客户端
    • 服务端
  • feign.FeignException$MethodNotAllowed
    • status405readingxxx#yyy(Integer)
    • 异常信息
    • 详细信息
    • 解决方案

feign远程调用无法传递对象属性

get请求405错误

通过查看feign底层源码,feign底层使用的是httpurlconnection的工具,而进行传递body的时候,会调用getOutputStrean方法,里边会判断是否是get请求,如果是get请求,则自动转为post请求,而远方的服务只能够支持get请求,因此会报错

使用feign请求远端

configuration添加如下配置类

package com.zx.consumer;
import com.google.common.collect.Lists;
import feign.Contract;
import feign.MethodMetadata;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.cloud.openfeign.annotation.PathVariableParameterProcessor;
import org.springframework.cloud.openfeign.annotation.RequestHeaderParameterProcessor;
import org.springframework.cloud.openfeign.annotation.RequestParamParameterProcessor;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.List;
/**
 * @author: zhaoxu
 * @date: 2021/4/29 0:20
 */
@Configuration
public class FeignConfiguration implements RequestInterceptor, AnnotatedParameterProcessor {
    @Override
    public void apply(RequestTemplate template) {
        //开启线程共享
        RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 对消息头进行配置
        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                String values = request.getHeader(name);
                template.header(name, values);
            }
        }
    }
    @Resource
    private ConversionService feignConversionService;
    private static final Class<RequestBody> ANNOTATION = RequestBody.class;
    @Override
    public Class<? extends Annotation> getAnnotationType() {
        return ANNOTATION;
    }
    @Override
    public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
        int paramIndex = context.getParameterIndex();
        MethodMetadata metadata = context.getMethodMetadata();
        if (metadata.queryMapIndex() == null) {
            metadata.queryMapIndex(paramIndex);
            metadata.queryMapEncoded(true);
        }
        if ("GET".equals(metadata.template().method())) {
            return true;
        }
        return false;
    }
    @Bean
    public Contract feignContract() {
        List<AnnotatedParameterProcessor> parameterProcessors = Lists.newArrayList();
        parameterProcessors.add(new PathVariableParameterProcessor());
        parameterProcessors.add(new RequestHeaderParameterProcessor());
        parameterProcessors.add(new RequestParamParameterProcessor());
        parameterProcessors.add(new FeignConfiguration());
        return new SpringMvcContract(parameterProcessors, feignConversionService);
    }
}

客户端

服务端

feign.FeignException$MethodNotAllowed

status 405 reading xxx#yyy(Integer)

异常信息

使用feign 调用异常

feign.FeignException$MethodNotAllowed: status 405 reading ConsumerService#findById(Integer)

详细信息

feign.FeignException$MethodNotAllowed: status 405 reading ConsumerService#findById(Integer)
    at feign.FeignException.errorStatus(FeignException.java:100) ~[feign-core-10.2.3.jar:na]
    at feign.FeignException.errorStatus(FeignException.java:86) ~[feign-core-10.2.3.jar:na]
    at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:93) ~[feign-core-10.2.3.jar:na]
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:149) ~[feign-core-10.2.3.jar:na]
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) ~[feign-core-10.2.3.jar:na]
    at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-10.2.3.jar:na]
    at com.sun.proxy.$Proxy74.findById(Unknown Source) ~[na:na]
    at ah.szxy.consumer.controller.ConsumerController.findById(ConsumerController.java:32) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_181]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_181]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.22.jar:9.0.22]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]

解决方案

根据异常信息可知, 接口 ConsumerService中的findById方法调用出现异常

feign.FeignException$MethodNotAllowed: status 405 reading ConsumerService#findById(Integer)

定位到该方法 , 添加@RequestParam("id")注解为其矫正参数

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 使用Feign远程调用时,序列化对象失败的解决

    Feign远程调用序列化对象失败 最近在搭建一个SpringCloud的微服务时,遇到了一个问题,在使用Feign远程调用时报错,返回对象没有无参构造方法,有其他的含参数的构造方法. 本地自己搭建的微服务目录大概如下,才刚开始,后续会逐渐补充优化迭代,有兴趣的可以fork下地址: https://github.com/zhanghailang123/MyCloud 给与指导意见. Eureka:注册中心服务端,采用Eureka注册中心 EurekaClientA:其中的一个Eureka服务端,命

  • 解决SpringCloud Feign传对象参数调用失败的问题

    SpringCloud Feign传对象参数调用失败 不支持GET请求方式 使用Apache HttpClient替换Feign原生httpclient @RequestBody接收json参数 bootstrap-local.yml feign: httpclient: enabled: true pom.xml <!-- 使用Apache HttpClient替换Feign原生httpclient --> <dependency> <groupId>com.netf

  • SpringCloud中的Feign远程调用接口传参失败问题

    目录 Feign远程调用接口传参失败 这是调用者 这是feign的client 这是被调者 Feign远程调用的注意点 定义的做远程调用的api接口 service微服务中的Controller的参数绑定 Feign远程调用接口传参失败 我在做一个微服务调用的时候出现了被调接口传参失败问题 Feign是通过http协议调用服务的,后来发现是因为Gep和Maping不一致,还有使用feign时要记得给实体类加无参构造注解 同时这些注解都尽量一致,不然微服务调bug很麻烦. 这是调用者 这是feig

  • feign远程调用无法传递对象属性405的问题

    目录 feign远程调用无法传递对象属性 get请求405错误 使用feign请求远端 客户端 服务端 feign.FeignException$MethodNotAllowed status405readingxxx#yyy(Integer) 异常信息 详细信息 解决方案 feign远程调用无法传递对象属性 get请求405错误 通过查看feign底层源码,feign底层使用的是httpurlconnection的工具,而进行传递body的时候,会调用getOutputStrean方法,里边会

  • Feign远程调用传递对象参数并返回自定义分页数据的过程解析

    目录 Feign介绍 Feign测试 1.在yml文件里面增加了配置信息 2.在客户端pom.xml文件中引入的依赖(消费者端) 3.服务调用端接口为 4.服务调用端Service代码 5.服务调用端Fallback为 6.服务提供端代码为 7.测试 Feign调用分页接口报错:MethodhastoomanyBodyparameters 解决方法 Feign介绍 Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端.Spring Cloud

  • SpringCloud学习笔记之Feign远程调用

    目录 前言 1.Feign替代RestTemplate 1.1 引入依赖 1.2 添加注释 1.3 编写Feign的客户端 1.4 测试 1.5 总结 2.自定义配置 2.1 配置文件方式 2.2 Java代码方式 3.Feign使用优化 4.最佳实践 4.1 继承方式 4.2 抽取方式 4.3 实现基于抽取的最佳实践 抽取 前言 为啥需要学Feign呢?我们先来回顾之前写的代码 先来看我们以前利用RestTemplate发起远程调用的代码: 这里就有几个问题: 代码可读性差,编程体验不统一 参

  • Feign远程调用Multipartfile参数处理

    目录 Feign远程调用Multipartfile参数 解决方案 Feign远程调用传参问题 Feign远程调用Multipartfile参数 今天在写业务代码的时候遇到的问题, 前端请求A服务,能正确把参数给到A服务<参数里面包括文件类型的 Multipartfile>,但是当A服务调用B服务时把文件参数丢过去,那边接收不到,并且会报Multipartfile 参数错误. 在网上找到了答案,特此记录一下: 解决方案 必须的 在你的fegin 服务接口暴露的地方新建一个配置类. package

  • 分布式医疗挂号系统Nacos微服务Feign远程调用数据字典

    目录 步骤1:向Nacos服务中心注册微服务 (1)引入Nacos依赖 步骤2:使用Feign进行远程调用 (1)service-hosp医院列表接口 (2)service-cmn医院等级/地址接口 (3)引入Feign依赖 (4)调用端通过包扫描Feign (5)远程调用 步骤3:使用swagger测试 需求:制作一个医院列表的显示功能.列表中包含医院编号.医院等级.医院地址.状态等.分析:首先确定是典型的条件查询带分页.由于医院的等级需要查询数据字典部分,这个调用是在不同的微服务模块中,这就

  • SpringCloud Feign远程调用实现详解

    目录 1. Feign远程调用 1.1.Feign替代RestTemplate 1.2.自定义配置 1.2.1.配置文件方式 1.2.2.Java代码方式 2.Feign使用优化 3. 最佳实践 3.1.继承方式 3.2.抽取方式 3.3.实现基于抽取的最佳实践 先来看我们以前利用RestTemplate发起远程调用的代码: 存在下面的问题: 代码可读性差,编程体验不统一 参数复杂URL难以维护 1. Feign远程调用 Feign是一个声明式的http客户端,官方地址:https://gith

  • Feign远程调用参数里面内容丢失的解决方案

    目录 Feign远程调用参数里面内容丢失 举个例子 解决方法 Feign远程调用细节--丢失数据 同步调用 异步调用 Feign远程调用参数里面内容丢失 举个例子 服务A提供了如下接口(注意这里的参数url是一个地址): @GetMapping("/getSample") public String getSample(@RequestParam String url){      //此处省略逻辑...... } 服务B需要调用服务A的接口,调用如下: sampleFeignClie

  • 使用Spring Cloud Feign远程调用的方法示例

    在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Apache的Http Client.Netty的异步HTTP Client, Spring的RestTemplate.但是,用起来最方便.最优雅的还是要属Feign了. Feign简介 Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便. 它具有可插拔注释支持

随机推荐