带路径变量的多个请求映射值

时间:2015-07-28 05:24:54

标签: spring-mvc

@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) {
        // ********

}

对于一个网址,我传递的是路径变量而另一个我不是。但我希望这两个网址都能使用相同的API。我怎样才能实现它?

4 个答案:

答案 0 :(得分:7)

现在,您可以通过支持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
) {
    // ********
}

答案 1 :(得分:5)

我们无法optional path variables,您可以使用两种控制器方法来调用相同的服务。

第一种方法

@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){}

我们可以使用<{1}},

@RequestParam

表示可选@RequestParam(value="somevalue",required=false)而不是params

答案 2 :(得分: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

答案 3 :(得分: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的任何使用。作为字段或字段的类型参数。可选的目的是为库方法返回类型提供一种有限的机制,该机制需要一种明确的方式来表示“无结果”。如果该类需要是可序列化的,则使用类型为java.util.Optional的字段也是有问题的,而java.util.Optional不是。 ''

说实话,我是这个行业的新手,我不太清楚IDE告诉我什么。如果有更多专业知识的人可以帮助澄清该信息,那就太好了。