Creating Filters With GServlet
Filters allow us to sort tasks during the pre or postprocessing of a request — learn how to create filters with the GServlet API in Java for an elegant implementation.
Join the DZone community and get the full member experience.
Join For FreeIn my first article "Getting Started with GServlet", we created a simple Hello World Servlet using the Groovy language. Today, we are going to see how simple it is to create filters with the GServlet API.
Let's start by creating a Maven war project.
pom.xml
xxxxxxxxxx
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gservlet-examples</groupId>
<artifactId>filters</artifactId>
<version>1.0.1</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.gservlet</groupId>
<artifactId>gservlet-api</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Creating Filters
A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both. The Filter interface defines methods that all filters must implement. Filters perform filtering in the doFilter() method.
Let's create a Java class that implements the Filter interface and which logs the request parameters and the cookies using the ServletContext object.
LoggingFilter.java
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
"/*") (
public class LoggingFilter implements Filter {
private ServletContext context;
public void init(FilterConfig config) throws ServletException {
this.context = config.getServletContext();
this.context.log("loggingFilter initialized");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
Enumeration < String > params = req.getParameterNames();
while (params.hasMoreElements()) {
String name = params.nextElement();
String value = request.getParameter(name);
context.log("Request Param : " + name + "=" + value);
}
Cookie[] cookies = req.getCookies();
for (Cookie cookie: cookies) {
context.log("Cookie : " + cookie.getName() + "=" + cookie.getValue());
}
chain.doFilter(request, response);
}
public void destroy() {}
}
Its Groovy version with the GServlet API looks like this:
LoggingFilter.groovy
xxxxxxxxxx
import org.gservlet.annotation.Filter
"/*") (
class LoggingFilter {
void init() {
logger.info("loggingFilter initialized")
}
void filter() {
request.parameterNames.each { name ->
logger.info("Request Param : $name=$request[name]")
}
request.cookies.each { cookie ->
logger.info("Cookie : $cookie.name=$cookie.value")
}
next()
}
}
As you can see, it is less verbose and much cleaner. Also a java.util.logging.Logger instance has been used for the logging instead of the ServletContext object and the implicit variables made available to a filter are as follows:
Variable | Description |
---|---|
logger |
Logger object |
config |
FilterConfig object |
request |
HttpServletRequest object |
response |
HttpServletResponse object |
chain |
FilterChain object |
session |
HttpSession object |
context |
ServletContext object |
sql |
Sql object |
out |
PrintWriter object |
html |
MarkupBuilder object |
xml |
MarkupBuilder object |
Filter Methods
For an exhaustive list of the supported methods, please read the Javadocs.
Method | Description |
---|---|
void init() |
handles the initialization process |
void filter() |
handles the filtering tasks |
void next() |
Calls the next filter in the chain |
void json(object) |
Sends the response as JSON |
void destroy() |
invoked when taken out of the service |
Filter Annotation Attributes
They are the same as those of the @WebFilter annotation.
Name | Type | Description |
---|---|---|
filterName |
String |
name of the filter |
value |
String[] |
URL patterns of the filter |
urlPatterns |
String[] |
URL patterns of the filter |
dispatcherTypes |
DispatcherType[] |
dispatcher types to which the filter applies |
initParams |
InitParam[] |
init parameters of the filter |
servletNames |
String[] |
names of the servlets to which the filter applies |
asyncSupported |
boolean |
Declares whether the filter supports asynchronous operation mode |
smallIcon |
String |
small icon of the filter |
largeIcon |
String |
large icon of the filter |
description |
String |
description of the filter |
displayName |
String |
display name of the filter |
Filter Initialization Parameters
Since Servlet 3.0, the @WebInitParam annotation is used to specify initialization parameters for a filter programmatically. In its initialization method init(), we can get our parameters using the getInitParameter() method of the FilterConfig object.
In the Java example below, we are going to profile a servlet's performance based on an initialization parameter.
Profiler.java
xxxxxxxxxx
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
urlPatterns = {"/*"}, initParams = (name = "env", value = "dev")) (
public class Profiler implements Filter {
private FilterConfig config;
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if ("dev".equals(config.getInitParameter("env"))) {
long time = System.currentTimeMillis();
chain.doFilter(request, response);
time = System.currentTimeMillis() - time;
String url = ((HttpServletRequest) request).getRequestURL().toString();
System.out.println("Time taken for request to complete: " + time + "ms");
System.out.println("Request url : " + url);
} else {
chain.doFilter(request, response);
}
}
public void destroy() {
}
}
In GServlet, the @WebInitParam annotation has been shortened to @InitParam, and like for a servlet, you can get an initialization parameter through the implicit config variable using just its name or as described above:
x
config.env
config.getInitParameter("env")
This means that we can now create our Groovy profiler in an elegant way:
Profiler.groovy
x
import org.gservlet.annotation.Filter
import org.gservlet.annotation.InitParam
urlPatterns = ["/*"], initParams = (name = "env", value = "dev")) (
class Profiler {
void filter() {
if ("dev" == config.env) {
long time = System.currentTimeMillis()
next()
time = System.currentTimeMillis() - time
println("Time taken for request to complete: ${time}ms")
println("Request url : $request.requestURL")
} else {
next()
}
}
}
This example is available for download on GitHub and you can refer to the developer guide for more details.
Opinions expressed by DZone contributors are their own.
Comments