Java servlet check box
last modified July 13, 2020
In this tutorial, we create a classic web application that reads a value from a HTML check box. The form values are validated with a filter class. The views are created with FreeMarker template. The web application is created with a Java servlet and deployed on Tomcat server.
Servlet is a Java class which responds to a particular type of network request - most commonly an HTTP request. Servlets are used to implement web applications. They run in a servlet container such as Tomcat or Jetty. In modern-day Java web development programmers use frameworks that are built on top of servlets.
A Java 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. It is used for tasks such as authentication, auditing, logging, data encryption, or data validation.
FreeMarker is a template engine for the Java programming language. Templates are written in the FreeMarker Template Language (FTL). Templates are used in web applications to create the UI.
Apache Tomcat is an open source Java Servlet Container developed by the Apache Software Foundation (ASF). It is the most popular Java web servers.
Bootstrap is an HTML, CSS, and JS framework for developing responsive, mobile first projects on the web. It contains HTML and CSS design templates for typography, forms, buttons, navigation and other interface components, as well as optional JavaScript extension.
Application
The following web application has a simple web form that consists of a check box and an input text. The values are send to the web application's controller, which is a Java servlet. Before the request reaches the controller, the values are validated in a Java filter. In the end, the values are shown in a HTML file, which is built with FreeMarker template. FreeMarker joins HTML with data.
<?xml version="1.0" encoding="UTF-8"?> <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>com.zetcode</groupId> <artifactId>FormCheckBox</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>FormCheckBox</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.25-incubating</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project>
The javax.servlet-api
dependency is a library for building Java
servlets. The freemarker
artifact is for FreeMarker template engine.
The maven-war-plugin
collects all artifact dependencies,
classes and resources of the web application and packages them into a
web application archive (WAR).
$ tree . ├── pom.xml └── src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ ├── filter │ │ │ └── FormFilter.java │ │ └── web │ │ └── MyController.java │ ├── resources │ └── webapp │ ├── index.html │ ├── META-INF │ │ └── context.xml │ └── WEB-INF │ ├── template │ │ ├── show.ftl │ │ └── unknown.ftl │ └── web.xml └── test └── java
With the tree
command we show the project directory structure.
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <servlet> <servlet-name>freemarker</servlet-name> <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class> <init-param> <param-name>TemplatePath</param-name> <param-value>/WEB-INF/template/</param-value> </init-param> <init-param> <param-name>NoCache</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>ResponseCharacterEncoding</param-name> <param-value>fromTemplate</param-value> </init-param> <init-param> <param-name>ExceptionOnMissingTemplate</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>incompatible_improvements</param-name> <param-value>2.3.25-incubating</param-value> </init-param> <init-param> <param-name>template_exception_handler</param-name> <param-value>html_debug</param-value> </init-param> <init-param> <param-name>template_update_delay</param-name> <param-value>0 s</param-value> </init-param> <init-param> <param-name>default_encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>output_encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>locale</param-name> <param-value>en_US</param-value> </init-param> <init-param> <param-name>number_format</param-name> <param-value>0.##########</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.ftl</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>FreeMarker MVC Views</web-resource-name> <url-pattern>*.ftl</url-pattern> </web-resource-collection> <auth-constraint> </auth-constraint> </security-constraint> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app>
In the web.xml
file, we set up the FreeMarker template. It works via
the freemarker.ext.servlet.FreemarkerServlet
. The template directory
is set to /WEB-INF/template/
.
<?xml version="1.0" encoding="UTF-8"?> <Context path="/FormCheckBox"/>
The context.xml
file is Tomcat's configuration file. Inside the file we set
the context path (the application name). The file is located in the META-INF
subdirectory.
<!DOCTYPE html> <html> <head> <title>Check box</title> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div class="container"> <div class="form"> <form action="MyController"> <input type="hidden" name="action" value="show"> <div class="form-group"> <label>Name:</label> <input type="text" name="name" class="form-control"> </div> <div class="checkbox"> <label><input type="checkbox" name="adult">Adult</label> </div> <button type="submit" class="btn btn-default">Submit</button> </form> </div> </div> </body> </html>
The index.html
file is the home page of our application. It contains an HTML
form with a text input and a check box. The look of the page is created with the Bootstrap library.
<input type="hidden" name="action" value="show">
This hidden input
tag defines an action parameter, which is used in the controller
servlet.
package com.zetcode.filter; import java.io.IOException; import java.util.Map; 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; @WebFilter(filterName = "FormFilter", servletNames = {"MyController"}) public class FormFilter implements Filter { public FormFilter() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Map<String, String[]> params = request.getParameterMap(); params.keySet().stream().forEach(key -> { String value = params.get(key)[0]; if (key != null && ! value.trim().isEmpty()) request.setAttribute(key, params.get(key)[0]); }); chain.doFilter(request, response); } @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) { } }
The FormFilter
processes the request before reaching the MyController
servlet. It retrieves all parameters from the request and validates them; we need to
ensure that the values are not null or empty.
Map<String, String[]> params = request.getParameterMap();
We get all the parameters from the request with the getParameterMap
method.
params.keySet().stream().forEach(key -> { String value = params.get(key)[0]; if (key != null && ! value.trim().isEmpty()) request.setAttribute(key, params.get(key)[0]); });
We need to turn request parameters into request attributes. We set an attribute to the request if it is not null or empty. These attributes are available for the FreeMarker template engine to process them.
chain.doFilter(request, response);
The request continues to the mapped servlet.
package com.zetcode.web; import com.zetcode.util.Validate; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "MyController", urlPatterns = {"/MyController"}) public class MyController extends HttpServlet { private static final String SHOW_ACTION = "show"; private static final String SHOW_VIEW = "show.ftl"; private static final String UNKNOW_VIEW = "unknown.ftl"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action = request.getParameter("action"); String path = UNKNOW_VIEW; if (SHOW_ACTION.equals(action)) { path = SHOW_VIEW; } response.setContentType("text/html;charset=UTF-8"); RequestDispatcher dispatcher = request.getRequestDispatcher(path); dispatcher.forward(request, response); } }
The MyController
servlet will handle a request aftet it was
processed by a filter.
@WebServlet(name = "MyController", urlPatterns = {"/MyController"})
The @WebServlet
annotation maps the request with MyController
URL pattern to the MyController
servlet.
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
The request is a GET request, so we serve it in the doGet
method.
response.setContentType("text/html;charset=UTF-8");
With the setContentType
method, we set the content type (HTML)
and charset.
RequestDispatcher dispatcher = request.getRequestDispatcher(path); dispatcher.forward(request, response);
With the RequestDispatcher
, we forward the request to the view.
The view is a FreeMarker template which is transformed into HTML page.
<!DOCTYPE html> <html> <head> <title>Show page</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <#if adult??> <p>${name!"Guest"} is adult</p> <#else> <p>${name!"Guest"} is minor</p> </#if> </body> </html>
This is the show.ftl
template. Two attributes were passed
to the template: adult
and name
. FreeMarker uses
the ${}
syntax to get the value of a request attribute.
<#if adult??>
With the #if
directive, we check if the adult
attribute
is set. The ??
tells if the left hand operand's value is missing.
<p>${name!"Guest"} is adult</p>
The !
is used to give a default value when a value is missing.
(Remember that we did not set attributes for parameters that were empty or null.)
If the name
variable is set, it is displayed; otherwise, "Guest" is shown.
<!DOCTYPE html> <html> <head> <title>Unknow action</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <p>Unknown action</p> </body> </html>
This is the unknown.ftl
template file.
In this tutorial, we have sent data from an HTML form to a Java servlet. The form contained an input tag and a check box. The request parameters were validated in a Java filter and turned into request attributes and send to a FreeMarker template to be displayed.