Однажды наш главный герой Кункун планировал открыть баскетбольный магазин. Он с радостью подготовил все, от баскетбольного оборудования до стиля оформления, и все это было тщательно продумано. Он решил назвать свой баскетбольный магазин «Баскетбольный магазин Kunkun», надеясь привлечь больше любителей баскетбола. В первый день открытия «Кункуна» баскетбольный магазин принял множество покупателей. Он радостно приветствует всех и знакомит с товарами и услугами магазина. Однако вскоре Кункун обнаружил, что некоторые клиенты могут и не быть настоящими фанатами баскетбола, но хотят воспользоваться возможностью, чтобы устроить неприятности или совершить какие-то незаконные поступки, которые часто называют «маленькими черными человечками». В это время он решил поставить трёх умных и милых Кун Цзявэя у входа в баскетбольный магазин. Известный как «Три куриные ноги», он является правой рукой Кункуна. Эта куриная нога, как вратарь, ловко различает, кто настоящие болельщики, а кто просто маленькие угри, и праведно издевается над фальшивыми фанатами. И вежливо поприветствуйте: «Тебе лучше быть». Когда кто-то заходит в баскетбольный магазин, Кун Цзявэй быстро определяет его цель. Если они настоящие фанаты баскетбола, Interceptor с энтузиазмом проведет их в подходящую зону для стажеров-айдолов и предоставит им услуги. Прежде чем они смогут весело танцевать, сцену и задник необходимо подготовить по своему вкусу. Тех, кто заподозрит подозрения, перехватчик сразу перехватит и предотвратит дальнейшие действия. Наконец, после страстного танца Остаётся Кун Цзявэй. Очистите поле боя, выполните последующие операции и очистите ресурсы.
Перехватчики играют важную роль в Spring MVC, используются для перехвата обработки запросов и ответов и позволяют разработчикам выполнять пользовательскую логику до того, как запрос попадет в контроллер или после того, как он покинет контроллер. Он предоставляет механизм для вставки пользовательского кода на разных этапах жизненного цикла запроса.
По сравнению с фильтрами перехватчики больше ориентированы на обработку логики уровня контроллера. Они тесно связаны с контроллером и могут получать доступ и изменять параметры и возвращаемые значения методов контроллера. Перехватчики часто используются для реализации некоторых общих сквозных задач, таких как аутентификация, проверка разрешений, ведение журналов, мониторинг производительности и т. д.
В Spring MVC перехватчики определяются путем реализации интерфейса HandlerInterceptor. Интерфейс HandlerInterceptor содержит три основных метода:
Эти методы вызываются в определенном порядке в цепочке перехватчиков. В случае существования нескольких перехватчиков порядок их выполнения определяется порядком конфигурации перехватчиков. Порядок выполнения цепочки перехватчиков — первый вход, последний выход, то есть перехватчик, настроенный первым, выполняется последним.
Написав собственный класс реализации HandlerInterceptor и настроив его в Spring MVC, разработчики могут гибко управлять логикой обработки запросов. Перехватчики предоставляют подключаемый механизм, который улучшает возможность повторного использования и сопровождения кода и может эффективно решать сквозные задачи.
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// существование вызывается до того, как запрос достигнет контроллера
// Можно выполнить некоторую предварительную обработку, например проверку личности, проверку разрешений и т. д.
// Возврат false предотвратит дальнейшую обработку запроса, возврат true позволит продолжить обработку запроса.
String token = request.getHeader("Authorization");
if (token == null || !isValidToken(token)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// существование вызывается после выполнения метода контроллера и перед визуализацией представления.
// Данные модели могут быть дополнительно обработаны или изменены.
if (modelAndView != null) {
modelAndView.addObject("customData", "Additional data");
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// существование вызывается после завершения всей обработки запроса
// Вы можете выполнять какие-то операции по очистке ресурсов или записывать результаты обработки запросов и т. д.
logRequestCompletion(request, response.getStatus());
}
private boolean isValidToken(String token) {
// Логика токена проверки
// Возврат true означает, что токен действителен, возврат false означает, что токен недействителен.
// Это всего лишь пример: реальную бизнес-логику необходимо реализовать в соответствии с конкретными потребностями.
return true;
}
private void logRequestCompletion(HttpServletRequest request, int status) {
// Логика записи результатов обработки запроса
// Это всего лишь пример: реальную бизнес-логику необходимо реализовать в соответствии с конкретными потребностями.
System.out.println("Request completed - URI: " + request.getRequestURI() + ", Status: " + status);
}
}
Создайте класс Java, реализующий интерфейс HandlerInterceptor. Например, мы можем создать класс CustomInterceptor:
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Реализуйте метод preHandle для перехвата и обработки существующих запросов до того, как они достигнут контроллера.
// Здесь можно реализовать необходимую бизнес-логику, такую как проверка личности, проверка разрешений и т. д.
// Возврат true означает продолжение обработки запроса, возврат false предотвратит продолжение обработки запроса.
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// Реализуйте метод postHandle, перехватите и обработайте его после выполнения метода контроллера.
// существоватьздесь Данные модели могут быть дополнительно обработаны или изменены.
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// Реализуйте метод afterCompletion для перехвата и обработки всего запроса после его обработки.
// существоватьздесь Вы можете выполнять какие-то операции по очистке ресурсов или записывать результаты обработки запросов и т. д.
}
}
В классе CustomInterceptor вы можете реализовать методы preHandle, postHandle и afterCompletion по мере необходимости для написания конкретной бизнес-логики.
Зарегистрируйте перехватчик в конфигурации Spring MVC. В файле конфигурации Spring MVC (например, файле конфигурации XML или классе конфигурации Java) зарегистрируйте собственный перехватчик, настроив InterceptorRegistry. Вот пример, предполагающий, что вы используете классы конфигурации Java:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Зарегистрируйте собственный перехватчик
registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/**");
}
}
Ведение журнала: перехватчики могут использоваться для записи информации журнала запросов и ответов, включая запрошенный URL-адрес, параметры, время обработки и т. д. Это полезно для отслеживания и устранения неполадок, оптимизации производительности и статистического анализа.
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Запишите запрошенный URL и параметры
String url = request.getRequestURL().toString();
String queryString = request.getQueryString();
System.out.println("Request URL: " + url);
System.out.println("Request Parameters: " + queryString);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// существуют Здесь данные ответа могут быть зарегистрированы или обработаны
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// существование Здесь вы можете записывать такую информацию, как время обработки запроса.
}
}
Управление кешем. Перехватчики можно использовать для управления кешем, например для проверки наличия данных ответа в кеше до того, как запрос достигнет контроллера. Если он существует, возвращайте кэшированные данные напрямую, чтобы избежать повторных вычислений или запросов к базе данных.
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CacheInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Проверьте, сохранены ли существующие данные ответа в кеше
String cacheKey = generateCacheKey(request);
Object cachedData = getFromCache(cacheKey);
if (cachedData != null) {
// Возврат непосредственно к данным кэша
writeResponseData(response, cachedData);
return false; // Завершить запрос, чтобы продолжить обработку
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// существуют Здесь вы можете кэшировать ответные данные
String cacheKey = generateCacheKey(request);
Object responseData = extractResponseData(response);
storeInCache(cacheKey, responseData);
}
private String generateCacheKey(HttpServletRequest request) {
// Генерируйте уникальные ключи кэша на основе запрошенного URL, параметров и т. д.
// ...
}
private Object getFromCache(String cacheKey) {
// Получить данные из кеша
// ...
}
private void writeResponseData(HttpServletResponse response, Object data) {
// Напишите данные в ответ
// ...
}
private Object extractResponseData(HttpServletResponse response) {
// Извлечь данные из ответа
// ...
}
private void storeInCache(String cacheKey, Object data) {
// Сохранить данные в кэш
// ...
}
}
Контроль разрешений. Помимо аутентификации, перехватчики можно использовать для реализации детального контроля разрешений. В методе preHandle вы можете проверить, есть ли у текущего пользователя разрешение на доступ к ресурсу или выполнение операции. Если нет, вы можете вернуть соответствующее сообщение об ошибке или перенаправить на другие страницы.
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AuthorizationInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Проверьте права пользователя
if (!hasPermission(request)) {
// Нет разрешений, вернуть сообщение об ошибке или перенаправить на другие страницы.
response.sendRedirect("/error/unauthorized");
return false; // Завершить запрос, чтобы продолжить обработку
}
return true;
}
private boolean hasPermission(HttpServletRequest request) {
// Проверьте, есть ли у текущего пользователя разрешение на доступ к ресурсу
// ...
}
}
Анализ и предварительная обработка параметров запроса. Перехватчики можно использовать для анализа параметров запроса и выполнения некоторых операций предварительной обработки, таких как преобразование формата данных, проверка параметров и т. д. Это помогает разгрузить методы контроллера, чтобы они могли больше сосредоточиться на бизнес-логике.
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RequestProcessingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Анализ параметров и предварительная обработка
String param1 = request.getParameter("param1");
String param2 = request.getParameter("param2");
// Обработка или проверка параметров
// ...
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// существуют Здесь данные модели могут быть дополнительно обработаны или изменены.
}
}
Обработка ошибок. Перехватчики можно использовать для глобальной обработки ошибок, перехвата и обработки исключений. В методе afterCompletion исключения могут обрабатываться единообразно, например, ведение журнала, отправка уведомлений и т. д.
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ErrorHandlingInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// существования Исключения здесь обрабатываются единообразно
if (ex != null) {
// Записывать или отправлять уведомления
System.out.println("Exception occurred: " + ex.getMessage());
}
}
}