spring cloud openFeign传参的一些总结(有错,待更新)

1. 客户端注解问题

spring cloud openFeign 的客户端 ,即调用方,在启动类中一定要加上 @EnableFeignClients 这个注解,service接口上的@service注解和@FeignClient("微服务名") 都写在一起,如果不加,会报@service 没初始化这个service接口。

2. openFeign的http连接优化选择

openFeign 默认用的是jdk的httpUrlConnection,没有连接池,http连接没复用,性能不太好,我们可以集成 httpClient 或者 okHttp,二选一,不用指定版本号,他会自动根据你的spring cloud 的openfeign 解析出来。

 
         io.github.openfeign
         feign-okhttp
 

或者


            io.github.openfeign
            feign-httpclient


3.关于记录feign调用日志,可以配置如下:

@Configuration
public class FeignLogConfig {

    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.FULL;
    }
}

4. 关于微服务传参

公共bean
@Data
public class Trans implements Serializable {

    private Integer id;

    private Date date;

    private LocalDateTime ldt;

    private String name;

    private Double money;

    private InnerTrans innerTrans;
}

@Data
public class InnerTrans implements Serializable {

    private String code;

    private Integer age;
}
调用方
@Service
@FeignClient("provider")
public interface TestService {
    @GetMapping("/test/getWithInt")
    Integer getWithInt(@RequestParam("i") Integer i);

    @GetMapping("/test/getWithDouble")
    Double getWithDouble(@RequestParam("d") Double d);

    @GetMapping("/test/getWithString")
    String getWithString(@RequestParam("str") String s);

    @GetMapping("/test/getWithPvInt/{id}")
    Integer getWithPvInt(@PathVariable("id") Integer id);

    @GetMapping("/test/getWithPvStr/{code}")
    String getWithPvStr(@PathVariable("code") String code);

    @GetMapping("/test/getWithMap")
    //Map getWithMap(@RequestParam("m") Map m);
    Map getWithMap(@SpringQueryMap Map m);

    //复杂类型接收失败(bean 嵌 bean)
    @GetMapping("/test/getWithBean")
    Trans getWithBean(@SpringQueryMap Trans t);

    @GetMapping("/test/getWithSimpleBean")
    InnerTrans getWithSimpleBean(@SpringQueryMap InnerTrans t);

    //-------------------------------**- get  end -**-------------------------------------

    //---------------------------------  post  start -------------------------------------
    @PostMapping("/test/postWithInt")
    Integer postWithInt(@RequestParam("i") Integer i);

    @PostMapping("/test/postWithDouble")
    Double postWithDouble(@RequestParam("d") Double d);

    @PostMapping("/test/postWithString")
    String postWithString(@RequestParam("s") String s);

    @PostMapping("/test/postWithMap")
    Map postWithMap(Map m);

    @PostMapping("/test/postWithList")
    List postWithList(List l);

    @PostMapping("/test/postWithBean")
    Trans postWithBean(Trans t);

    @PostMapping("/test/postWithSimpleBean")
    InnerTrans postWithSimpleBean(InnerTrans t);

}
被调用方:
@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/getWithInt")
    public Integer getWithInt(@RequestParam Integer i) {
        return i + 10;
    }

    @GetMapping("/getWithDouble")
    public Double getWithDouble(@RequestParam Double d) {
        return d + 10;
    }

    @GetMapping("/getWithString")
    public String getWithString(@RequestParam String str) {
        return "provider-a test getWithString : " + str + " return";
    }

    @GetMapping("/getWithPvInt/{id}")
    public String getWithPvInt(@PathVariable(name = "id") Integer id) {
        return "provider-a test getWithPvInt : " + id + " return";
    }

    @GetMapping("/getWithPvStr/{code}")
    public String getWithPvStr(@PathVariable(name = "code") String code) {
        return "provider-a test getWithPvStr : " + code + " return";
    }

    @GetMapping("/getWithMap")
    public Map getWithMap(@RequestParam Map m) {
        System.out.println(m);
        return m;
    }

    @GetMapping("/getWithBean")
    public Trans getWithBean(Trans t) {
        System.out.println(t.toString());
        t.setName("provider-a test getBean return");
        return t;
    }

    @GetMapping("/getWithSimpleBean")
    public InnerTrans getWithSimpleBean(InnerTrans t) {
        System.out.println(t.toString());
        t.setCode("provider-a test getBean return");
        return t;
    }

    @GetMapping("/getString")
    public String getString() {
        return "provider-a test getString";
    }

    @GetMapping("/getBean")
    public Trans getBean() {
        Trans trans = new Trans();
        trans.setDate(new Date());
        trans.setLdt(LocalDateTime.now().minusYears(1L));
        trans.setId(99);
        trans.setMoney(99.99);
        trans.setName("provider-a test getBean");
        InnerTrans innerTrans = new InnerTrans();
        innerTrans.setAge(88);
        innerTrans.setCode("inner");
        trans.setInnerTrans(innerTrans);
        return trans;
    }


    //----------------  post -----------------

    @PostMapping("/postWithInt")
    public Integer postWithInt(@RequestParam Integer i){
        return i + 20;
    }

    @PostMapping("/postWithDouble")
    public Double postWithDouble(@RequestParam Double d){
        return d + 4;
    }

    @PostMapping("/postWithString")
    public String postWithString(@RequestParam String s){
        return "test postWithString : provider-a receive " + s + " and return";
    }

    @PostMapping("/postWithMap")
    public Map postWithMap(@RequestBody Map m){
        System.out.println(m);
        return m;
    }

    @PostMapping("/postWithList")
    public List postWithList(@RequestBody List l){
        System.out.println(Arrays.toString(l.toArray()));
        return l;
    }

    @PostMapping("/postWithBean")
    public Trans postWithBean(@RequestBody Trans t){
        System.out.println(t.toString());
        return t;
    }

    @PostMapping("/postWithSimpleBean")
    public InnerTrans postWithSimpleBean(@RequestBody InnerTrans t){
        System.out.println(t.toString());
        return t;
    }

经过测试,得到以下结论:

对于GET
  • 参数是基本的类型(integer、string这些),调用方 必须加上@RequestParam,而且还要在@RequestParam那加上被 调用方 端参数的别名,如@RequestParam("xxx") ,@PathVariable 依然是如此,否则应用也报错启动不了,而 被调用方 则可加可不加,为保持一致,还是加上好点。

  • 参数是map,调用方 可以使用@RequestParam 或 @SpringQueryMap,被调用方则用 @RequestParam,必须用,如springmvc那样,不加的话直接访问 被调用方 也是报错的。

  • 参数是bean,复合的bean会有问题(即bean里面有别的自定义bean参数),简单类型参数的bean就没问题。因为参数都拼接在后面,如
    http://provider/test/getWithBean?date=2021-10-22 23:14:04&money=99.99&name=consumer-a test getWithBean&innerTrans=InnerTrans(code=inner, age=88, favor=null, time=2019-10-22T23:14:04.828, date=Fri Oct 22 23:14:04 CST 2021)&id=99&ldt=2020-10-22 23:14:04,会报错。

错误如下:

2021-10-22 11:51:19.131 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] ---> GET http://provider/test/getWithBean?date=Fri%20Oct%2022%2011%3A51%3A19%20CST%202021&money=99.99&name=consumer-a%20test%20getWithBean&innerTrans=InnerTrans%28code%3Dinner%2C%20age%3D88%29&id=99&ldt=2020-10-22T11%3A51%3A19.128 HTTP/1.1
2021-10-22 11:51:19.131 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] ---> END HTTP (0-byte body)
2021-10-22 11:51:19.142 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] <--- HTTP/1.1 400 (10ms)
2021-10-22 11:51:19.142 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] connection: close
2021-10-22 11:51:19.142 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] content-type: application/json
2021-10-22 11:51:19.142 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] date: Fri, 22 Oct 2021 03:51:19 GMT
2021-10-22 11:51:19.142 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] transfer-encoding: chunked
2021-10-22 11:51:19.143 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] 
2021-10-22 11:51:19.143 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] {"timestamp":"2021-10-22 11:51:19","status":400,"error":"Bad Request","message":"","path":"/test/getWithBean"}
2021-10-22 11:51:19.143 DEBUG 11640 --- [nio-8000-exec-8] com.orion.service.TestService            : [TestService#getWithBean] <--- END HTTP (110-byte body)
2021-10-22 11:51:19.145 ERROR 11640 --- [nio-8000-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.FeignException$BadRequest: [400] during [GET] to [http://provider/test/getWithBean?date=Fri%20Oct%2022%2011%3A51%3A19%20CST%202021&money=99.99&name=consumer-a%20test%20getWithBean&innerTrans=InnerTrans%28code%3Dinner%2C%20age%3D88%29&id=99&ldt=2020-10-22T11%3A51%3A19.128] [TestService#getWithBean(Trans)]: [{"timestamp":"2021-10-22 11:51:19","status":400,"error":"Bad Request","message":"","path":"/test/getWithBean"}]] with root cause

feign.FeignException$BadRequest: [400] during [GET] to [http://provider/test/getWithBean?date=Fri%20Oct%2022%2011%3A51%3A19%20CST%202021&money=99.99&name=consumer-a%20test%20getWithBean&innerTrans=InnerTrans%28code%3Dinner%2C%20age%3D88%29&id=99&ldt=2020-10-22T11%3A51%3A19.128] [TestService#getWithBean(Trans)]: [{"timestamp":"2021-10-22 11:51:19","status":400,"error":"Bad Request","message":"","path":"/test/getWithBean"}]
    at feign.FeignException.clientErrorStatus(FeignException.java:195) ~[feign-core-10.10.1.jar:na]
    at feign.FeignException.errorStatus(FeignException.java:177) ~[feign-core-10.10.1.jar:na]
    at feign.FeignException.errorStatus(FeignException.java:169) ~[feign-core-10.10.1.jar:na]
    at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:92) ~[feign-core-10.10.1.jar:na]
    at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:96) ~[feign-core-10.10.1.jar:na]
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138) ~[feign-core-10.10.1.jar:na]
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89) ~[feign-core-10.10.1.jar:na]
    at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100) ~[feign-core-10.10.1.jar:na]
    at com.sun.proxy.$Proxy111.getWithBean(Unknown Source) ~[na:na]
    at com.orion.controller.TestController.getWithBean(TestController.java:69) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93) ~[spring-boot-actuator-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.37.jar:9.0.37]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]

值得注意的是,多参数不建议用map,可读性差,如果少的话,可以用分开用多个参数来传,各个参数用 @RequestParam("xxx")注解就行,如果太多的话,建议封装成一个bean,使用@SpringQueryMap注解。

使用get方式发送,就是在url后面通过 & 把所有参数拼接起来一起传输,这个可以打开日志来观察即可。前提得配置,结论3 处。

对于post

  • 参数是基本的类型(integer、string这些),调用方 必须加上@RequestParam,而且还要在@RequestParam那加上被 调用方 端参数的别名,如@RequestParam("xxx") ,@PathVariable 依然是如此,否则应用也报错启动不了,而 被调用方 则可加可不加,为保持一致,还是加上好点。

  • 参数是map,list,bean嵌bean,简单参数bean,调用方 不需要加注解,被调用方则必须用 @RequestBody来接收,如果是list的话,必须指定list的泛型类型,不然报错。

注意:

get方法已经说了是在url后面拼接的,所以如果get的方式传@SpringQueryMap 的bean参数里面,如果有LocalDatetime、Date这类的属性,它们默认是用toString方法,所以Date是话使用cst这种时区,LocalDatetime有T这种时区在里面,不符合我们日常使用的yyyy-MM-dd HH:mm:ss 这种格式,必须自定义自己的QueryMapEncoder,其实现QueryMapEncoder接口,并配置上; 自定义feignBuilder会导致hystrix失效。

Post是不会有影响的

@Configuration
public class CustomFeignConfig {


    @Bean
    public Feign.Builder feignBuilder() {
        return Feign.builder()
                .queryMapEncoder(new QueryMapImproveEncoder())
                .retryer(Retryer.NEVER_RETRY);
    }

}
public class QueryMapImproveEncoder implements QueryMapEncoder {
    private final Map, ObjectParamMetadata> classToMetadata =
            new HashMap<>();
    private final DateTimeFormatter dtf = DateTimeFormatter.ofPattern(JacksonConfig.PATTERN);



    @Override
    public Map encode(Object object) throws EncodeException {
        try {
            ObjectParamMetadata metadata = getMetadata(object.getClass());
            Map propertyNameToValue = new HashMap<>(16);
            for (PropertyDescriptor pd : metadata.objectProperties) {
                Method method = pd.getReadMethod();

                Object value = method.invoke(object);
                if (value != null && value != object) {
                    Param alias = method.getAnnotation(Param.class);
                    String name = alias != null ? alias.value() : pd.getName();


                    String handleClazzName = method.getReturnType().getName();
                    switch (handleClazzName){
                        case "java.time.LocalDateTime" :
                            propertyNameToValue.put(name, dtf.format((LocalDateTime) value));
                            break;
                        case "java.util.Date" :
                            LocalDateTime ldt = LocalDateTime.ofInstant(((Date)value).toInstant(), ZoneId.systemDefault());
                            propertyNameToValue.put(name, dtf.format(ldt));
                            break;
                        default:
                            propertyNameToValue.put(name, value);
                            break;
                    }
                }
            }
            return propertyNameToValue;
        } catch (IllegalAccessException | IntrospectionException | InvocationTargetException e) {
            throw new EncodeException("Failure encoding object into query map", e);
        }
    }

    private ObjectParamMetadata getMetadata(Class objectType) throws IntrospectionException {
        ObjectParamMetadata metadata = classToMetadata.get(objectType);
        if (metadata == null) {
            metadata = ObjectParamMetadata.parseObjectType(objectType);
            classToMetadata.put(objectType, metadata);
        }
        return metadata;
    }

    private static class ObjectParamMetadata {

        private final List objectProperties;

        private ObjectParamMetadata(List objectProperties) {
            this.objectProperties = Collections.unmodifiableList(objectProperties);
        }

        private static ObjectParamMetadata parseObjectType(Class type)
                throws IntrospectionException {
            List properties = new ArrayList<>();

            for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) {
                boolean isGetterMethod = pd.getReadMethod() != null && !"class".equals(pd.getName());
                if (isGetterMethod) {
                    properties.add(pd);
                }
            }

            return new ObjectParamMetadata(properties);
        }
    }
}

参考:
SpringCloud中利用FeignClient发送请求时参数的传递和返回值

feign请求返回值反序列LocalDateTime异常记录

openfeign get请求参数dto包含LocalDateTime的处理

你可能感兴趣的:(spring cloud openFeign传参的一些总结(有错,待更新))