【问题标题】:Sending information from a servlet back to a Filter将信息从 servlet 发送回过滤器
【发布时间】:2017-12-22 12:38:14
【问题描述】:

我有一个在 Tomcat 7 上运行的旧 Web 应用程序,它使用过滤器提供的非常基本的 open-session-in-view 机制:

@Override public void doFilter (ServletRequest req, ServletResponse resp, FilterChain fc) 
    throws IOException, ServletException 
{
    try {
        HibernateUtil.beginTransaction();
        fc.doFilter(req, resp);
        HibernateUtil.commitTransaction();
    } catch (Throwable t) {
        Logger.exception(t, "processing servlet request");
        HibernateUtil.rollbackTransaction();
        throw new ServletException(t);
    }
}

我现在坚持这一点,我认为我遇到了 OSIV(或至少它的这种实现)的众多缺陷之一,即我现在希望能够回滚事务,甚至 没有抛出异常。我希望 servlet 能够控制它,而且我认为我别无选择,只能以某种方式破解此功能。

我的问题是:我怎样才能将某种“回滚”标志从任意 servlet 传回这个过滤器?我希望能够在过滤器中做这样的事情:

HibernateUtil.beginTransaction();
fc.doFilter(req, resp);
if (/* something that was set by a servlet/jsp */)
    HibernateUtil.rollbackTransaction();
else
    HibernateUtil.commitTransaction();

我不太确定将此类信息从 servlet 传播回此过滤器的可靠方法是什么。

【问题讨论】:

  • 请求属性或其他一些线程本地值。
  • @SotiriosDelimanolis 嗯,这很容易。亲爱的,谢谢。

标签: java servlets tomcat7 servlet-filters


【解决方案1】:

我不建议使用请求属性或线程局部变量,它们存在以下问题:

  1. 您的交易依赖于设置标志的其他人。如果你在银行工作,我真的不想成为那里的客户。
  2. 如果您不清理线程本地存储,则会导致资源泄漏。
  3. 如果不在线程本地存储之间手动复制内容,您将无法编写多线程代码。
  4. 如果使用请求属性,您必须在 Servlet 中提取值并一直传递给您的 DAO,假设您使用的是通用的多层架构。

相反,您可以简单地从 Hibernate 会话对象中获取当前事务并要求它回滚。 Session.getTransaction().rollback()。最好,废弃该代码或找到编写代码的人并要求退款。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-21
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    相关资源
    最近更新 更多