【问题标题】:Feign client mapping by parameter通过参数Feign客户端映射
【发布时间】:2018-07-22 06:52:40
【问题描述】:

我有一个看起来像这样的假客户端:

@RequestMapping(method = RequestMethod.POST, value = "/breakdowns/utmMedium", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
List<Breakdown> getUtmMediumBreakdowns(
    @RequestBody Record record,
    @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
    @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
    @RequestParam("timezone") String timezone
);


@RequestMapping(method = RequestMethod.POST, value = "/breakdowns/utmCampaign", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
List<Breakdown> getUtmCampaignBreakdowns(
    @RequestBody Record record,
    @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
    @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
    @RequestParam("timezone") String timezone
);


@RequestMapping(method = RequestMethod.POST, value = "/breakdowns/utmSource", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
List<Breakdown> getUtmSourceBreakdowns(
    @RequestBody Record record,
    @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
    @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
    @RequestParam("timezone") String timezone
);

如您所见,除了 API 路径根据参数 utmMediumutmCampaignutmSource 更改之外,这三种方法完全相同,因为在服务器端我们确实对它们进行了不同的处理.

我无法更改服务器,因此无法更改端点以接受此参数作为请求参数或其他内容。 我想知道是否有办法让我仍然参数化这部分路径,所以我只有一个方法而不是三个。

【问题讨论】:

    标签: java rest spring-cloud-feign


    【解决方案1】:

    您可以使用@PathVariable 注释定义附加参数,如下面的utmType

    @RequestMapping(method = RequestMethod.POST, value = "/breakdowns/{utmType}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    List<Breakdown> getUtmCampaignBreakdowns(
        @RequestBody Record record,
        @PathVariable("utmType") String utmType,
        @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
        @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
        @RequestParam("timezone") String timezone
    );
    

    您必须注意的一件事是,您需要指定名称utmType,如带有注释的@PathVariable("utmType")

    【讨论】:

      【解决方案2】:

      如果您想将编译时检查添加到备用 URI,可以将字符串枚举用于 utmType 参数。这假设您使用的是 Spring Open Feign。 Plain Feign 需要备用注释 some starting guidance for that case can be found here.:

      //Slight changes should be introduced in the getUtmCampaignBreakdowns method signature utmType parameter.
      package test;
      
      import java.time.ZonedDateTime;
      import java.util.List;
      import org.springframework.cloud.openfeign.FeignClient;
      import org.springframework.format.annotation.DateTimeFormat;
      import org.springframework.http.MediaType;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestParam;
      
      @FeignClient(name = "utmThing", url = "${feign.client.config.utmThing.url}")
      public interface Test {
        @PostMapping(value = "/breakdowns/{utmType}", consumes = MediaType.APPLICATION_JSON_VALUE)
        List<Breakdown> getUtmCampaignBreakdowns(
            @RequestBody Record record,
            @PathVariable("utmType") UtmTypes utmType, //<-Type changed to Enum
            @RequestParam("since") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime since,
            @RequestParam("until") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime until,
            @RequestParam("timezone") String timezone
        );
      }
      
      
      //An enum should be declared
      package test;
      
      enum UtmTypes {
        UTM_MEDIUM("utmMedium"),
        UTM_CAMPAIGN("utmCampaign"),
        UTM_SOURCE("utmSource");
      
        private final String utmType;
      
        UtmTypes(String utmType) {
              this.utmType = utmType;
        }
      
        //Do not forget to privide a toString() that would map to the URI parameter
        public String toString() {
          return utmType;
        }
      }
      
      //Can be used like so:
      package test;
      
      import java.time.ZonedDateTime;
      import java.util.Arrays;
      import java.util.TimeZone;
      import org.springframework.beans.factory.annotation.Autowired;
      
      public class User {
      
        @Autowired
        void User(Test test) {
          test.getUtmCampaignBreakdowns(new Record(), UtmTypes.UTM_CAMPAIGN, ZonedDateTime.now(),
              ZonedDateTime.now().plusDays(1),
              Arrays.stream(TimeZone.getAvailableIDs())
                  .filter(zoneName -> zoneName.contains("Montevideo")).findFirst()
                  .orElse(TimeZone.getAvailableIDs()[0]));
        }
      }
      
      //Assuming simple Record and Breakdown implementations
      package test;
      
      public class Record {
        private String someField;
      
        public void setSomeField(String someField) {
          this.someField = someField;
        }
      
        public String getSomeField() {
          return this.someField;
        }
      }
      
      package test;
      
      public class Record {
        private String someField;
      
        Record() {
          this.someField = "defaultValue";
        }
      
        public void setSomeField(String someField) {
          this.someField = someField;
        }
      
        public String getSomeField() {
          return this.someField;
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-14
        • 2018-01-05
        • 1970-01-01
        • 2016-03-09
        • 2020-01-27
        • 2020-04-12
        • 2019-11-04
        • 1970-01-01
        相关资源
        最近更新 更多