Spring MVC interceptors

Posted on: August 3rd, 2012 by Spade No Comments »

Иногда нужно добавить некоторую общую логику для всех обработчиков запросов. Например, проверка авторизован ли пользователь, какой он имеет набор прав, есть ли у него доступ к этой странице. Можно так же пускать пользователей на определенные ресурсы только в определенные часы. Для подобного рода задач spring framework предоставляет возможность написания своих «плагинов» – interceptor-ов. Каждый раз, когда начинается процесс разбора УРЛ, выбора обработчика (класса контроллера), вызова его функций и т.д. фреймворк смотрит не определен ли пользователем дополнительный обработчик для текущей стадии, если да – он будет вызван.

Разберем пример. Допустим мы хотим реализовать в нашей системе некоторое подобие архитектуры FeatureFlag – когда определенная функциональность в системе может включаться/выключаться администратором. Сильно упростим эту задачу и оставим только анализ УРЛ – пользователя можно пускать на запрошеный адрес, только если этот адрес «включен». Допустим у нас в БД есть таблица с адресами, на которые нельзя пускать. Алгоритм будет таков: если запрошеный адрес есть в таблице и он «отключен» – перенаправить пользователя в другое место.

Приведем код класса интерсептора:

public class UrlEnabledInterceptor extends HandlerInterceptorAdapter {
 
    private static final Logger log = LoggerFactory.getLogger(UrlEnabledInterceptor.class);
 
    @Autowired
    private ISystemService systemService;
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 
        log.debug("URI: {}", request.getRequestURI());
 
        boolean urlEnabled = systemService.isUrlEnabled(request.getRequestURI());
        if (!urlEnabled) {
            response.sendRedirect("/under-construction");
        }
        return urlEnabled;
    }
}

Он обязан реализовывать интерфейс HandlerInterceptor, либо, как в нашем случае, наследовать класс HandlerInterceptorAdapter, который уже реализовал этот интерфейс с помощью функций заглушек. Функций адаптера всего 3. Нас интересует только

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
	    throws Exception

Она возвращает булево значение, указывающее стоит ли продолжать обработку, или необходимо оборвать цепочку на этом месте. Если наш УРЛ отключен, мы «требуем» редирект на общую для такого случая страницу и возвращаем false – что завершает процесс обработки этого адреса.

В спринг конфиге – подключаем этот класс, как обработчик:

    <mvc:interceptors>
        <bean class="com.acestime.example.web.interceptors.UrlEnabledInterceptor"/>
    </mvc:interceptors>

Вот и все.

Leave a Reply