Spring + Web MVC:dispatcher-servlet.xml与applicationContext.xml(加上共享安全性)

Kon*_*rus 68 spring spring-mvc spring-security

使用这两种情境的正确方法是什么?dispatcher-servlet.xmlapplicationContext.xml?怎么回事?

我想编写一个部署在servlet容器中的相当典型的应用程序.它有一些带JSP视图的控制器.它在后端也有一些非常重要的逻辑.我真的需要两种情境吗?它们如何相互关联?我该如何决定放入哪些内容?

另外,我想在我的应用程序中使用Spring-security.我可能希望在Web控制器以及更深层中使用其功能(如带注释的声明性安全性).在这种情况下,我应该如何配置安全性?它应该在其中一个文件中(哪个?),还是两个文件?

Kev*_*sox 77

dispatcher-servlet.xml文件包含您的所有配置Spring MVC.因此,在它,你会发现豆类,如ViewHandlerResolvers,ConverterFactories,Interceptors等等.所有这些bean都是Spring MVC一个框架,它构成了处理Web请求的方式,提供了有用的功能,如数据绑定,视图解析和请求映射.

application-context.xml使用时,可任选地包含Spring MVC或与此有关的任何其他框架.这为您提供了一个容器,可用于配置其他类型的spring bean,为数据持久性等提供支持.基本上,在这个配置文件中,您可以获取Spring提供的所有其他好东西.

这些配置文件在web.xml文件中配置,如下所示:

调度程序配置

<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>
Run Code Online (Sandbox Code Playgroud)

应用程序配置

<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>
Run Code Online (Sandbox Code Playgroud)

要配置控制器,请注释它们,@Controller 然后在dispatcher-context.xml文件中包含以下内容:

<mvc:annotation-driven/>
<context:component-scan base-package="package.with.controllers.**" />
Run Code Online (Sandbox Code Playgroud)

  • 我应该把我的MVC控制器放在哪里?我应该在哪里配置弹簧安全? (11认同)
  • @KonradGarus你现在可以自己回答这个问题吗?你是如何最终配置你的项目的? (2认同)

Bri*_*ace 42

为了添加Kevin的答案,我发现实际上几乎所有非平凡的Spring MVC应用程序都需要一个应用程序上下文(而不是只有spring MVC调度程序servlet上下文).在应用程序上下文中,您应该配置所有与Web无关的问题,例如:

  • 安全
  • 坚持
  • 计划任务
  • 其他?

为了使这更具体一点,这里是我在设置现代(Spring版本4.1.2)Spring MVC应用程序时使用的Spring配置示例.就个人而言,我更喜欢仍然使用WEB-INF/web.xml文件,但这确实是唯一的xml配置.

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>
Run Code Online (Sandbox Code Playgroud)


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;
  }
}
Run Code Online (Sandbox Code Playgroud)


AppConfig.java

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


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;
  }
}
Run Code Online (Sandbox Code Playgroud)


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;
  }
}
Run Code Online (Sandbox Code Playgroud)


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();
  }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,Web配置只是整个Spring Web应用程序配置的一小部分.我曾与大多数Web应用程序具有处在调度servlet配置需要通过自举一个完全成熟的应用程序上下文之外的许多问题org.springframework.web.context.ContextLoaderListenerweb.xml.