Java 具有路径变量的多个请求映射值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31667945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:23:32  来源:igfitidea点击:

Multiple requestmapping value with path variables

javaspring-mvc

提问by Sharique

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

}

For one url I am passing the path variable and for one I am not. But I want both the url to hit the same API. How can I achieve it?

对于一个 url,我正在传递路径变量,而对于一个我没有传递。但我希望两个 url 都访问相同的 API。我怎样才能实现它?

回答by Ankur Singhal

We can't have optional path variables, you can have two controller methods which can call the same service.

我们不能有optional path variables,你可以有两个可以调用同一个服务的控制器方法。

First Method

第一种方法

@RequestMapping("/abcd")
public String getEmployees(@RequestParam(value="param", required=false)String value){}

Second Method

第二种方法

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

For @RequestParamwe can use,

因为@RequestParam我们可以使用,

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

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

for optional paramsrather than a pathVariable

对于可选params而不是一个pathVariable

回答by Kyle

Just found a way to do this without using multiple methods.

刚刚找到了一种无需使用多种方法即可完成此操作的方法。

First create a simple class to hold the path variables:

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

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;
  }
}

Then define your controller method like this:

然后像这样定义你的控制器方法:

@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 will automatically map any path variables available to the EmployeesRequestclass. Spring will also do this for any request parameters so you can simplify things further by adding the request parameter to EmployeesRequest:

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;
  }
}

And then finally:

然后最后:

@RequestMapping(value={
  "/abcd",
  "/employees/{value}/{id}"
})
public String getEmployees(EmployeesRequest request) {
  if (request.getValue() != null) {
    // do something
  } else {
    // do something else
  }
}

An added benefit of this solution is that now you can support both variables or request parameters. Meaning all of these would be valid:

此解决方案的另一个好处是现在您可以同时支持变量或请求参数。这意味着所有这些都是有效的:

  • /abcd
  • /abcd?param=123
  • /abcd?value=123&id=456&param=789
  • /employees/123/456
  • /employees/123/456?param=123
  • /abcd
  • /abcd?param=123
  • /abcd?value=123&id=456&param=789
  • /employees/123/456
  • /employees/123/456?param=123

回答by OrangeDog

You can now have optional path variables via support for Java 8 Optional. At least Spring version 4.x will be required.

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

N.B. this doesn't work with the optional primitives (OptionalInt, etc.).

注意这不适用于可选的原语(OptionalInt等)。

回答by catra

I had a similar problem and I found this solution:

我有一个类似的问题,我找到了这个解决方案:

@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 helped me to get this kind of compact result. Although Intellij throw this message:

Intellij 帮助我获得了这种紧凑的结果。尽管 Intellij 抛出此消息:

''Reports any uses of java.util.Optional, java.util.OptionalDouble, java.util.OptionalInt, java.util.OptionalLong or com.google.common.base.Optional as the type for a field or a parameter. Optional was designed to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result". Using a field with type java.util.Optional is also problematic if the class needs to be Serializable, which java.util.Optional is not. ''

''报告任何使用 java.util.Optional、java.util.OptionalDouble、java.util.OptionalInt、java.util.OptionalLong 或 com.google.common.base.Optional 作为字段或参数类型的情况。Optional 旨在为库方法返回类型提供一种有限的机制,其中需要一种明确的方式来表示“无结果”。如果类需要可序列化,而 java.util.Optional 不是,则使用类型为 java.util.Optional 的字段也会有问题。''

To be honest, I'm new in this business and I don't understand clearly what the IDE is telling me. If someone with more expertise could help to clarify that message would be great.

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