具有路径变量的多个RequestMapping值

13
@RequestMapping(value = {"/abcd", "/employees/{value}/{id}"})
public String getEmployees(
      @PathVariable(value = "value") String val, 
      @PathVariable(value = "id") String id,
      @RequestParam(value = "param", required = false) String value) {
        // ********

}

我有一个URL,其中一个包含路径变量而另一个不包含。但是我希望这两个URL都能命中同一个API。我该如何实现?

4个回答

8

现在你可以通过Java 8的Optional支持来获得可选路径变量。至少需要Spring版本4.x。

@RequestMapping({"/abcd", "/employees/{value}/{id}"})
public String getEmployees(
    @PathVariable("value") Optional<String> val, 
    @PathVariable("id") Optional<String> id,
    @RequestParam("param") Optional<String> value
) {
    // ********
}

注意:这不适用于可选原始类型(OptionalInt等)。

5

我找到了一种方法,可以不使用多种方法来实现这个。

首先创建一个简单的类来保存路径变量:

public class EmployeesRequest {
  private String value;
  private String id;

  public String getValue() {
    return this.value;
  }

  public void setValue(String value) {
    this.value = value;
  }

  public String getId() {
    return this.id;
  }

  public void setId(String id) {
    this.id = id;
  }
}

然后按照以下方式定义您的控制器方法:
@RequestMapping(value={
  "/abcd",
  "/employees/{value}/{id}"
})
public String getEmployees(@RequestParam(value="param", required=false) String param,
                           EmployeesRequest request) {
  if (request.getValue() != null) {
    // do something
  } else {
    // do something else
  }
}

Spring会自动映射任何可用的路径变量到EmployeesRequest类。对于任何请求参数,Spring也会这样做,因此您可以通过将请求参数添加到EmployeesRequest来进一步简化:

public class EmployeesRequest {
  private String value;
  private String id;
  private String param;

  public String getValue() {
    return this.value;
  }

  public void setValue(String value) {
    this.value = value;
  }

  public String getId() {
    return this.id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getParam() {
    return this.param;
  }

  public void setParam(String param) {
    this.param = param;
  }
}

最后,最终步骤是:
@RequestMapping(value={
  "/abcd",
  "/employees/{value}/{id}"
})
public String getEmployees(EmployeesRequest request) {
  if (request.getValue() != null) {
    // do something
  } else {
    // do something else
  }
}

这种解决方案的另一个好处是现在您可以支持变量或请求参数。这意味着所有这些都是有效的:
  • /abcd
  • /abcd?param=123
  • /abcd?value=123&id=456&param=789
  • /employees/123/456
  • /employees/123/456?param=123

5
我们不能使用可选的路径变量,但是可以有两个控制器方法调用同一个服务。
第一个方法:
@RequestMapping("/abcd")
public String getEmployees(@RequestParam(value="param", required=false)String value){}

第二种方法

@RequestMapping("/employees/{value}/{id}")
public String getEmployees(@PathVariable(value="value") String val, @PathVariable(value="id") String id, @RequestParam(value="param", required=false) String value){}

对于@RequestParam,我们可以使用以下方式:

@RequestParam(value="somevalue",required=false)

用于可选的params而不是pathVariable


0

我曾经遇到过类似的问题,后来我找到了这个解决方案:

@GetMapping(value = {"/clients/page", "/clients/page/{page}"})
public Page<Client> index(@PathVariable Optional<Integer> page) {
   PageRequest pageRequest = page.map(integer -> PageRequest.of(integer, 4))
   .orElseGet(() -> PageRequest.of(0, 4));
      return clientService.showAll(pageRequest);
}

Intellij帮助我获得了这种紧凑的结果。虽然Intellij抛出了这个消息:

''报告任何使用java.util.Optional、java.util.OptionalDouble、java.util.OptionalInt、java.util.OptionalLong或com.google.common.base.Optional作为字段或参数类型的情况。Optional旨在为库方法返回类型提供有限的机制,在需要清晰地表示“无结果”的情况下。如果类需要是Serializable,使用类型为java.util.Optional的字段也会存在问题,因为java.util.Optional不是Serializable。''

老实说,我是新手,我不太明白IDE告诉我的内容。如果有更多经验的人能够帮助澄清这个消息,那就太好了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接