【问题标题】:Event like .net's "Application_Start" and "Begin_Request" for java/tomcat/JSP?java/tomcat/JSP 的 .net 的“Application_Start”和“Begin_Request”之类的事件?
【发布时间】:2011-04-09 11:25:14
【问题描述】:

有没有办法在 Java/Tomcat/JSP Web 项目中附加到诸如 asp.net 的“Application_Start”和“Begin_Request”之类的事件?我真的宁愿不使用 JSF 或额外的框架(Spring、Struts)。我不想在每页的基础上使用“jspInit”之类的东西,目标是全局事件处理程序。

如果我被困在 .net 的做事方式中,关键是要有一个中心位置来初始化 IoC 容器 (Application_Start),并实现“每个请求一个数据库事务”工作流 (Begin_Request)。

谢谢。

【问题讨论】:

    标签: java jsp tomcat servlets page-lifecycle


    【解决方案1】:

    在Java EE(Servlets+JSPs)的世界里,通过实现Java EE规范标准化的相关接口,可以获得等价的功能。

    Application 概念的等价物是 Web Context 或 Servlet 上下文。会话和请求在 Java EE 中的概念与 .Net 相同。有一些相关的监听器类需要被实现以便挂钩到

    中的相关事件
    • 应用程序的生命周期(ServletContextListenerServletContextAttributeListener),
    • 应用程序服务的请求(ServletRequestListenerServletRequestAttributeListener)或
    • 由相同的会话建立(HttpSessionListenerHttpSessionActivationListener)。

    更多信息请参见Java EE 5 tutorial on the Servlet lifecycleJava EE 6 的接口仍然适用。

    过滤器与 ServletRequestListener

    如果您阅读过 cmets,您会注意到可以通过实现 ServletRequestListenerFilter 对请求进行预处理和后处理。

    我建议您使用Filters(就像 BalusC 一样)。这是因为每次向特定 URL 发送请求时都会调用 Filter,这通常是确保对 URL 的所有请求都得到相同“处理”的最有效方法。

    原因可在ServletRequestListener 上的 Java EE API 文档中找到:

    接收通知的接口 关于请求进入和 超出网络范围 应用。

    一个 ServletRequest 被定义为 进入 Web 应用程序的范围时 即将进入第一个 servlet 或 Web 应用程序的过滤器,以及 当它退出时超出范围 最后一个 servlet 或第一个过滤器 链条。

    当您使用 ServletRequestListener 时,您必须注意 requestInitializedrequestDestroyed 事件在每个请求中只触发一次(与 Filter 不同,其中 Filter 时都会调用>doFilter 方法)。由于过滤器是在请求之前和之后执行操作的常用方式(我没有看到很多人使用 ServletRequestListeners),我建议您在这种情况下使用过滤器。

    【讨论】:

    • 附录:ServletRequestListener 所做的事情也可以通过 Filter 来完成,只要您想挂接更具体的 URL(例如,当您想忽略对静态文件的请求时)。
    • @BalusC,你是对的。我正在考虑何时使用它们;当然其中之一不能是多余的。当我得出相同的结论时会更新答案。
    • 选择过滤器的另一个原因是您可以更改请求和/或响应,但是问题中的“每个请求一个事务”要求不需要这样做。
    • @BalusC,确切地说。我只需要一个普通的听众。已经把它连接起来了,效果很好。
    • 另外,在某处(可能不在此处)提到 requestInitialized 仅在对动态资源的请求时调用,这显然是不正确的。除非我手动检查,否则它会比 .jsp 请求更频繁地触发。
    【解决方案2】:

    当涉及到这个问题时,Servlet 可以为您提供更多信息。在 Java 世界中,事件被称为监听器。有一些有用的监听器:

    javax.servlet.ServletContextListener

    void contextDestroyed(ServletContextEvent sce) 在 servlet 上下文即将被销毁时调用。

    void contextInitialized(ServletContextEvent sce) 在 Web 应用程序准备好处理请求时调用。

    javax.servlet.ServletContextAttributeListener

    void attributeAdded(ServletContextAttributeEvent scae) 在将新属性添加到 servlet 上下文时调用。

    void attributeRemoved(ServletContextAttributeEvent scae) 从 servlet 上下文中删除属性时调用。

    void attributeReplaced(ServletContextAttributeEvent scae) 在 servlet 上下文中的属性被替换时调用。

    javax.servlet.http.HttpSessionListener

    void sessionCreated(HttpSessionEvent se) 在创建会话时调用。

    void sessionDestroyed(HttpSessionEvent se) 在会话无效时调用。

    javax.servlet.http.HttpSessionAttributeListener

    void attributeAdded(HttpSessionBindingEvent se) 在将属性添加到会话时调用。

    void attributeRemoved(HttpSessionBindingEvent se) 从会话中删除属性时调用。

    void attributeReplaced(HttpSessionBindingEvent se) 在会话中替换属性时调用。

    【讨论】:

      【解决方案3】:

      在 Servlet API 中有可用的“相似”事件(事件不是最好的词)。对于应用程序启动,您应该使用上下文侦听器 http://download.oracle.com/javaee/5/api/javax/servlet/ServletContextListener.html
      对于请求: http://download.oracle.com/javaee/5/api/javax/servlet/ServletRequestListener.html

      【讨论】:

        【解决方案4】:

        要在“应用程序启动”处执行某些操作,您需要实现 ServletContextListener。它是标准 servlet API 的一部分。正如其他人已经提到的,您可以在“过滤器链”中实现一个或多个过滤器,以便在每个传入请求由 servlet 处理之前进行特殊处理。

        【讨论】:

          【解决方案5】:

          http://download.oracle.com/javaee/5/api/javax/servlet/Filter.html 用于处理请求

          我认为,如果您研究可以为您解决许多问题的框架,那么最终您将拥有更好的运气和更易于维护的代码

          【讨论】:

          • 它可能会更好,但有几个原因我不能。首先,我真的不喜欢流行的 java 框架。其次,最后这是一个本科班,我必须管理一个由 3-4 名其他没有 Web 应用程序经验的学生组成的团队,所以我不想投入额外的框架,我将负责教学。
          猜你喜欢
          • 2010-10-28
          • 1970-01-01
          • 1970-01-01
          • 2012-02-06
          • 2019-05-08
          • 1970-01-01
          • 2011-01-04
          • 1970-01-01
          • 2011-08-10
          相关资源
          最近更新 更多