Jakarta EE Programming/Servlet

A servlet is a Java class that runs on the server side that receives HTTP data and does a processing or more following the constraints of the HTTP protocol.

The servlets

edit

Example of servlet

edit
package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Hello
 */
@WebServlet("/Hello")
public class Hello extends HttpServlet {

    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public Hello() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)              
                                               throws ServletException, IOException {
 
        // TODO Auto-generated method stub
       
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            out.println("Hello World");
        } finally {
            out.close();
        }
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        doGet(request,response);
    }
}

Description

edit

We notice two methods in this class: doGet() and doPost(). The first answers by HTTP to the reception of a GET request, the second to the reception of a POST request. As we want that in the both cases the servlet processes the request, doPost() forwards to doGet().

Deployment on Tomcat

edit
  • Put the compiled class with its package in the directory classes in WEB-INF of the working web directory (here: webTest)
  • Edit web.xml in WEB-INF by adding:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0"
  metadata-complete="true">  

  <!-- Beginning here -->

    <servlet>
      <servlet-name>Hello</servlet-name><!-- Class name -->
      <servlet-class>servlet.Hello</servlet-class><!-- Class tree: with the package -->
    </servlet>
    <servlet-mapping>
        <servlet-name>Hello</servlet-name><!-- Class name -->
        <url-pattern>/Hello</url-pattern><!-- Class pattern in the URL-->
    </servlet-mapping>

   <!-- End here -->

<web-app>

So the WEB-INF contains:

   WEB-INF
     web.xml
     classes
       servlet
         Hello.class

Call of the servlet

edit

http://localhost:999/webTest/Hello

Result in the browser:

Hello World

Decomposition of the URL

edit

[Protocol://][DNS]:[PORT]/[RootEntryDirectory]/[ServletName]

Information methods about the URL

edit
// Returns the server name
request.getServerName();

// Returns the server port
request.getServerPort();

// Returns the name of the application hosting the servlet
request.getContextPath();

// Returns the servlet path
request.getServletPath();

// Returns the type of the HTTP request used
request.getMethod();

// Returns the parameters sent in the URL
request.getQueryString();

// Returns the URL used to contact the servlet
request.getRequestURL();

// Returns the local address
request.getLocalAddr();

// Returns the local name
request.getLocalName();

// Returns the local port
request.getLocalPort();

// Returns the remote address
request.getRemoteAddr();

// Returns the remote host
request.getRemoteHost();

Example in the servlet:

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Hello
 */
@WebServlet("/Hello")
public class Hello extends HttpServlet {

  private static final long serialVersionUID = 1L;
   
  /**
   * @see HttpServlet#HttpServlet()
   */
  public Hello() {
    super();
    // TODO Auto-generated constructor stub
  }

  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {
      out.println(request.getServerName());
      out.println("<br/>");
      out.println(request.getServerPort());
      out.println("<br/>");
      out.println(request.getContextPath());
      out.println("<br/>");
      out.println(request.getServletPath());
      out.println("<br/>");
      out.println(request.getMethod());
      out.println("<br/>");
      out.println(request.getQueryString());
      out.println("<br/>");
      out.println(request.getRequestURL());
      out.println("<br/>");
      out.println(request.getLocalAddr());
      out.println("<br/>");
      out.println(request.getLocalName());
      out.println("<br/>");
      out.println(request.getLocalPort());
      out.println("<br/>");
      out.println(request.getRemoteAddr());
      out.println("<br/>");
      out.println(request.getRemoteHost());
    } finally {
      out.close();
    }
  }
   
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
   
    processRequest(request, response);
  }

  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    // TODO Auto-generated method stub

    processRequest(request, response);
  }
}

The related call: http://localhost:999/webTest/Hello

localhost
999
/webTest
/Hello
GET
null
http://localhost:999/webTest/Hello
127.0.0.1
localhost
999
127.0.0.1
127.0.0.1

Parameter reading methods

edit
// Parameter retrieving by the "parameterName"
request.getParameter(parameterName);

// Returns an enumeration of all the parameters of a request
request.getParameterNames();

// Returns all the parameter values of "parameterName"
request.getParameterValues(parameterName);

// Returns an iteration of the parameter names
request.getParameterMap();

Header reading methods

edit
// Returns the header names
request.getHeaderNames();

// Returns the headers
request.getHeaders();

// Returns the number of bytes of the request
request.getContentLength();

// Returns the content type of the request
request.getContentType();

// Returns the default language
request.getLocale();

// Returns the list of languages
request.getLocales();

// Returns the header date
request.getDateHeader(String name);

// Returns the header specified by the "name"
request.getHeader(String name);

// Returns the headers specified by the "name"
request.getHeaders(String name);

Request methods for adding information

edit
// Store an object in the HttpServletRequest object
request.setAttribute(String name, Object o);

// Returns the stored object "name"
request.getAttribute(String name);

// Returns an enumeration of the attribute names
request.getAttributeNames();

// Remove the attribute "name" the attributes of the request
request.removeAttribute(String name);

Request methods for adding headers

edit

The HTTP headers adds complementary informations to the response.

// Indicates the nature of the information put into the response
response.setContentType(String type);

// Indicates the local language
response.setLocale(Locale loc);

// Adds the header "name" with the value "value"
response.addHeader(String name, String value);

Construction of the response body

edit
  • (PrintWriter)getWriter() allows to transfer text into the HTTP response body.
  • (ServletOutputStream)getOutputStream() allows to transfer binary data into the HTTP response body.

Never use the both at the same time, or you will have an IllegalStateException exception.

Here is an example of binary sending:

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ReponseHttp2
 */
@WebServlet("/HttpResponse2")
public class HttpResponse2 extends HttpServlet {
  private static final long serialVersionUID = 1L;
       
  /**
   * @see HttpServlet#HttpServlet()
   */
  public HttpResponse2() {
    super();
    // TODO Auto-generated constructor stub
  }
   
  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    response.sendRedirect("images/toto.jpg");
  }
   
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    processRequest(request, response);
  }

  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    processRequest(request, response);
  }

}

In this example, we use processRequest(request, response) to always get the same process in GET or POST.

Constructing the HTTP response

edit

The status codes are splitted into 5 categories:

1XX: informative
2XX: success
3XX: redirection
4XX: client error
5XX: server error

The details of these codes are available at http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

  • setStatus(int rc)
  • sendError(int sc, String message)

...allow to set the error status of the page. As an example, we will generate a server error.

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ReponseHTTP
 */
@WebServlet("/ReponseHTTP")
public class ReponseHTTP extends HttpServlet {

  private static final long serialVersionUID = 1L;
       
  /**
   * @see HttpServlet#HttpServlet()
   */
  public ReponseHTTP() {
    super();
    // TODO Auto-generated constructor stub
  }

  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {
      response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "the server is overloaded. Please try later.");
    } finally {
      out.close();
    }
  }
   
  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    processRequest(request, response);
  }

  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    processRequest(request, response);
  }
}

Other ressources

edit

RequestDispatcher

edit

include

edit

Inclusion of an external resource.

RequestDispatcher rd = null;
rd = getServletContext().getRequestDispatcher("/header.html");
rd.include(request, response);

forward

edit

Servlet result transfer to another resource.

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.HttpServlet;
import javax.servlet.HttpServletRequest;
import javax.servlet.HttpServletResponse;

public class Result extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
       
      response.setContentType("text/html;charset=UTF-8");
      PrintWriter out = response.getWriter();
      try {
        int result = 10;
        RequestDispatcher rd = null;
        rd = getServletContext().getRequestDispatcher("/result.jsp");
        request.setAttribute("theResult", result);
        rd.forward(request, response);
      } finally {
        out.close();
      }
   }
}

The destination resource: result.jsp

<%@page contentType="text/html" pageEncoding="UTF-8">
<%@page import="java.text.*" %>
<html>
  <body>
    <%
    theResult = (double) request.getAttribute("theResult");
    %>

    Result: <%= theResult %>
  </body>
</html>

Redirect

edit

The server informs the browser to send a HTTP request to the given URL.

location

edit
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); // For a 301 HTTP response
response.setHeader("location", "http://www.google.be"); // For a 302 HTTP response

redirect

edit
response.sendRedirect("http://www.google.be");

Filters

edit

The filters add a process on a HTTP request before it is received by the servlet or on the HTTP response before it is returned.

Its roles are:

  • Access control
  • Access log
  • Data decompression
  • Decipherment
  • Data conversion

Several responses can be executed successively. The filter class must implement javax.servlet.Filter.

 

To do:
Add examples.


Events

edit

The events inform about the application operations like the instantiation and the destruction of the objects.

  • Application-related events: Those triggered by the servlet context.
  • Session-related events : Those classes must implement HttpSessionListener, HttpSessionAttributeListener.

Servlet synchronization

edit

This synchronization avoids the server to use two threads at the same time, for example, when two instances of the same class call a same method with two different clients. synchronized(this){} must be applied to the critical processes like counters.

public class ... {
  public void method() {
    out = response.getWriter();
    synchronized(this) {
      counter++;
    }
    out.println("The counter value is " + counter);
  }
}
 

To do:
Add exercises.