【问题标题】:Feign client support for optional request paramFeign 客户端支持可选请求参数
【发布时间】:2020-04-12 05:54:46
【问题描述】:

Feign 客户端是否支持可选的请求参数?

例如,我有一个端点,但我没有找到使用 feign 客户端实际使 param1 可选的方法。

@GetMapping(path = "endpoint1")
ResponseEntity request(@RequestParam(name = "param1", required = false, defaultValue = "key") String param1){}

【问题讨论】:

    标签: spring-cloud-feign feign


    【解决方案1】:

    您可以使用带有@SpringQueryMap 注释的简单Map<String, String>,然后您可以传递任意数量的可选/强制参数。

    @GetMapping("/task")
    ResponseEntity<List<TaskResponse>> getTasks(@SpringQueryMap Map<String, String> queryParameters);
    

    如果有的话,请务必验证您传递给地图的参数 其中不是可选的。

    类似这样的:

    List<TaskResponse> getTasks(@NotBlank final String mandatoryParam1, final String optionalParam2) {
    
            Map<String, String> parameters = new HashMap<>();
            parameters.put("mandatoryParam1", mandatoryParam1);
            Optional.ofNullable(optionalParam2)
                    .ifPresent(nonNullParam -> parameters.put("optionalParam2", nonNullParam));
    
            return yourFiegnApiClient.getTasks(parameters).getBody();
        }
    

    【讨论】:

      【解决方案2】:

      我通过创建自定义的FeignFormatterRegistrar 设法将 可选 请求参数与 Feign 一起使用。 代码如下:

      package feignformatters;
      
      import org.springframework.cloud.openfeign.FeignFormatterRegistrar;
      import org.springframework.format.FormatterRegistry;
      import org.springframework.stereotype.Component;
      
      import java.util.Optional;
      
      @Component
      public class OptionalFeignFormatterRegistrar implements FeignFormatterRegistrar {
          
          @Override
          public void registerFormatters(FormatterRegistry registry) {
              registry.addConverter(
                  Optional.class, 
                  String.class, 
                  optional -> {
                      if (optional.isPresent())
                          return optional.get().toString();
                      else
                          return "";
                  });
          }
      }
      

      以下客户端开始使用项目中加载的先前组件正常工作:

      @FeignClient("book-service")
      public interface BookServiceClient {
      
          @GetMapping("/books")
          public List<Book> getBooks(
              @RequestParam("page") Optional<Integer> pageNum,
              @RequestParam("size") Optional<Integer> pageSize,
              @RequestParam("reader") Optional<Long> readerId);
      }
      

      【讨论】:

        【解决方案3】:

        由于您使用的是 Spring Cloud Feign,我发现实现可选参数的最简单方法是使用 DTO,并可选地实现构建器模式(Lombok 可以帮助减少冗长)。

        DTO 将使请求中的参数成为可选参数(当为 null 时),而不是方法签名。方法的可选参数应该 - 几乎 - 不可能,但有一些 alternatives can be found here

        构建器模式将使初始化参数成为可选(或强制)details can be found here。该构建器还可用于设置默认值。 Lombok details can be found here。 或者,构建器可以手动构建。 Starting at wikipediaSome example pure Java code.

        代码可能如下所示:

        @GetMapping(path = "/endpoint1") //Not starting with / does not look ok...
        ResponseEntity request(@SpringQueryMap MyDTO);
        
        //MyDTO
        
        import lombok.Builder;
        import lombok.Getter;
        
        @Getter
        @Builder
        public class MyDTO {
        
          private String param1;
          private String param2;
          private String param3;
        }
        
        //when using
        
        request(MyDTO.Builder().build()); //use all defaults
        request(MyDTO.Builder().param1("foo").build()); //param1 set, all other defaults
        request(MyDTO.Builder().param1("foo").param2("bar").build()); //param1 and param2 set
        

        【讨论】:

          猜你喜欢
          • 2018-01-05
          • 1970-01-01
          • 2020-01-08
          • 2019-05-17
          • 1970-01-01
          • 2020-01-14
          • 2018-07-22
          • 1970-01-01
          • 2019-11-12
          相关资源
          最近更新 更多