1. Overview
1.概述
In this quick tutorial, we’ll explore Spring’s @PathVariable annotation.
在这个快速教程中,我们将探索Spring的@PathVariable注解。
Simply put, the @PathVariable annotation can be used to handle template variables in the request URI mapping, and set them as method parameters.
简单地说,@PathVariable注解可用于处理请求URI映射中的模板变量,并将其设置为方法参数。
Let’s see how to use @PathVariable and its various attributes.
让我们看看如何使用@PathVariable和它的各种属性。
2. A Simple Mapping
2.一个简单的映射
A simple use case of the @PathVariable annotation would be an endpoint that identifies an entity with a primary key:
@PathVariable注解的一个简单用例是一个端点,它用一个主键来标识一个实体。
@GetMapping("/api/employees/{id}")
@ResponseBody
public String getEmployeesById(@PathVariable String id) {
return "ID: " + id;
}
In this example, we use the @PathVariable annotation to extract the templated part of the URI, represented by the variable {id}.
在这个例子中,我们使用@PathVariable注解来提取URI的模板部分,由变量{id}代表。
A simple GET request to /api/employees/{id} will invoke getEmployeesById with the extracted id value:
一个简单的GET请求到/api/employees/{id}。将调用getEmployeesById与提取的id值。
http://localhost:8080/api/employees/111
----
ID: 111
Now let’s further explore this annotation, and have a look at its attributes.
现在让我们进一步探讨这个注释,看看它的属性。
3. Specifying the Path Variable Name
3.指定路径变量名称
In the previous example, we skipped defining the name of the template path variable since the names for the method parameter and the path variable were the same.
在前面的例子中,我们跳过了定义模板路径变量的名称,因为方法参数和路径变量的名称是一样的。
However, if the path variable name is different, we can specify it in the argument of the @PathVariable annotation:
然而,如果路径变量名称不同,我们可以在@PathVariable注释的参数中指定它。
@GetMapping("/api/employeeswithvariable/{id}")
@ResponseBody
public String getEmployeesByIdWithVariableName(@PathVariable("id") String employeeId) {
return "ID: " + employeeId;
}
http://localhost:8080/api/employeeswithvariable/1
----
ID: 1
We can also define the path variable name as @PathVariable(value=”id”) instead of PathVariable(“id”) for clarity.
我们也可以将路径变量名称定义为@PathVariable(value=”id”),而不是PathVariable(“id”),这样更清晰。
4. Multiple Path Variables in a Single Request
4.一个请求中的多个路径变量
Depending on the use case, we can have more than one path variable in our request URI for a controller method, which also has multiple method parameters:
根据不同的使用情况,我们可以在控制器方法的请求URI中设置一个以上的路径变量,这也有多个方法参数。
@GetMapping("/api/employees/{id}/{name}")
@ResponseBody
public String getEmployeesByIdAndName(@PathVariable String id, @PathVariable String name) {
return "ID: " + id + ", name: " + name;
}
http://localhost:8080/api/employees/1/bar
----
ID: 1, name: bar
We can also handle more than one @PathVariable parameter using a method parameter of type java.util.Map<String, String>:
我们也可以使用@PathVariable类型的方法参数来处理一个以上的java.util.Map<String, String>:
@GetMapping("/api/employeeswithmapvariable/{id}/{name}")
@ResponseBody
public String getEmployeesByIdAndNameWithMapVariable(@PathVariable Map<String, String> pathVarsMap) {
String id = pathVarsMap.get("id");
String name = pathVarsMap.get("name");
if (id != null && name != null) {
return "ID: " + id + ", name: " + name;
} else {
return "Missing Parameters";
}
}
http://localhost:8080/api/employees/1/bar
----
ID: 1, name: bar
There is, however, a small catch while handling multiple @PathVariable parameters when the path variable string contains a dot(.) character. We’ve discussed those corner cases in detail here.
然而,在处理多个@PathVariable参数时,当路径变量字符串包含一个点(.)字符时,有一个小问题。我们已经在这里详细讨论了这些角落的情况。
5. Optional Path Variables
5.可选的路径变量
In Spring, method parameters annotated with @PathVariable are required by default:
在Spring中,用@PathVariable注解的方法参数是默认需要的:。
@GetMapping(value = { "/api/employeeswithrequired", "/api/employeeswithrequired/{id}" })
@ResponseBody
public String getEmployeesByIdWithRequired(@PathVariable String id) {
return "ID: " + id;
}
Given how it looks, the above controller should handle both /api/employeeswithrequired and /api/employeeswithrequired/1 request paths. However, since method parameters annotated by @PathVariables are mandatory by default, it doesn’t handle the requests sent to the /api/employeeswithrequired path:
鉴于它的外观,上述控制器应该处理/api/employeeswithrequired和/api/employeeswithrequired/1请求路径。然而,由于由@PathVariables注释的方法参数在默认情况下是强制性的,它不会处理发送到/api/employeeswithrequired路径的请求。
http://localhost:8080/api/employeeswithrequired ---- {"timestamp":"2020-07-08T02:20:07.349+00:00","status":404,"error":"Not Found","message":"","path":"/api/employeeswithrequired"}
http://localhost:8080/api/employeeswithrequired/1 ---- ID: 111
We can handle this in two different ways.
我们可以用两种不同的方式来处理这个问题。
5.1. Setting @PathVariable as Not Required
5.1.将@PathVariable设置为非必填项
We can set the required property of @PathVariable to false to make it optional. Thus, modifying our previous example, we can now handle the URI versions with and without the path variable:
我们可以将@PathVariable的required属性设置为false,使其成为可选项。因此,修改我们之前的例子,我们现在可以处理有和无路径变量的URI版本。
@GetMapping(value = { "/api/employeeswithrequiredfalse", "/api/employeeswithrequiredfalse/{id}" })
@ResponseBody
public String getEmployeesByIdWithRequiredFalse(@PathVariable(required = false) String id) {
if (id != null) {
return "ID: " + id;
} else {
return "ID missing";
}
}
http://localhost:8080/api/employeeswithrequiredfalse
----
ID missing
5.2. Using java.util.Optional
5.2.使用java.util.Optional
Since the introduction of Spring 4.1, we can also use java.util.Optional<T> (available in Java 8+) to handle a non-mandatory path variable:
自从引入Spring 4.1后,我们也可以使用java.util.Optional<T>(在Java 8+中可用)来处理一个非强制性的路径变量。
@GetMapping(value = { "/api/employeeswithoptional", "/api/employeeswithoptional/{id}" })
@ResponseBody
public String getEmployeesByIdWithOptional(@PathVariable Optional<String> id) {
if (id.isPresent()) {
return "ID: " + id.get();
} else {
return "ID missing";
}
}
Now if we don’t specify the path variable id in the request, we get the default response:
现在,如果我们不在请求中指定路径变量id,我们会得到默认的响应。
http://localhost:8080/api/employeeswithoptional
----
ID missing
5.3. Using a Method Parameter of Type Map<String, String>
5.3.使用Map<String, String>类型的方法参数
As shown earlier, we can use a single method parameter of type java.util.Map to handle all the path variables in the request URI. We can also use this strategy to handle the optional path variables case:
如前所示,我们可以使用一个java.util.Map类型的单一方法参数来处理请求URI中的所有路径变量。我们还可以使用这种策略来处理可选路径变量的情况:。
@GetMapping(value = { "/api/employeeswithmap/{id}", "/api/employeeswithmap" })
@ResponseBody
public String getEmployeesByIdWithMap(@PathVariable Map<String, String> pathVarsMap) {
String id = pathVarsMap.get("id");
if (id != null) {
return "ID: " + id;
} else {
return "ID missing";
}
}
6. Default Value for @PathVariable
6.@PathVariable的默认值
Out of the box, there isn’t a provision to define a default value for method parameters annotated with @PathVariable. However, we can use the same strategies discussed above to satisfy the default value case for @PathVariable, we just need to check for null on the path variable.
开箱即用,并没有规定为用@PathVariable注释的方法参数定义默认值。然而,我们可以使用上面讨论的相同策略来满足@PathVariable的默认值情况,我们只需要检查路径变量的null。
For instance, using java.util.Optional<String, String>, we can identify if the path variable is null or not. If it is null, then we can just respond to the request with a default value:
例如,使用java.util.Optional<String, String>,我们可以识别路径变量是否为null。如果是null,那么我们就可以用一个默认值来响应请求。
@GetMapping(value = { "/api/defaultemployeeswithoptional", "/api/defaultemployeeswithoptional/{id}" })
@ResponseBody
public String getDefaultEmployeesByIdWithOptional(@PathVariable Optional<String> id) {
if (id.isPresent()) {
return "ID: " + id.get();
} else {
return "ID: Default Employee";
}
}
7. Conclusion
7.结语
In this article, we discussed how to use Spring’s @PathVariable annotation. We also identified the various ways to effectively use the @PathVariable annotation to suit different use cases, such as optional parameters and dealing with default values.
在这篇文章中,我们讨论了如何使用Spring的@PathVariable注解。我们还确定了有效使用@PathVariable注解的各种方法,以适应不同的使用情况,如可选参数和处理默认值。
The code example shown in this article is also available over on Github.
本文中显示的代码示例也可在Github上获得over。