摘自孔浩视频 spring部分-17_spring_SSH整合02_OpenSessionInViewer的讲解
思路就是创建一个filter,这个filter在视图请求的过程中获取到Spring所管理的SessionFactory对象。 这样便解决了视图层Session无法获取的问题。
[b]1. 首先创建一个OpenSessionFilter.java[/b]
OpenSessionFilter
[b]2. 在web.xml中配置filter[/b]
[color=orange]Note[/color]: 注意这里如果使用的是struts2, 那么struts2的url-pattern也是/*,所有的请求都会被struts2的拦截器拦截, 这个filter也就不会起作用了。
因此必须要将这个filter的配置放在Struts2的前面,才能正常使用。
这时就可以在Dao层调用这个类来获取Session,例如:
这样web容器便会在视图层中获取Session,并执行相应的Session操作。
==========================
Spring已经提供了OpenSessionInViewerFilter, 一般直接配置Spring的就可以了。
思路就是创建一个filter,这个filter在视图请求的过程中获取到Spring所管理的SessionFactory对象。 这样便解决了视图层Session无法获取的问题。
[b]1. 首先创建一个OpenSessionFilter.java[/b]
OpenSessionFilter
package com.lj.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class OpenSessionFilter implements Filter {
//Spring的工厂,在init中获取
private WebApplicationContext wac;
private static SessionFactory factory;
private static ThreadLocal<Session> sessionHolder=new ThreadLocal<Session>();
private static void setSession(Session session){
sessionHolder.set(session);
}
public static Session getSession(){
return sessionHolder.get();
}
private static void removeSession(){
sessionHolder.remove();
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
/**
* 在这里获取Spring的工厂信息,在init里面就只会执行一次
* 使用WebApplicationContextUtils.getWebApplicationContext(ServletContext)来获取Web中的Spring工厂。
* 这种手段非常重要,要熟悉
*/
wac=WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
//我们在beans.xml中定义的sessionFactory <bean id="sessionFactory">
factory=(SessionFactory) wac.getBean("sessionFactory");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
//开启session
System.out.println("begin");
/** 要获取SessionFactory,需要先获取Spring的工厂
* 如果使用new ClassPathXmlApplicationContext(),就会产生一个新工厂,和Servlet初始化时的工厂是两个对象
* 必须通过其他方法来获取
* 在Spring中可以通过Web
*/
//这里不能用getCurrentSession,要用openSession()
try {
setSession(factory.openSession());
chain.doFilter(req, res);
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//关闭session
System.out.println("back");
}
@Override
public void destroy() {
}
}
[b]2. 在web.xml中配置filter[/b]
<filter>
<filter-name>mySessionInViewerFilter</filter-name>
<filter-class>com.lj.filter.OpenSessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>mySessionInViewerFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[color=orange]Note[/color]: 注意这里如果使用的是struts2, 那么struts2的url-pattern也是/*,所有的请求都会被struts2的拦截器拦截, 这个filter也就不会起作用了。
因此必须要将这个filter的配置放在Struts2的前面,才能正常使用。
这时就可以在Dao层调用这个类来获取Session,例如:
public List<Group> list() {
// TODO Auto-generated method stub
//return this.getSession().createQuery("from Group").list();
return OpenSessionFilter.getSession().createQuery("from Group").list();
}
这样web容器便会在视图层中获取Session,并执行相应的Session操作。
==========================
Spring已经提供了OpenSessionInViewerFilter, 一般直接配置Spring的就可以了。
<filter>
<filter-name>openSessionInViewerFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInViewerFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>