1. Обзор
В этом кратком руководстве мы рассмотрим аннотацию Spring @PathVariable
.
Проще говоря, аннотацию @PathVariable
можно использовать для обработки переменных шаблона в отображении URI запроса и установки их в качестве параметров метода.
Давайте посмотрим, как использовать @PathVariable
и его различные атрибуты.
2. Простое отображение
Простым вариантом использования аннотации @PathVariable
может быть конечная точка, которая идентифицирует объект с помощью первичного ключа:
@GetMapping("/api/employees/{id}")
@ResponseBody
public String getEmployeesById(@PathVariable String id) {
return "ID: " + id;
}
В этом примере мы используем аннотацию @PathVariable
для извлечения шаблонной части URI, представленной переменной {id}
.
Простой запрос GET
к /api/employees/{id}
вызовет getEmployeesById
с извлеченным значением идентификатора:
http://localhost:8080/api/employees/111
----
ID: 111
Теперь давайте подробнее изучим эту аннотацию и посмотрим на ее атрибуты.
3. Указание имени переменной пути
В предыдущем примере мы пропустили определение имени переменной пути шаблона, поскольку имена параметра метода и переменной пути были одинаковыми.
Однако, если имя переменной пути отличается, мы можем указать его в аргументе аннотации @PathVariable
:
@GetMapping("/api/employeeswithvariable/{id}")
@ResponseBody
public String getEmployeesByIdWithVariableName(@PathVariable("id") String employeeId) {
return "ID: " + employeeId;
}
http://localhost:8080/api/employeeswithvariable/1
----
ID: 1
Мы также можем определить имя переменной пути как @PathVariable(value="id")
вместо PathVariable("id")
для ясности.
4. Несколько переменных пути в одном запросе
В зависимости от варианта использования у нас может быть более одной переменной пути в нашем 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
Мы также можем обрабатывать более одного параметра @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
Однако существует небольшая проблема при обработке нескольких параметров @ PathVariable
, когда строка переменной пути содержит символ точки (.). Мы подробно обсудили эти угловые случаи здесь .
5. Дополнительные переменные пути
В Spring параметры метода, аннотированные @PathVariable
, требуются по умолчанию:
@GetMapping(value = { "/api/employeeswithrequired", "/api/employeeswithrequired/{id}" })
@ResponseBody
public String getEmployeesByIdWithRequired(@PathVariable String id) {
return "ID: " + id;
}
Судя по тому, как это выглядит, вышеприведенный контроллер должен обрабатывать пути запросов /api/employeeswithrequired
и /api/employeeswithrequired/1 .
Однако, поскольку параметры метода, аннотированные @PathVariables
, являются обязательными по умолчанию, он не обрабатывает запросы, отправленные в /api/employeeswithrequired
path:
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
Мы можем справиться с этим двумя разными способами.
5.1. Установка @PathVariable
как необязательная
Мы можем установить для обязательного
свойства @PathVariable
значение 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. Использование java.util.Optional
С момента появления 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";
}
}
Теперь, если мы не укажем идентификатор
переменной пути в запросе, мы получим ответ по умолчанию:
http://localhost:8080/api/employeeswithoptional
----
ID missing
5.3. Использование параметра метода типа Map<String, String>
Как показано ранее, мы можем использовать один параметр метода типа 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. Значение по умолчанию для @PathVariable
По умолчанию не предусмотрено определение значения по умолчанию для параметров метода, аннотированных с помощью @PathVariable
. Однако мы можем использовать те же стратегии, которые обсуждались выше, чтобы удовлетворить случай значения по умолчанию для @PathVariable,
нам просто нужно проверить значение null
в переменной пути.
Например, используя java.util.Optional<String, String>
, мы можем определить, является ли переменная пути нулевой
или нет. Если он равен нулю,
то мы можем просто ответить на запрос со значением по умолчанию:
@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. Заключение
В этой статье мы обсудили, как использовать аннотацию Spring @PathVariable
. Мы также определили различные способы эффективного использования аннотации @PathVariable
для различных вариантов использования, таких как необязательные параметры и работа со значениями по умолчанию.
Пример кода, показанный в этой статье, также доступен на Github .