我有一个spring应用程序和带有Sticky Sessions的多节点服务器。我想将会话保留在数据库中,以免进行复制会话。
我尝试使用jdbc
实现@EnableJdbcHttpSession
会话存储,但我没有设法创建配置,以便数据库中的会话可以正常工作。
我在spring-session-jdbc
中有pom.xml
:
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
<version>2.0.2.RELEASE</version>
<type>pom</type>
</dependency>
也有:
@Configuration
@EnableTransactionManagement
@EnableJdbcHttpSession
public class AppConfig{
@Autowired
private AppEnvironment env;
@Bean(name = "dataSource")
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getDriverClassName());
dataSource.setUrl(env.getDatabaseUrl());
dataSource.setUsername(env.getDatabaseUserName());
dataSource.setPassword(env.getDatabasePassword());
dataSource.setValidationQuery(env.getDatabaseValidationQuery());
dataSource.setTestOnBorrow(env.isTomcatTestOnBorrow());
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter jpaAdapter = new HibernateJpaVendorAdapter();
jpaAdapter.setShowSql(Boolean.valueOf(env.isJpaShowSql()));
jpaAdapter.setDatabase(Database.SQL_SERVER);
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPersistenceProvider(new HibernatePersistenceProvider());
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "com.humanbizz.web.entities" });
em.setPersistenceUnitName("persistenceUnit");
em.setJpaVendorAdapter(jpaAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", env.getHibernateDialect());
properties.setProperty("hibernate.default_catalog", env.getDefaultCatalog());
properties.setProperty("hibernate.hbm2ddl.auto", env.getHbm2ddlAuto());
properties.setProperty("hibernate.id.new_generator_mappings", String.valueOf(env.isIdNewGeneratorMappings()));
properties.setProperty("hibernate.default_schema", env.getDefaultSchema());
properties.setProperty("hibernate.connection.useUnicode", String.valueOf(env.isConnectionUseUnicode()));
properties.setProperty("hibernate.connection.charSet", env.getConnectionCharSet());
return properties;
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
我的HttpSessionApplicationInitializer:
public class HttpSessionApplicationInitializer extends AbstractHttpSessionApplicationInitializer{
public HttpSessionApplicationInitializer() {
super(AppConfig.class);
}
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(WebSecurity.class, Datasource.class);
container.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(WebMvc.class);
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
container.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
}
}
但是当你启动应用程序时,会话没有存储在表中,我不知道我是否错过了配置中的任何内容,我发现的所有内容都应该设置这个但是它不起作用,任何想法和帮助会欢迎我
答案 0 :(得分:0)
主要问题是你已经覆盖了onStartup
的{{1}}方法,你打破了AbstractHttpSessionApplicationInitializer
的整个目的,即将Spring Session所需的过滤器注册到做它的工作。
我建议使用多个AbstractHttpSessionApplicationInitializer
,以便您可以利用默认值而不是重新发明轮子。在你的情况下,这意味着3 WebApplicationInitializer
。
要配置您的应用程序,我建议扩展WebApplicationInitializer
,这基本上就是您现在手动执行的操作。
AbstractAnnotationConfigDispatcherServletInitializer
现在您已经加载了所有配置,您需要启用Spring Security,以创建一个扩展@Order(1)
public MainApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class, WebSecurity.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebMvc.class };
}
}
的类。
AbstractSecurityWebApplicationInitializer
这个类就是您所需要的,因为它将从之前加载的根上下文中检测配置。
最后你需要Spring Session的东西,为此创建一个扩展@Order(2)
public SecurityInitializer extends AbstractSecurityWebApplicationInitializer() {}
的类。
AbstractHttpSessionApplicationInitializer
再次需要,因为它将检测先前创建的配置中的过滤器。您可能希望在每个上放置一个@Order(3)
public SpringSessionInitializer extends AbstractHttpSessionApplicationInitializer {}
,以确保它们以正确的顺序执行。