通常如何从 class 中获取会话对象?
How to get the session object in general from within a class?
有一个 class :
@Configuration
@ComponentScan("com.ambre.pta")
@EnableTransactionManagement
@PropertySources({
@PropertySource("classpath:fr/global.properties"),
@PropertySource("classpath:fr/main.properties"),
@PropertySource("classpath:fr/admin.properties"),
@PropertySource("classpath:fr/referentiel.properties"),
@PropertySource("classpath:fr/departement.properties"),
@PropertySource("classpath:fr/exercice.properties"),
@PropertySource("classpath:fr/defi.properties")
})
public class ApplicationContextConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean(name = "dataSource")
public DataSource getDataSource() {
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
bds.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
bds.setUsername("pta");
bds.setPassword("pta");
return bds;
}
@Autowired
@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.scanPackages("com.ambre.pta.model");
return sessionBuilder.buildSessionFactory();
}
@Autowired
@Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
@Autowired
@Bean(name = "utilisateurDao")
public UtilisateurDAO getUtilisateurDao(SessionFactory sessionFactory) {
return new UtilisateurDAOImpl(sessionFactory);
}
}
我们可以通过这种方式在这个class中获取request
对象:
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
那么有没有办法获取 session
( HttpSession ) 对象?
使用控制器类
您可以将 HttpSession
定义为控制器方法的参数:
@RequestMapping("/my-path")
public String doStuff(HttpSession session) {
// do stuff...
}
这也是访问 HttpRequest
的推荐方式,而不是通过 RequestContextHolder
,因为模拟会话以进行测试更容易。
见the Spring MVC docs for more detail.
不使用控制器类
另一种选择是使用 @SessionScope
bean 并相应地改变它:
@Component
@SessionScope
public class MySessionScopedBean {
String attribute;
}
public class MyOtherClass {
@Autowired
private MySessionScopedBean myBean;
public void doStuff() {
// myBean accesses a bean instance isolated in the user session
myBean.attribute = "test";
}
}
如果您想在控制器方法之外访问 HttpSession,有两种可能的答案:
- 不要这样做,这是邪恶的。
如果你真的真的很想做(我以前也做过,我又能怪谁),那么最简单的方法就是写一个class来保持会话,以及一个拦截器来设置和取消设置它。但为了让事情更简单,我将使用 HttpServletRequest 对象,您可以从中提取会话:
public class RequestHolder {
private static final ThreadLocal<HttpServletRequest> REQUEST =
new ThreadLocal<>();
public static HttpServletRequest getCurrentRequest() {
return REQUEST.get();
}
public static HttpSession getCurrentSession() {
HttpServletRequest request = REQUEST.get();
return request == null ? null : request.getSession();
}
public static void setCurrentRequest(HttpServletRequest request) {
REQUEST.set(request);
}
public static void unsetCurrentRequest() {
REQUEST.remove();
}
}
public class RequestHolderInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
RequestHolder.setCurrentRequest(request);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView mav) {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e){
RequestHolder.unsetCurrentRequest();
}
}
有一个 class :
@Configuration
@ComponentScan("com.ambre.pta")
@EnableTransactionManagement
@PropertySources({
@PropertySource("classpath:fr/global.properties"),
@PropertySource("classpath:fr/main.properties"),
@PropertySource("classpath:fr/admin.properties"),
@PropertySource("classpath:fr/referentiel.properties"),
@PropertySource("classpath:fr/departement.properties"),
@PropertySource("classpath:fr/exercice.properties"),
@PropertySource("classpath:fr/defi.properties")
})
public class ApplicationContextConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean(name = "dataSource")
public DataSource getDataSource() {
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
bds.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
bds.setUsername("pta");
bds.setPassword("pta");
return bds;
}
@Autowired
@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.scanPackages("com.ambre.pta.model");
return sessionBuilder.buildSessionFactory();
}
@Autowired
@Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
@Autowired
@Bean(name = "utilisateurDao")
public UtilisateurDAO getUtilisateurDao(SessionFactory sessionFactory) {
return new UtilisateurDAOImpl(sessionFactory);
}
}
我们可以通过这种方式在这个class中获取request
对象:
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
那么有没有办法获取 session
( HttpSession ) 对象?
使用控制器类
您可以将 HttpSession
定义为控制器方法的参数:
@RequestMapping("/my-path")
public String doStuff(HttpSession session) {
// do stuff...
}
这也是访问 HttpRequest
的推荐方式,而不是通过 RequestContextHolder
,因为模拟会话以进行测试更容易。
见the Spring MVC docs for more detail.
不使用控制器类
另一种选择是使用 @SessionScope
bean 并相应地改变它:
@Component
@SessionScope
public class MySessionScopedBean {
String attribute;
}
public class MyOtherClass {
@Autowired
private MySessionScopedBean myBean;
public void doStuff() {
// myBean accesses a bean instance isolated in the user session
myBean.attribute = "test";
}
}
如果您想在控制器方法之外访问 HttpSession,有两种可能的答案:
- 不要这样做,这是邪恶的。
如果你真的真的很想做(我以前也做过,我又能怪谁),那么最简单的方法就是写一个class来保持会话,以及一个拦截器来设置和取消设置它。但为了让事情更简单,我将使用 HttpServletRequest 对象,您可以从中提取会话:
public class RequestHolder { private static final ThreadLocal<HttpServletRequest> REQUEST = new ThreadLocal<>(); public static HttpServletRequest getCurrentRequest() { return REQUEST.get(); } public static HttpSession getCurrentSession() { HttpServletRequest request = REQUEST.get(); return request == null ? null : request.getSession(); } public static void setCurrentRequest(HttpServletRequest request) { REQUEST.set(request); } public static void unsetCurrentRequest() { REQUEST.remove(); } } public class RequestHolderInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) { RequestHolder.setCurrentRequest(request); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView mav) { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e){ RequestHolder.unsetCurrentRequest(); } }