Spring + Web MVC: dispatcher-servlet.xml and applicationContext.xml (plus general security)

What is the correct way to use two contexts: dispatcher-servlet.xml and applicationContext.xml ? What's happening?

I want to write a fairly typical application deployed in a servlet container. It has several controllers with JSP views. It also has some nontrivial logic in the background. Do I really need both contexts? How are they related to each other? How can I decide what to add?

In addition, I want to use Spring-security for my application. I can use its functions (e.g. declarative security with annotations) in web controllers as well as in deeper layers. How to configure security in this case? Should it be in one of these files (which?) Or both?

+62
spring spring-mvc spring-security
May 09 '13 at 9:39
source share
6 answers

The dispatcher-servlet.xml contains all of your configuration for Spring MVC . So you will find beans like ViewHandlerResolvers , ConverterFactories , Interceptors and so on. All of these beans are part of Spring MVC , which is a framework that structures how you handle web requests, providing useful features like data binding, view resolution, and query matching.

application-context.xml can optionally be included when using Spring MVC or any other structure in this regard. This gives you a container that can be used to configure other types of spring beans that provide support for things like data storage. Basically, in this configuration file, you can use all the other useful spring properties.

These configuration files are configured in the web.xml file, as shown below:

Dispatcher configuration

 <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/spring/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> 

Application configuration

 <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/application-context.xml</param-value> </context-param> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> 

To configure the controllers, annotate them using @Controller , and then add the following to the dispatcher-context.xml file:

 <mvc:annotation-driven/> <context:component-scan base-package="package.with.controllers.**" /> 
+71
May 9 '13 at
source share

To add to Kevin’s answer, I find that almost all of your non-trivial Spring MVC applications will require an application context (as opposed to only the Spring MVC dispatcher servlet context). In the context of the application, you must configure all non-website related issues, such as:

  • Security
  • Constancy
  • Scheduled Tasks
  • Others?

To make it more specific, here is an example Spring configuration that I used when setting up a modern Spring application version 4.1.2) Spring MVC. Personally, I prefer to use the WEB-INF/web.xml , but this is really the only xml configuration in sight.

WEB-INF / web.xml

 <?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"> <filter> <filter-name>openEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> </filter> <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> <filter-mapping> <filter-name>openEntityManagerInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <param-value>com.company.config.WebConfig</param-value> </init-param> </servlet> <context-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value>com.company.config.AppConfig</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet-mapping> <servlet-name>springMvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid>true</scripting-invalid> </jsp-property-group> </jsp-config> </web-app> 


Webconfig.java

 @Configuration @EnableWebMvc @ComponentScan(basePackages = "com.company.controller") public class WebConfig { @Bean public InternalResourceViewResolver getInternalResourceViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; } } 


Appconfig.java

 @Configuration @ComponentScan(basePackages = "com.company") @Import(value = {SecurityConfig.class, PersistenceConfig.class, ScheduleConfig.class}) public class AppConfig { // application domain @Beans here... } 


Security.java

 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private LdapUserDetailsMapper ldapUserDetailsMapper; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/**/js/**").permitAll() .antMatchers("/**/images/**").permitAll() .antMatchers("/**").access("hasRole('ROLE_ADMIN')") .and().formLogin(); http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.ldapAuthentication() .userSearchBase("OU=App Users") .userSearchFilter("sAMAccountName={0}") .groupSearchBase("OU=Development") .groupSearchFilter("member={0}") .userDetailsContextMapper(ldapUserDetailsMapper) .contextSource(getLdapContextSource()); } private LdapContextSource getLdapContextSource() { LdapContextSource cs = new LdapContextSource(); cs.setUrl("ldaps://ldapServer:636"); cs.setBase("DC=COMPANY,DC=COM"); cs.setUserDn("CN=administrator,CN=Users,DC=COMPANY,DC=COM"); cs.setPassword("password"); cs.afterPropertiesSet(); return cs; } } 


PersistenceConfig.java

 @Configuration @EnableTransactionManagement @EnableJpaRepositories(transactionManagerRef = "getTransactionManager", entityManagerFactoryRef = "getEntityManagerFactory", basePackages = "com.company") public class PersistenceConfig { @Bean public LocalContainerEntityManagerFactoryBean getEntityManagerFactory(DataSource dataSource) { LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean(); lef.setDataSource(dataSource); lef.setJpaVendorAdapter(getHibernateJpaVendorAdapter()); lef.setPackagesToScan("com.company"); return lef; } private HibernateJpaVendorAdapter getHibernateJpaVendorAdapter() { HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter(); hibernateJpaVendorAdapter.setDatabase(Database.ORACLE); hibernateJpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.Oracle10gDialect"); hibernateJpaVendorAdapter.setShowSql(false); hibernateJpaVendorAdapter.setGenerateDdl(false); return hibernateJpaVendorAdapter; } @Bean public JndiObjectFactoryBean getDataSource() { JndiObjectFactoryBean jndiFactoryBean = new JndiObjectFactoryBean(); jndiFactoryBean.setJndiName("java:comp/env/jdbc/AppDS"); return jndiFactoryBean; } @Bean public JpaTransactionManager getTransactionManager(DataSource dataSource) { JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); jpaTransactionManager.setEntityManagerFactory(getEntityManagerFactory(dataSource).getObject()); jpaTransactionManager.setDataSource(dataSource); return jpaTransactionManager; } } 


ScheduleConfig.java

 @Configuration @EnableScheduling public class ScheduleConfig { @Autowired private EmployeeSynchronizer employeeSynchronizer; // cron pattern: sec, min, hr, day-of-month, month, day-of-week, year (optional) @Scheduled(cron="0 0 0 * * *") public void employeeSync() { employeeSynchronizer.syncEmployees(); } } 

As you can see, the web configuration is only a small part of the overall configuration of the Spring web application. Most of the web applications I have worked with have many problems that lie outside the dispatcher servlet configuration, which require a full-blown application context loaded through org.springframework.web.context.ContextLoaderListener in web.xml .

+36
Dec 12 '14 at 0:44
source share
 <?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <mvc:annotation-driven/> <context:component-scan base-package="com.testpoc.controller"/> <bean id="ViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="ViewClass" value="org.springframework.web.servlet.view.JstlView"></property> <property name="prefix"> <value>/WEB-INF/pages/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans> 
+2
Feb 03 '16 at 12:13
source share
 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>TestPOC</display-name> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> </context-param> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 
0
Feb 03 '16 at 12:18
source share
 <mvc:annotation-driven /> <mvc:default-servlet-handler /> <mvc:resources mapping="/resources/**" location="/resources/" /> <context:component-scan base-package="com.tridenthyundai.ains" /> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="/WEB-INF/messages" /> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/pages/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> 

0
Feb 04 '16 at 4:36
source share
 <?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd "> <mvc:annotation-driven /> <mvc:default-servlet-handler /> <mvc:resources mapping="/resources/**" location="/resources/" /> <context:component-scan base-package="com.sapta.hr" /> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="/WEB-INF/messages" /> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/pages/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans> 
0
Feb 22 '17 at 14:33
source share



All Articles