Spring MVC Java Config (конфигурация с аннотациями) для web.xml
Пример преобразования дескриптора развертывания web.xml в конфигурацию Spring MVC Java Config (конфигурация с аннотациями).
Обзор приложения Spring MVC + AngularJS + Bootstrap + HTML5
Используемые технологии и библиотеки
- Spring MVC 4.2.4.Release
1. Описание задачи
Преобразовать дескриптор развертывания web.xml в программную конфигурацию с помощью Java config (POJO класс).
2. Структура проекта
Чтобы поменять xml конфигурации (web.xml, security-config.xml, mvc-config.xml, application-context.xml) на вариант Java Config с использованием классов и аннотаций был добавлен пакет javaconfig. В нем содержаться классы, соответствующие xml конфигурации, которые были использованы на протяжении цикла статей этого проекта. WebConfig является аналогом web.xml, ApplicationConfig = application-context.xml, MVCConfig = mvc-config.xml, SpringSecurityInit и SecurityConfig являются аналогом security-config.xml.
3. Важное замечание
Это первая часть из нескольких статей по переходу от xml конфигурации к Java конфгурации. Поэтому просто убрав web.xml и заменив на аналог WebConfig из этой статьи работать приложение у вас не будет. Используйте полную конфигурацию из скачанного проекта или используйте эту статью как справочную информацию по сопоставлению элементов из xml файла с java конфигурацией.
4. web.xml
Т.к. все настройки были описаны в предыдущих статьях, то здесь будет минимум описаний каждого элемента. Код можно легко сравнить сопоставляя названия xml и java класса.
web.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 79 80 81 |
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>mvc-html5-angularjs</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value> WEB-INF/config/application-context.xml WEB-INF/config/security-config.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <!--Spring security--> <!-- Need to enable xml config Spring Security --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/mvc-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--Позволяет работать с русскими символами--> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--<welcome-file-list>--> <!--<welcome-file>/WEB-INF/view/index.jsp</welcome-file>--> <!--</welcome-file-list>--> <error-page> <error-code>404</error-code> <location>/WEB-INF/view/error/errorstatus.jsp</location> </error-page> </web-app> |
5. WebConfig
Аналог web.xml в конфгурации Java выглядит так.
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 |
package ru.javastudy.mvcHtml5Angular.javaconfig; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; /** * Created for JavaStudy.ru on 28.05.2016. * _web.xml analogue */ public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { //create the root Spring application context AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(ApplicationConfig.class, SecurityConfig.class); servletContext.addListener(new ContextLoaderListener(rootContext)); //Create the dispatcher servlet's Spring application context AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext(); servletAppContext.register(MVCConfig.class); DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext); // throw NoHandlerFoundException to controller ExceptionHandler.class. Used for <error-page> analogue dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); //register and map the dispatcher servlet //note Dispatcher servlet with constructor arguments ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", dispatcherServlet); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encoding-filter", new CharacterEncodingFilter()); encodingFilter.setInitParameter("encoding", "UTF-8"); encodingFilter.setInitParameter("forceEncoding", "true"); encodingFilter.addMappingForUrlPatterns(null, true, "/*"); } /** * added to load spring security filter in root context (created in onStartup()) */ @Override protected Class<?>[] getRootConfigClasses() { return new Class[] {SecurityConfig.class}; } @Override protected String[] getServletMappings() { return new String[0]; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[0]; } } |
Сопоставить одно с другим достаточно легко, но разобьем обе конфигурации на части.
Инициализация корневого контекста и добавление в него двух конфигурационных файлов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<context-param> <param-name>contextConfigLocation</param-name> <param-value> WEB-INF/config/application-context.xml WEB-INF/config/security-config.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> |
и
1 2 3 4 5 |
//create the root Spring application context AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(ApplicationConfig.class, SecurityConfig.class); servletContext.addListener(new ContextLoaderListener(rootContext)); |
Регистрация диспетчера сервлетов и mvc конфигурации.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/mvc-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> |
аналог в java:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//Create the dispatcher servlet's Spring application context AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext(); servletAppContext.register(MVCConfig.class); DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext); // throw NoHandlerFoundException to controller ExceptionHandler.class. Used for <error-page> analogue dispatcherServlet.setThrowExceptionIfNoHandlerFound(true); //register and map the dispatcher servlet //note Dispatcher servlet with constructor arguments ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", dispatcherServlet); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); |
Добавление фильтра кодирования символов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!--Позволяет работать с русскими символами--> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
encodingFilter в java config:
1 2 3 4 |
FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encoding-filter", new CharacterEncodingFilter()); encodingFilter.setInitParameter("encoding", "UTF-8"); encodingFilter.setInitParameter("forceEncoding", "true"); encodingFilter.addMappingForUrlPatterns(null, true, "/*"); |
Конфигурация Spring Security будет рассматриваться в отдельной статье, но здесь есть два участка, в которых конфигурация Security загружается в контекст приложения.
1 |
rootContext.register(ApplicationConfig.class, SecurityConfig.class); |
Здесь регистрируется класс с конфигурацией Spring Security. Но если оставить только этот код, то мы будем получать ошибки при загрузке (или компиляции) приложения. Например для этого приложения сразу будет падать на @Autowired DataSource. Дело в том, что конфигурация spring security должна быть загружена в тот же контекст, который мы создаем в методе onStartup(). Это делается с помощью метода getRootConfigClasses().
1 2 3 4 |
@Override protected Class<?>[] getRootConfigClasses() { return new Class[] {SecurityConfig.class}; } |
На этом преобразования web.xml в java конфигурацию закончены. Читайте следующие статьи для изучения преобразования других конфигурационных xml файлов Spring.
Следующие части перехода с xml на Java конфигурацию
Spring MVC Java Config (конфигурация с аннотациями) для mvc-config.xml
Spring MVC Java Config (конфигурация с аннотациями) для Spring Security (security-config.xml)
Spring MVC Java Config (конфигурация с аннотациями) для application-context.xml
Исходный код
23. Annotations config — проект в IDEA
107 thoughts on “Spring MVC Java Config (конфигурация с аннотациями) для web.xml”
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.
Добрый день!
А если мы SecurityConfig.class добавим в onStartup: То нам не нужно наследоваться от
То нам не нужно наследоваться от
???
Не совсем понял вопроса. SecurityConfig и AbstractAnnotationConfigDispatcherServletInitializer это два совершенно независимых класса. Настройки SecurityConfig относятся только к Spring Security и их вообще можно не грузить, а наследоваться от второго класса нужно обязательно (есть еще варианты, но здесь использован этот класс).
У меня вот так работает :
Зачем тогда нужен onStartup?
Не понимаю как быть с <welcome—file>. Почему в web.xml он закомменчен и что вместо него писать в JavaConfig?
Ничего не нужно писать, т.к. стартовая страница тянется из настроек спринга
<mvc:view—controller path=«/» view—name=«/index»/>
При старте сервера приложений по умолчанию для Tomcat откроется по / и следовательно перейдет на index.html. Поэтому в web.xml этот участок закомментирован, а в java конфиг вообще не прописывается.
Еще нужно учитывать подключенный Spring Security — при переходе на закрытую страницу перекинет на авторизацию.
У меня не видит метода
Разве так не проще http://www.ibm.com/developerworks/ru/library/ws-springjava/