tl;dr:
How do I get the ServletResponse during ServletRequestListener.requestDestroyed?
Short Version
In JavaEE, I want to know when:
- when a request starts
- and when a request ends
and be able to inspect the request and response objects.
Long Version
In the ASP.NET world, if you want to know when a request starts and ends, you write an IHttpModule
:
public class ExampleModuleForThisQuestion : IHttpModule
{
}
And then register your "module" in the web XML configuration file:
web.config:
<system.webServer>
<modules>
<add name="DoesntMatter" type="ExampleModuleForThisQuestion "/>
</modules>
</system.webServer>
Inside your module, you can register callback handlers for:
- BeginRequest event
- EndRequest event
The web server infrastructure then calls you Init
method. That is your opportunity to register that you want to receive notifications when a request starts, and when a request ends:
public class ExampleModuleForThisQuestion : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(beginRequest); //register the "BeginRequet" event
application.EndRequest += new EventHandler(endRequest); //register the "EndRequest" event
}
}
And now we have our callbacks when a request starts:
private void beginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
//Record the time the request started
application.Context.Items["RequestStartTime"] = DateTime.Now;
//We can even access the Request and Response objects
application.ContenxtLog(application.Context.Request.Headers["User-Agent"]);
}
And we have our callback when a request ends:
private void endRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
//We can even access the Request and Response objects
//Get the response status code (e.g. 418 I'm a teapot)
int statusCode = application.Context.Response.StatusCode;
//Get the request method (e.g. GET, POST, BREW)
String method = application.context.Request.RequestType;
//Get the path from the request (e.g. /ViewCustomer)
String path = application.context.Request.AppRelativeCurrentExecutionFilePath'
//Get when the request started - that we recorded during "Begin Request"
DateTime requestStartTime = (DateTime)application.Context.Items["RequestStartTime"];
//And we can modify the response
if ((DateTime.Now - requestStartTime).TotalSeconds = 17)
application.Context.Response.StatusCode = 451;
}
The Java Almost-Equivalent is ServletRequestListener
In Java, apparently the corresponding technique is to create and object that implements the ServletRequestListener interface:
@WebListener
public class ExampleListenerForThisQuestion
implements javax.servlet.ServletRequestListener {
}
and register our listener with the application server by including it in our web XML configuration file:
web.xml
<listener>
<listener-class>ExampleListenerForThisQuestion</listener-class>
</listener>
Now we can implement the requestInitialized and requestDestroyed methods to get when a request starts and ends:
public class ExampleListenerForThisQuestion
implements javax.servlet.ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
ServletRequest sr = sre.getServletRequest();
sr.setAttribute("requestStartTicks", getCurrentTickCount());
HttpServletRequest request = (HttpServletRequest) sr;
// e.g. "PUT /Customers/1234"
System.out.printf("%s %s\r\n", request.getMethod());
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
ServletRequest sr = sre.getServletRequest();
long requestStartTicks = (long)sr.getAttribute("requestStartTicks");
HttpServletResponse response = (HttpServletRequest)...nothing, because i don't know how...
// e.g. "226 IM Used"
System.out.printf("%d %s\r\n", response.getStatus(), response.getStatusDescription());
}
}
But how do we get the response?
Now that I'm notified when the response ends, I need the result of that request:
- I need the HTTP status code (e.g., 424)
- I need the HTTP status description (e.g., Failed Dependency)
- I need to inspect response headers
- I need to modify response headers
You notice the line in my code above:
HttpServletResponse response = (HttpServletRequest)...nothing, because i don't know how...
How can I get hold of the response?