You would not need to read HTTP headers so frequently during the development of your Java EE web modules. You aren't probably writing servlets any longer. Nevertheless, it might happen one day that you need to explore what's there, inside the HTTP headers that go to your servlet or your JSP. That's easy enough, though: just use the getHeader method (and its brothers) of the HttpServletRequest interface.
But if you're using HTTP headers you're not moving information to be used by the business logic. At least, I hope you don't. That's why you might also be interested in not polluting your business logic (servlets' code, JSPs' and so on). The solution to such problems may be a filter, as specified in the Java Servlet Specification, chapter SRV.6.
What's a filter?
Good question, that's why the servlet specification is there! Filters interpose during the call to a web resource between the client and the resource itself and the container executes them before the resource is invoked. With a filter you could, for example:- Intercept a call to a web resource to perform logic which is orthogonal to the code into the resource itself.
- Modify the request content before it gets accessed by the web resource.
- Deny access to the resource, by redirecting the user to another resource or by launching an exception.
As far as it concerns the code, a filter is a class which implements the javax.servlet.Filter interface. There clearly are two life-cycle management methods:
- init(FilterConfig fc)
- destroy()
- doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
Coding the filter
Coding the init and destroy methods.
Coding the init and the destroy methods is straightforward, unless you really put logic in them, such as custom filter configuration, external resources initialization and so on. A basic implementation for these method is the following:public void destroy() {
Coding the filter logic
That's pretty straightforward, too. Maybe the only thing you should remember is just... invoking the other filters in the chain. That's why the method signature has that FilterChain in it. This is NetBeans' doFilter prototypeFilterChain chain)
throws IOException, ServletException {
if (debug) {
log("DPErrorFilter:doFilter()");
}
doBeforeProcessing(request, response);
Throwable problem = null;
try {
chain.doFilter(request, response);
} catch (Throwable t) {
// If an exception is thrown somewhere down the filter chain,
// we still want to execute our after processing, and then
// rethrow the problem after that.
problem = t;
t.printStackTrace();
}
doAfterProcessing(request, response);
// If there was a problem, we want to rethrow it if it is
// a known type, otherwise log it.
if (problem != null) {
if (problem instanceof ServletException) {
throw (ServletException) problem;
}
if (problem instanceof IOException) {
throw (IOException) problem;
}
sendProcessingError(problem, response);
}
}
Reading HTTP headers
The last piece of code you miss is the logic itself. Here it is:throws IOException, ServletException {
if (debug) {
log("DPErrorFilter:DoBeforeProcessing");
}
// wrapping the servlet request
if (!(request instanceof HttpServletRequest)) {
log("Request isn't an instance of HttpServletRequest, skipping...");
return;
}
HttpServletRequestWrapper req =
// read your headers here
The only trick here is wrapping your ServletRequest (which lacks HTTP-related functionality) parameter into an HttpServletWrapper. I also do an instanceof check before doing it, just in case, and return if the object type isn't the expected.
Using the filter
To use the filter, you have to deploy it and configure your deployment descriptor, the web.xml file. The required steps are:- Declare the filter.
- Map the filter.
- REQUEST (the default value)
- FORWARD
- INCLUDE
- ERROR
es.trafico.datapower.exceptions.filters.DPErrorFilter
</filter-class>
In this case the filter is triggered at every request because of the /* URL pattern.
0 komentar:
Posting Komentar