Tuesday, January 24, 2012

Filters

Filters are special classes which are called before the Servlet executes.
They are used to do some preliminary work before the Servlet executes.

For example, in our User.java, one of the validations we do is to check for empty input.

This validation is necessary for all forms - so why not put it in a "common" class which is called before processing any form?

This class can be implemented as a filter.

Let us write our first filter, which will validate form input for empty values.

In your org.confucius, create a new class called InputCheckFilter.java which implements the javax.servlet.Filter interface.

It will look like this:
 package org.confucius;  

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class InputCheckFilter implements Filter {

@Override
public void init(FilterConfig arg0) throws ServletException {

}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {

// Verifies input
Enumeration parameters = request.getParameterNames();
while (parameters.hasMoreElements()){
String parameter = (String) parameters.nextElement();
String value = request.getParameter(parameter);

if (value == null || value.length() == 0){
response.getOutputStream().print("Please enter values for all inputs!");
return;
}
}

chain.doFilter(request, response);

}

@Override
public void destroy() {

}

}



The filter checks all the parameters. If any parameter is not specified, it returns an error message. Otherwise, it continues the "filter chain" - we will learn more about the filter chain later.

For now, understand that the "chain.dofilter()" call passes the control to the Servlet.

Note that in the above code, the chain.dofilter() will not get called if any parameter is missing.

Let us now update out web.xml to specify that this filter should be used for all requests directed to the /register URL. Like this:
 <web-app>   
<filter>
<filter-name>empty_input</filter-name>
<filter-class>org.confucius.InputCheckFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>empty_input</filter-name>
<url-pattern>/register</url-pattern>
</filter-mapping>

<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.confucius.HelloWorld</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/register</url-pattern>
</servlet-mapping>

</web-app>



Finally, let us clean up the User.java validation so it does not have to do the empty parameter check.

Our User.java now looks like this:
 package org.confucius;  

import java.util.regex.Pattern;

public class User {
private String firstName = null;
private String lastName = null;

public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

public Boolean validate(){
if (Pattern.matches("[a-zA-Z]+", firstName)
&& Pattern.matches("[a-zA-Z]+", lastName)){
return true;
}
else{
return false;
}
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}


}



We can also update our Error.jsp to make it more specific, since the user validation now checks only for numbers in names.

Your Error.jsp will look like this:
 <html>   
<head>
</head>
<body>
Error! You entered names with numbers in them.
</body>
</html>




If you build and deploy HelloWorld.war, and point your browser to:
http://localhost:8080/HelloWorld/jsp/HelloWorld.jsp

you will see the filter in action if you do not specify a value for both parameters.

NOTE: The filter is totally reusable. You can associate it with any number of URLs in web.xml and it will do its job of checking the request parameters.

No comments: