views:

61

answers:

5

Is there a way to attach to events like asp.net's "Application_Start" and "Begin_Request" in Java/Tomcat/JSP web projects? I would really rather not use JSF or an extra framework(Spring, Struts). I do not want to do it on a per-page basis with anything like 'jspInit', a global event handler is the goal.

In the event that I am stuck in the .net way of doing things, the point is to have a central place to initialize IoC containers (Application_Start), and implement a 'One database transaction per request' workflow (Begin_Request).

Thanks.

+1  A: 

http://download.oracle.com/javaee/5/api/javax/servlet/Filter.html for handling requests

I think in the end you will have better luck and code that is more maintainable if you investigate frameworks that could solve lots of your problems for you

Aaron Saunders
It probably, would be better, but there are a few reasons why I can not. First, I really don't like the popular frameworks for java. Second, in the end this is for an undergraduate class in which I have to manage a team of 3-4 other students who have no experience with web applications, so I dont want to throw in an extra framework, which I would be responsible for teaching.
jdc0589
+1  A: 

To do something at "application start" you need to implement a ServletContextListener. It is part of the standard servlet API. As someone else already mentioned, you can implement one or more filters in a "filter chain" to do special processing before each incoming request is handled by the servlets.

Jim Tough
+4  A: 

In the Java EE (Servlets+JSPs) world, the equivalent functionality can be obtained by implementing the relevant interfaces standardized by the Java EE specification.

The equivalent of the Application concept is the Web Context or the Servlet context. Sessions and Requests are the same concept in Java EE as .Net. There are relevant listener classes that need to be implemented in order to hook onto the relevant events in

  • the lifecyle of an application (ServletContextListener and ServletContextAttributeListener),
  • requests served by the application (ServletRequestListener and ServletRequestAttributeListener) or
  • sessions established by the same (HttpSessionListener and HttpSessionActivationListener).

More information on this can be found in the Java EE 5 tutorial on the Servlet lifecycle. The interfaces continue to hold good for Java EE 6 as well.

Filters vs ServletRequestListener

If you've read the comments, you would have noticed that it is possible to do preprocessing and postprocessing of requests by implementing a ServletRequestListener or a Filter.

I would suggest that you utilize Filters (as did BalusC). This is because the Filter will be invoked everytime a request is sent to a particular URL, and is often the most effective way of ensuring that all requests to a URL receive the same 'treatment'.

The reasons for this are found in the Java EE API documentation on the ServletRequestListener:

Interface for receiving notification events about requests coming into and going out of scope of a web application.

A ServletRequest is defined as coming into scope of a web application when it is about to enter the first servlet or filter of the web application, and as going out of scope as it exits the last servlet or the first filter in the chain.

When you use a ServletRequestListener, you must note that the requestInitialized and requestDestroyed events are fired only once per request (unlike the Filter where the doFilter method is invoked everytime the Filter is invoked in a processing pipeline). Since Filters are the usual way of performing actions before and after requests (I haven't seen a lot of people use ServletRequestListeners), I would suggest that you utlize filters in such a context.

Vineet Reynolds
Addendum: what a `ServletRequestListener` does can also be done with a `Filter` whenever you want to hook on more specific URL's (e.g. when you want to ignore requests on static files).
BalusC
@BalusC, you're right. I'm pondering over when to use each; surely one of them can't be redundant. Will update the answer when I arrive at the conclusion for the same.
Vineet Reynolds
Another reason to choose a filter is that you can change the request and/or response, however this is not needed for "one transaction per request" requirement in the question.
BalusC
@BalusC, exactly. I just needed a general listener. Already hooked it up and its working great.
jdc0589
Also, somewhere (maybe not here) it was mentioned that requestInitialized is only called for requests to a dynamic resource, which apparently is NOT correct. Unless I manually check, it gets fire more often than just for .jsp requests.
jdc0589
@jdc: you may then consider to use a `Filter` mapped on `*.jsp` instead.
BalusC
@jdc, a JSP gets translated into a servlet (either through pre-compilation or at runtime before the first request is served), so the definition of a dynamic resource would include servlets and JSPs. After all, requests to either of them will involve creation of a HttpServletRequest object. So you could use the RequestListener to listen for all requests, whereas Filters could be used for very specific ones.
Vineet Reynolds
+1  A: 

There are "similar" events (event is not the best word for this) available in the Servlet API. For application start you should use a Context listener http://download.oracle.com/javaee/5/api/javax/servlet/ServletContextListener.html
and for requests: http://download.oracle.com/javaee/5/api/javax/servlet/ServletRequestListener.html

Mondain
+1  A: 

Servlets give you more when it comes to this issue. And in Java world, events are called listeners. There are some useful listeners:

javax.servlet.ServletContextListener

void contextDestroyed(ServletContextEvent sce) Called when the servlet context is about to be destroyed.

void contextInitialized(ServletContextEvent sce) Called when the web application is ready to process requests.

javax.servlet.ServletContextAttributeListener

void attributeAdded(ServletContextAttributeEvent scae) Called when a new attribute is added to the servlet context.

void attributeRemoved(ServletContextAttributeEvent scae) Called when an attribute is removed from the servlet context.

void attributeReplaced(ServletContextAttributeEvent scae) Called when an attribute on the servlet contextis replaced.

javax.servlet.http.HttpSessionListener

void sessionCreated(HttpSessionEvent se) Called when a session is created.

void sessionDestroyed(HttpSessionEvent se) Called when a session is invalidated.

javax.servlet.http.HttpSessionAttributeListener

void attributeAdded(HttpSessionBindingEvent se) Called when an attribute is added to a session.

void attributeRemoved(HttpSessionBindingEvent se) Called when an attribute is removed from a session.

void attributeReplaced(HttpSessionBindingEvent se) Called when an attribute is replaced in a session.

Truong Ha