• Method has too many Body parameters openfeign


    feign 调用问题,最新版本的feign和旧版本的稍微有一些不一样,具体如下(eureka 作为服务发现与注册 )

     依赖:

        compile('io.github.openfeign:feign-java8:9.6.0')
        compile('org.springframework.cloud:spring-cloud-openfeign-core')
        compile('org.springframework.cloud:spring-cloud-starter-openfeign')

    feign client 接口,这里统一使用feign的@Param进行注解

    import org.springframework.cloud.openfeign.FeignClient;
    
    import feign.Headers;
    import feign.Param;
    import feign.RequestLine;
    
    @FeignClient(value = "xxx-service")
    public interface xxxServiceClient {
    
        @RequestLine("POST /xxx/save")
        String saveLog(@Param(value = "data") String data);
    
    }

     对应xxx-service的具体rest,这里使用spring的@RequestParam 等进行参数的接收

        @RequestMapping(value = "/xxx/save", method = { RequestMethod.POST })
        public String saveLog(@RequestParam(value = "data", required = false) String data) String status) {
         // TODO
       return "xxx"; }

    feign 基本请求格式

     ...
     @RequestLine("POST /servers")
     void post(@Param("serverId") String serverId, @Param("count") int count);
     ...
    
     @RequestLine("GET /servers/{serverId}?count={count}")
     void get(@Param("serverId") String serverId, @Param("count") int count);
    ...

    对于post多参数问题,需要使用form的提交格式(某些字段是xml、json之类的参数),普通的提交,head里是

    "Content-Type: application/json; charset=UTF-8", "Accept: application/json"

    多参数需要使用

    "Content-Type: application/x-www-form-urlencoded; charset=UTF-8", "Accept: application/json"

    而第二种格式需要feign-form的支持

    依赖:

        compile('io.github.openfeign.form:feign-form:3.3.0')
        compile('io.github.openfeign.form:feign-form-spring:3.3.0')
        compile('io.github.openfeign:feign-java8:9.6.0')
        compile('org.springframework.cloud:spring-cloud-openfeign-core')
        compile('org.springframework.cloud:spring-cloud-starter-openfeign')

    feign:

    import org.springframework.cloud.openfeign.FeignClient;
    
    import feign.Headers;
    import feign.Param;
    import feign.RequestLine;
    
    @FeignClient(value = "whale-service", configuration = EurekaConfiguration.class)
    public interface xxxServiceClient {
    
        @Headers({ "Content-Type: application/x-www-form-urlencoded; charset=UTF-8", "Accept: application/json" })
        @RequestLine("POST /deviceActionLog/save")
        String saveLog(@Param(value = "data") String data);
    
    }
    import org.springframework.cloud.openfeign.FeignClient;
    import feign.Headers;
    import feign.Param;
    import feign.RequestLine;
    
    @FeignClient(value = "xxx-service", configuration = EurekaConfiguration.class)
    public interface xxxClient {
    
        @Headers({ "Content-Type: application/json; charset=UTF-8", "Accept: application/json" })
        @RequestLine("GET /xxx/obj?id={id}")
        String getById(@Param(value = "id") String deviceId);
    
    }

    注:若实现xxxclient的接口,则feign首先调用远程服务,远程服务不可用时,降级调用本地实现类

    EurekaConfiguration:

    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.ObjectFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
    import org.springframework.cloud.openfeign.support.SpringDecoder;
    import org.springframework.cloud.openfeign.support.SpringEncoder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.http.converter.HttpMessageConverter;
    
    import feign.Contract;
    import feign.auth.BasicAuthRequestInterceptor;
    import feign.codec.Decoder;
    import feign.codec.Encoder;
    import feign.form.FormEncoder;
    import feign.form.spring.converter.SpringManyMultipartFilesReader;
    
    @Configuration
    public class EurekaConfiguration {
    
        @Bean
        public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
            return new BasicAuthRequestInterceptor("admin", "admin");//eureka 获取注册服务使用的账号密码
        }
    
        // 使用Feign自己的注解,使用springmvc的注解就会报错
        @Bean
        public Contract feignContract() {
            return new feign.Contract.Default();
        }
    
        @Autowired
        private ObjectFactory<HttpMessageConverters> messageConverters;
    
        @Bean // spring使用的编码器
        @Primary
        Encoder feignEncoder() {
            // return new SpringEncoder(this.messageConverters);
            return new FormEncoder(new SpringEncoder(this.messageConverters));
        }
    
        @Bean // download使用的解码器
        @Qualifier("download")
        public Decoder feignDecoder() {
            final List<HttpMessageConverter<?>> springConverters = messageConverters.getObject().getConverters();
            final List<HttpMessageConverter<?>> decoderConverters = new ArrayList<HttpMessageConverter<?>>(
                    springConverters.size() + 1);
    
            decoderConverters.addAll(springConverters);
            decoderConverters.add(new SpringManyMultipartFilesReader(4096));
            final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(decoderConverters);
    
            return new SpringDecoder(new ObjectFactory<HttpMessageConverters>() {
                @Override
                public HttpMessageConverters getObject() {
                    return httpMessageConverters;
                }
            });
        }
    }

    参考:

    https://github.com/OpenFeign/feign

    http://sparkgis.com/java/2018/02/feign-method-has-too-many-body-parameters-%E5%8E%9F-feign-method-has-too-many-body-parameters-xixingzhe/

    https://yezhwi.github.io/springcloud/2017/12/07/%E5%AE%9E%E8%B7%B5bug%E6%80%BB%E7%BB%93-Feign/

    https://blog.csdn.net/liuchuanhong1/article/details/54728681

    编码参考:

    https://github.com/OpenFeign/feign-form

  • 相关阅读:
    剑指offer-重建二叉树
    Java集合学习-总体框架
    leetcode-6-ZigZag Conversion
    海拔高度与大气密度的关系函数
    C++ 获取文件夹下的所有文件名
    01-复杂度1. 最大子列和问题
    00-自测5. Shuffling Machine
    00-自测4. Have Fun with Numbers
    00-自测3. 数组元素循环右移问题
    00-自测2. 素数对猜想
  • 原文地址:https://www.cnblogs.com/lossingdawn/p/9071223.html
Copyright © 2020-2023  润新知