`

OpenSessionInView Filter 但是发现不生效(转载)

阅读更多

今天有一个朋友问了我一个问题,他使用的是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

    ### Spring + Hibernate OpenSessionInView 模式的理解和应用 在Java Web开发中,Spring与Hibernate作为两个重要的框架,经常被一起使用来实现业务逻辑与数据持久化的处理。而在使用这两个框架时,为了更好地管理...

    Struts Spring Hibernate 整合 OpenSessionInView 例子

    为了练手培训,给大家准备的 Open...3.通过 open session in view filter 支持 延迟加载 4.在页面上通过 jstl 很优雅的获取数据 5.通过 spring aop(aspectJ) 声明事务 6.通过formular 映射参数表,指定两个死的变量

    Open_Session_In_View详解.doc

    &lt;filter-class&gt;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter&lt;/filter-class&gt; &lt;param-name&gt;singleSession &lt;param-value&gt;true &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;...

    OpenSessionInView项目整合jar包

    在Java Web开发中,OpenSessionInView(OSIV)模式是一种常见的解决数据持久化问题的设计模式,主要用于Spring框架与Hibernate等ORM工具的集成。这个模式的主要目的是解决在HTTP请求处理过程中,由于Session范围内的...

    Spring提供的CharacterEncoding和OpenSessionInView功能

    Spring框架是Java开发中不可或缺的一部分,它为开发者提供了丰富的功能,包括依赖注入、面向切面编程、事务管理等。在处理Web应用时,Spring提供了一些关键特性,如`CharacterEncodingFilter`和`...

    第30讲--Spring提供的CharacterEncoding和OpenSessionInView功能

    同时,需要注意的是,OpenSessionInView模式虽然方便,但也会带来潜在的问题,如事务边界不清晰和会话泄漏。因此,在实际应用中,应结合具体需求谨慎使用,并考虑使用更现代的解决方案,如Spring Data JPA的...

    SSH项目整合示例【OpenSessionInView】所用到的jar包

    在实际项目中,还需要在web.xml中配置DispatcherServlet、Struts2的Filter以及Spring的ContextLoaderListener。同时,需要编写相关的配置文件,如struts.xml、hibernate.cfg.xml、applicationContext.xml,以完成各...

    spring中lazy=“true”的正常读取关联表(用opensessioninview)

    4. **错误隐蔽**:由于延迟加载在视图渲染阶段才执行,一些本应在业务逻辑中发现的错误可能会被延迟暴露。 `数据库.txt` 和 `osiv` 这两个文件名可能是与数据库操作和OSIV模式相关的资料。`数据库.txt` 可能包含了...

    SSH全注解环境搭建

    &lt;filter-name&gt;openSessionInView&lt;/filter-name&gt; &lt;filter-class&gt;org.springframework.orm.hibernate5.support.OpenSessionInViewFilter&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;...

    configuration

    &lt;filter-name&gt;openSessionInView&lt;/filter-name&gt; &lt;filter-class&gt;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter&lt;/filter-class&gt; &lt;!--...--&gt; &lt;/filter&gt; ``` 此过滤器保持一个打开的Hibernate ...

    ssh配置总结

    &lt;filter-name&gt;openSessionInView&lt;/filter-name&gt; &lt;filter-class&gt;org.springframework.orm.hibernate5.support.OpenSessionInViewFilter&lt;/filter-class&gt; &lt;param-name&gt;sessionFactoryBeanName &lt;param-value&gt;...

    SSH整合文档

    2. **OpenSessionInView模式**: 为了防止Session在请求结束后关闭导致数据丢失,我们可以使用`OpenSessionInViewFilter`。这个过滤器在每次请求开始时打开Session,结束时关闭,保证在整个视图渲染过程中Session都是...

    struts2+hibernate+spring

    &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt; &lt;param-name&gt;encoding &lt;param-value&gt;UTF-8 &lt;/filter&gt; &lt;!-- Hibernate OpenSessionInView 过滤器 --&gt; &lt;filter&gt; ...

    SSH搭建详细步骤

    这些JAR包通常包括但不限于: - Struts2核心库(例如struts2-core-x.x.x.jar)。 - Spring框架的核心库(例如spring-context-x.x.x.jar)。 - Hibernate的核心库(例如hibernate-core-x.x.x.jar)。 - 其他依赖...

    关于OpenSessionInViewFilter的学习

    然而,当我们在服务层关闭了Session后,到视图层进行数据填充时,可能会遇到已关闭的Session导致的数据不可用问题。OpenSessionInViewFilter就是为了缓解这一问题而设计的。 该过滤器的核心思想是在用户的HTTP请求...

    OA项目SSH整合框架

    &lt;filter-name&gt;OpenSessionInView&lt;/filter-name&gt; &lt;filter-class&gt;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;...

    SSH框架整合小册子

    5. **OpenSessionInView模式** - 修改`HibernateSessionFactory.java`,实现线程局部变量存储事务对象。 - 实现`beginTransaction`、`commitTransaction`、`rollbackTransaction`等方法,确保在每次请求结束时关闭...

    MyContextLoaderPlugIn.jar

    和Spring中OpenSessionInView由于org.springframework.web.struts.ContextLoaderPlugIn中保存同一个对象的名不同导致openSessionInView失效 稍微修改后在struts-config.xml中使用MyContextLoaderPlugIn.jar包中...

    struts+spring+hibernate面试题

    - `openSessionInView`模式是在Web层使用Filter打开和关闭Session,确保每个HTTP请求都有一个活跃的Session,以支持延迟加载。 6. Spring的事务管理: - 有两种方式:声明式事务(基于注解或XML配置)和编程式...

    java并发编程实践笔记资料.pdf

    17. 单一不可变对象往往是线程安全的,但是复杂不可变对象需要保证其内部成员变量也是不可变的。 18. 良好的多线程编程习惯是:将所有的域都声明为final,除非它们是可变的。 19. 保证共享变量的发布是安全的,...

Global site tag (gtag.js) - Google Analytics