Обробка HTTP запитів від клієнтів у веб-додатках, надання правильних даних і забезпечення безпеки додатку мають велике значення. Spring Framework пропонує дві потужні структури для виконання цих завдань: Request Filter та Request Mapping. У цій статті ми детально розглянемо ці два поняття та пояснимо їх використання через приклади.
Request Mapping
Request Mapping — це механізм, який дозволяє спрямувати HTTP запит від клієнта до певного методу контролера. У Spring Framework це здійснюється за допомогою анотацій @RequestMapping та її більш специфічних варіантів (@GetMapping, @PostMapping тощо).
Основні характеристики Request Mapping
- Відповідність URL: Прив'язує певний URL до методу.
- Підтримка HTTP методів: Може здійснювати відповідність за методами HTTP, такими як GET, POST, PUT, DELETE.
- Шляхові змінні та параметри запиту: Може працювати з динамічними частинами URL або параметрами запиту.
- Content Negotiation: Використовується для визначення типів запиту або відповіді (наприклад,
produces
,consumes
).
Основне використання
Розглянемо приклад:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users")
public List getAllUsers() {
return List.of("Alice", "Bob", "Charlie");
}
@PostMapping("/users")
public String createUser(@RequestBody String userName) {
return "Користувач створений: " + userName;
}
}
- Якщо буде зроблений GET запит за адресою /api/users, виконується метод
getAllUsers
. - Якщо буде зроблений POST запит за адресою /api/users, викликається метод
createUser
.
Динамічні параметри у Request Mapping
Для використання динамічних сегментів URL застосовуються анотації @PathVariable або @RequestParam:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users/{id}")
public String getUserById(@PathVariable int id) {
return "Користувач ID: " + id;
}
@GetMapping("/search")
public String searchUser(@RequestParam String name) {
return "Шукаємо користувача: " + name;
}
}
- /api/users/5 → викликається метод
getUserById
, а параметр id отримає значення 5. - /api/search?name=Alice → викликається метод
searchUser
, а параметр name отримає значення “Alice”.
Request Mapping з Content Negotiation
Spring підтримує обробку запитів і відповідей в залежності від їх типу:
@RestController
@RequestMapping("/api")
public class FileController {
@PostMapping(value = "/upload", consumes = "multipart/form-data")
public String uploadFile() {
return "Файл завантажено.";
}
@GetMapping(value = "/download", produces = "application/json")
public Map downloadFile() {
return Map.of("fileName", "document.txt", "status", "available");
}
}
consumes
: визначає тип запиту (наприклад, application/json, multipart/form-data).produces
: визначає тип відповіді (наприклад, application/json).
Request Filter
Request Filter — це механізм, який дає змогу контролювати та маніпулювати HTTP запитами та відповідями. Spring Framework використовує інтерфейс Filter з Java Servlet API для виконання операцій фільтрації.
Мета Request Filter
- Контроль безпеки: Фільтри можуть бути використані для аутентифікації та авторизації.
- Маніпуляція запитом: Зміна заголовків або тіла вхідного запиту.
- Маніпуляція відповіддю: Зміна відповіді, що повертається сервером.
- Загальна логіка: Додавання функцій логування, стиснення даних або моніторингу.
Основні характеристики Request Filter
- Filter інтерфейс: Реалізує інтерфейс
javax.servlet.Filter
. - Цепочка обробки: Можна використовувати кілька фільтрів, які виконуються по черзі.
3.
Інтеграція зі Spring Boot: У Spring Boot фільтри можна легко налаштувати.
Простий приклад Request Filter
У наступному прикладі ми створюємо фільтр, який перехоплює всі HTTP запити і веде їх логування:
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Отриманий запит: " + request.getRemoteAddr());
chain.doFilter(request, response); // Продовжуємо обробку запиту
}
}
Щоб додати цей фільтр до Spring Boot додатку:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
@Configuration
public class FilterConfig {
@Bean
public Filter loggingFilter() {
return new LoggingFilter();
}
}
Розширене використання: Контроль безпеки
Приклад фільтра, який виконує перевірку JWT (JSON Web Token):
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class JwtAuthenticationFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String token = httpRequest.getHeader("Authorization");
if (token == null || !validateToken(token)) {
throw new ServletException("Невірний токен!");
}
chain.doFilter(request, response); // Продовжуємо обробку запиту
}
private boolean validateToken(String token) {
// Логіка перевірки токена
return true; // Для прикладу завжди вважаємо його дійсним
}
}
Порядок фільтрів у Spring Boot
Коли використовується кілька фільтрів, порядок їх виконання має значення. У Spring Boot можна вказати порядок фільтрів за допомогою анотації @Order:
@Bean
@Order(1)
public Filter firstFilter() {
return new FirstFilter();
}
@Bean
@Order(2)
public Filter secondFilter() {
return new SecondFilter();
}
Різниця між Request Mapping та Request Filter
Висновок
Request Mapping та Request Filter служать різним цілям у Spring додатках. Request Mapping дозволяє правильно спрямувати запит від клієнта до відповідного методу, тоді як Request Filter дає змогу здійснювати низькорівневу маніпуляцію з запитами та відповідями. Обидві структури є потужними, і при правильному використанні вони можуть суттєво вплинути на безпеку, продуктивність та масштабованість вашого додатку.
Перекладено з: Java Spring Framework: Request Filter ve Request Mapping Kavramları