Interceptors (перехватчики ) в Spring MVC. Настройка, пример использования
Пример использования простого перехватчика для дополнительной обработки запроса в Spring MVC.
Обзор приложения Spring MVC + AngularJS + Bootstrap + HTML5
Используемые технологии и библиотеки
- Spring MVC 4.2.4.Release
- Maven 3.2.5
- IntelliJ IDEA 15.0.2
1. Описание задачи
Рассмотреть работу перехватчиков в Spring MVC. Написать три метода: preHandle(), postHandle(), afterCompletion(), которые вызываются перед обработкой запроса актуальным классом, после этой обработки, а так же после окончания запроса соответственно.
2. Структура проекта
Для этой статьи относительно прошлой части добавлены только два класса InterceptorController и SiteInterceptor. Первый класс — это обычный контроллер, который обрабатывает запрос в стандартном порядке. С помощью него мы увидим в какой момент относительно вызова метода контроллера будут вызываться методы перехватчика.
3. Конфигурация Spring MVC
Для включения в обработку запросов перехватчиков Spring необходимо минимум настроек.
mvc-config.xml:
1 2 3 4 5 6 7 8 |
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/interceptorCall/*"/> <!--need to use ' /** ' not ' /* ' if you want to intercept all requests.--> <!--<mvc:mapping path="/**"/>--> <bean class="ru.javastudy.mvcHtml5Angular.mvc.interceptors.SiteInterceptor"/> </mvc:interceptor> </mvc:interceptors> |
Здесь приведена простенькая настройка одного перехватчика. Сначала задается общий тег <interceptors /> внутри которого необходимо перечислить все необходимые перехватчики. В нашем случае задан один перехватчик, а так же его маппинг (/interceptorCall/*). Так же указан класс перехватчик, который должен реагировать при перехвате запроса, соответствующему URI. В комментариях в коде обращаю внимание, что для обработки всех запросов необходимо использовать две звездочки, а не одну.
Полный листинг mvc-config.xml показан под катом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- context:component-scan This tag will scan @Component, @Repository, @Service, @Controller and also resolves @Autowired and @Qualifier --> <context:component-scan base-package="ru.javastudy.mvcHtml5Angular.mvc" /> <!-- mvc:annotation-driven configures Spring MVC annotations Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is present on the classpath. HttpMessageConverter support for @RequestBody method parameters and @ResponseBody method return values from @RequestMapping or @ExceptionHandler methods. --> <mvc:annotation-driven/> <!-- activate @Transactional JPA annotation --> <tx:annotation-driven/> <!-- ViewResolver bean config for mapping strings to jsp views --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' --> <property name="order" value="1" /> <property name="prefix" value="/WEB-INF/view/" /> <property name="suffix" value=".jsp" /> </bean> <!-- File Upload bean config--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- set the maximum file size in bytes --> <property name="maxUploadSize" value="1000000"/> </bean> <!--Excel and PDF xml view configuration --> <!--disabling for jUnit test. --> <bean class="org.springframework.web.servlet.view.XmlViewResolver"> <property name="order" value="0" /> <property name="location" value="/WEB-INF/config/excel-pdf-config.xml"/> </bean> <mvc:view-controller path="/index.html" view-name="/index"/> <mvc:view-controller path="/about.html" view-name="/about/about"/> <mvc:view-controller path="/file.html" view-name="/file/file"/> <mvc:view-controller path="/jdbc.html" view-name="/jdbc/jdbc"/> <mvc:view-controller path="/email.html" view-name="/email/email"/> <mvc:view-controller path="/rest.html" view-name="/rest/rest"/> <mvc:view-controller path="/orm.html" view-name="/orm/orm"/> <mvc:view-controller path="/jstl.html" view-name="/jstl/jstl"/> <!-- Static Resources Configuration (get access to static sources such as CSS and JavaScript files) --> <mvc:resources mapping="/resources/**" location="/resources/" /> <!-- themes can be put in different folder such as <mvc:resources mapping="/resources/**" location="/resources/themeBlue" /> <mvc:resources mapping="/resources/**" location="/resources/themeGreen" /> --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/interceptorCall/*"/> <!--need to use ' /** ' not ' /* ' if you want to intercept all requests.--> <!--<mvc:mapping path="/**"/>--> <bean class="ru.javastudy.mvcHtml5Angular.mvc.interceptors.SiteInterceptor"/> </mvc:interceptor> </mvc:interceptors> </beans> |
4. Web.xml, pom.xml
Никаких строк в конфигурационные файлы для этой части добавлено не было. Смотрите предыдущую статью или скачивайте исходные коды в конце статьи.
5. Java классы
Сначала был добавлен обычный контроллер Spring MVC, который срабатывает на запрос, соответствующий /interceptorCall/subLevel.
InterceptorController:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package ru.javastudy.mvcHtml5Angular.mvc.interceptors; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; /** * Created for JavaStudy.ru on 03.03.2016. */ @Controller public class InterceptorController { @RequestMapping(value = "/interceptorCall/subLevel", method = RequestMethod.GET) public ModelAndView interceptorCall() { System.out.println("interceptorCall() is called"); return new ModelAndView("/index"); } } |
Теперь добавим непосредственно перехватчик, который будет выполнять определенный код до вызова метода interceptorCall() контроллера, после него, а так же по завершению запроса.
SiteInterceptor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package ru.javastudy.mvcHtml5Angular.mvc.interceptors; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Created for JavaStudy.ru on 03.03.2016. */ @Component public class SiteInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("SiteInterceptor preHandle"); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("SiteInterceptor postHandle"); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("SiteInterceptor afterCompletion"); } } |
6. Запуск приложения
Вызов перехватчика происходит по нажатию кнопки внизу первой страницы приложения.
В результате в консоль будут выведены строки:
1 2 3 4 |
SiteInterceptor preHandle interceptorCall() is called SiteInterceptor postHandle SiteInterceptor afterCompletion |
Как видите перед вызовом метода контроллера был вызван метод preHandle(). Затем был вызван метод контроллера и в последствии два метода перехватчика.
В дальнейшем будут добавлены еще классы-перехватчики, например при локализации i18n приложения.
Исходные коды
MVC_AngularJS_Html5 full project — полный проект Spring MVC + AngularJS + Bootstrap + HTML5.
10. Interceptors — код для этой части