通过参数

时间:2018-02-12 06:37:22

标签: java rest spring-cloud-feign

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

@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而变化,如服务器中所示我们确实以不同的方式对待它们。

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

2 个答案:

答案 0 :(得分:0)

您可以使用@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")

答案 1 :(得分:0)

如果要将编译时间检查添加到备用URI,则可以将String Enum用作utmType参数。假设您正在使用Spring Open 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;
  }
}