Mục lục
@PathVariable được sử dụng để xử lý template variables trong request URI mapping.
Simple mapping
Trường hợp sử dụng @PathVariable đơn giản nhất là dùng để xác thực khóa chính của entity muốn truy vấn.
@GetMapping("/api/employee/{id}") public String getEmployeeById(@PathVariable String id) { return "ID " + id; }
Trong ví dụ trên, @PathVariable được sử dụng để trích xuất {id} từ đường dẫn URL. Khi thực hiển truy vấn đến /api/employees/{id} với id được truyền vào thì getEmployeeById() sẽ được gọi với giá trị id tương ứng.
curl http://localhost:8080/api/employee/13 --- ID 13
Path Variables Name
Trong ví dụ trước, mình đã sử dụng @PathVariable mà không chỉ định bất kỳ thuộc tính nào, vì vậy tên biến của tham số đầu vào sẽ trùng với tên trên URL template . Nhiều bạn có sử dụng mặc định như vậy sẽ rất dễ gây nhầm lẫn.
Chúng ta có thể cấu hình tên trên URL template tương ứng thông qua thuộc tính name mà @PathVariable cung cấp, lúc này chúng ta có thể đặt tên biến của tham số đầu vào cách tự do và có ý nghĩa hơn.
@GetMapping("/api/employeeswithvariable/{id}") public String getEmployeesByIdWithVariableName(@PathVariable("id") String employeeId) { return "ID: " + employeeId }
Chúng ta có thể thấy ở ví dụ trên, tên của tham số đầu vào là employeeId khác với tên trên URL template là id. Nhưng vì chúng ta đã chỉ định @PathVariable(“id”) nên Spring sẽ nhận biết và trích xuất giá trị của id trên URL template.
curl http://localhost:8080/api/employeeswithvariable/1 --- ID: 1
Chúng ta có thể sử dụng @PathVariable(value=”id”) tương ứng như PathVariable(“id”).
Optional Path Variables
Các tham số được chú thích với @PathVariable mặc định phải khác NULL, nếu chúng ta truyền vào một giá trị NULL thì Spring Boot sẽ trả về một exception để thông báo lỗi.
@GetMapping("/api/employeeswithrequired/{id}") public String getEmployeesByIdWithRequired(@PathVariable String id) { return "ID: " + id; }
Giả sử mình có API trên, khi mình truy vấn với giá trị của id NULL thì sẽ nhận về một thông báo lỗi như sau:
curl http://localhost:8080/api/employeeswithrequired/ {"timestamp":"2020-12-24T04:22:13.157+00:00","status":404,"error":"Not Found","message":"","path":"/api/employeeswithrequired/"}
Để giải quyết vấn đề trên, trước hết chúng ta cần xác định, nếu giá trị id chấp nhận NULL thì có 2 cách:
- required = false
- Optional
Với cách đầu tiên, @PathVariable cung cấp thuộc tính required mặc định có giá trị TRUE nghĩa là dữ liệu truyền vào không được NULL, chúng ta có thể gán nó thành NULL. Tuy nhiên chúng ta phải thêm một URL template đại diện cho trường hợp giá trị NULL
@GetMapping(value = {"/api/employeeswithrequiredfalse", "/api/employeeswithrequiredfalse/{id}" }) public String getEmployeesByIdWithRequiredFalse(@PathVariable(required = false) String id) { if (id != null) { return "ID: " + id; } else { return "ID missing"; } }
Kết quả
curl http://localhost:8080/api/employeeswithrequiredfalse/ --- ID missing
Kể từ Spring 4.1, chúng ta có thể sử dụng Optional class(phiên bản Java 8+) để xử lý trường hợp giá trị trên URL template rỗng.
curl http://localhost:8080/api/employeeswithoptional --- ID missing
Multiple Path Variables in a Single Reques
Tùy thuộc vào trường hợp sử dụng, chúng ta có thể có nhiều hơn một biến đường dẫn trong URI yêu cầu của chúng ta cho một phương thức bộ điều khiển, cũng có nhiều tham số phương thức:
@GetMapping("/api/employees/{id}/{name}") public String getEmployeesByIdAndName(@PathVariable String id, @PathVariable String name) { return "ID: " + id + ", name: " + name; }
curl http://localhost:8080/api/employees/1/bar ---- ID: 1, name: bar
@PathVariable với Map
Chúng ta có thể sử dụng một tham số phương thức duy nhất kiểu java.util.Map để xử lý tất cả các biến đường dẫn trong URI yêu cầu. Chúng ta cũng có thể sử dụng chiến lược này để xử lý trường hợp biến đường dẫn tùy chọn:
@GetMapping(value = { "/api/employeeswithmap/{id}", "/api/employeeswithmap" }) public String getEmployeesByIdWithMap(@PathVariable Map<String, String> pathVarsMap) { String id = pathVarsMap.get("id"); if (id != null) { return "ID: " + id; } else { return "ID missing"; } }
Default value trên @PathVariable
Trong Spring,chúng ta không thể xác định giá trị mặc định cho các tham số được chú thích bằng @PathVariable. Tuy nhiên, chúng ta có thể sử dụng các chiến lược tương tự đã thảo luận ở trên để đáp ứng trường hợp giá trị mặc định cho @PathVariable. Chúng ta chỉ cần kiểm tra giá trị null trên biến đường dẫn.
@GetMapping(value = { "/api/defaultemployeeswithoptional", "/api/defaultemployeeswithoptional/{id}" }) public String getDefaultEmployeesByIdWithOptional(@PathVariable Optional<String> id) { if (id.isPresent()) { return "ID: " + id.get(); } else { return "ID: Default Employee"; } }
Kết bài
Như vậy chúng ta vừa tìm hiểu về cách sử dụng @PathVariable annotation trong Spring boot, với rất nhiều ví dụ có thể giúp bạn triển khai bất cứ một yêu cầu nào.
Sau cùng, các bạn có thể tham khảo mã nguồn mình công khai trên gitlab để tiện theo dõi và thực hành: pathvariable