ZetCode

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.

pom.xml
<?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.

web.xml
<?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/.

context.xml
<?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.

index.html
<!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.

com/zetcode/FormFilter.java
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.

com/zetcode/MyController.java
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.

show.ftl
<!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.

unknown.ftl
<!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.