今天有一个朋友问了我一个问题,他使用的是Hibernate/Spring/Struts架构,配置使用Spring的 OpenSessionInView Filter,但是发现不生效,lazy的集合属性在页面访问的时候仍然报session已经关闭的错误。我和他一起检查了所有的配置和相关的代码,但是 没有发现任何问题。经过调试发现,应用程序使用的Session和OpenSessionInView Filter打开的Session不是同一个,所以OpenSessionInView模式没有生效,但是为什么他们不使用同一个Session呢?
检查了一遍Spring的相关源代码,发现了问题的根源:
通常在Web应用中初始化Spring的配置,我们会在web.xml里面配置一个Listener,即:
xml代码:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
如果使用Struts,那么需要在Struts的配置文件struts-config.xml里面配置一个Spring的plugin:ContextLoaderPlugIn。
实 际上ContextLoaderListener和ContextLoaderPlugIn的功能是重叠的,他们都是进行Spring配置的初始化工作 的。因此,如果你不打算使用OpenSessionInView,那么你并不需要在web.xml里面配置ContextLoaderListener。
好了,但是你现在既需要Struts集成Spring,又需要OpenSessionInView模式,问题就来了!
由于 ContextLoaderListener和ContextLoaderPlugIn功能重叠,都是初始化Spring,你不应该进行两次初始化,所以 你不应该同时使用这两者,只能选择一个,因为你现在需要集成Struts,所以你只能使用ContextLoaderPlugIn。
但是令人困惑的是,ContextLoaderListener和ContextLoaderPlugIn有一个非常矛盾的地方!
ContextLoaderListener初始化spring配置,然后把它放在ServletContext对象里面保存:
java代码:
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
请注意,保存的对象的key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE!
但是ContextLoaderPlugIn初始化spring配置,然后把它放在ServletContext对象里面保存:
java代码:
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
这个attrName和WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE名字是不一样的!
如果仅仅是名字不一样,问题还不大,你仍然可以放心使用ContextLoaderPlugIn,但是当你使用OpenSessionInView的时候,OpenSessionInViewFilter是使用哪个key取得spring配置的呢?
java代码:
WebApplicationContext wac =
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
显然,OpenSessionInViewFilter是按照WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE这个key去拿spring配置的!
我们整理一下思路:
ContextLoaderPlugIn保存spring配置的名字叫做attrName;
,ContextLoaderListener保存spring配置的名字叫做WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
而OpenSessionInView是按照WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE这个名字去取得spring配置的!
而你的应用程序却是按照attrName去取得spring的配置的!
所以,OpenSessionInView模式失效!
解决办法:
修改ContextLoaderPlugIn代码,在getServletContext().setAttribute(attrName, wac);这个地方加上一行代码:
getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
或者修改OpenSessionInViewFilter,让它按照attrName去取得spring配置。
——————————————————————————————————————————————————————
同时使用ContextLoaderListener和ContextLoaderPlugIn,但是不 要在ContextLoaderPlugIn里面加入applicationContext.xml,只要加入你的action- servlet.xml,我相信,同样也可以非常流畅的使用OpenSessionInView
整个配置如下:
1.首先是web.xml
java代码:
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
......
2. 然后是struts-config.xml:
java代码:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/action-servlet.xml"
/>
</plug-in>
http://hi.baidu.com/anypcao/blog/item/22a76a1e217c43fd1bd576b2.html
分享到:
相关推荐
介绍Spring+hibernate opensessioninview问题
为了练手培训,给大家准备的 Open...3.通过 open session in view filter 支持 延迟加载 4.在页面上通过 jstl 很优雅的获取数据 5.通过 spring aop(aspectJ) 声明事务 6.通过formular 映射参数表,指定两个死的变量
OpenSessionInView项目整合jar包
Spring提供的CharacterEncoding和OpenSessionInView功能
在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要在应用层内把关系集合都初始化,如 company.getEmployees(),否则Hibernate抛...
SSH项目整合示例【OpenSessionInView】所用到的jar包 包含Struts + Hibernate + Spring所有jar及其依赖的jar
NULL 博文链接:https://8366.iteye.com/blog/472141
NULL 博文链接:https://likenice.iteye.com/blog/290162
<filter-name>OpenSessionInView</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>...
NULL 博文链接:https://yanzhenwei.iteye.com/blog/1701164
和Spring中OpenSessionInView由于org.springframework.web.struts.ContextLoaderPlugIn中保存同一个对象的名不同导致openSessionInView失效 稍微修改后在struts-config.xml中使用MyContextLoaderPlugIn.jar包中...
SSH项目整合示例【OpenSessionInView】源码
最新版SSH项目整合 实现了OpenSessionInView。 hibernate5.2.3+struts2.5.2+spring4.3.3
spring2.5学习PPT 传智博客 01_全面阐释Spring及其各项功能 ... 30.Spring提供的CharacterEncoding和OpenSessionInView功能 31.使用Spring集成JPA 32.Struts+Spring+JPA集成 33.使用Spring集成Struts2 34.所有源码
使用 AOC 拦截器而不是过滤器进行 OpenSessionInView 处理 列出一个国家的城市和添加城市的可能性(bean 验证和自动检索 lat 和 lng 坐标) 安全 安全的 REST Web 服务 使用 CSRF 令牌 角度父状态的问题 有用的链接 ...
Spring的Ioc Spring的AOP , AspectJ Spring的事务管理 , 三大框架的整合 目录 1.1 Spring 框架学习路线:..........................................................................................................