Java EE 7: Servlets

A servlet is a Java program that it is executed in a web server and it builds or serve web pages. This allows us to build dynamic pages.

Servlets are a standard implementation in Java EE, for this reason, we can find it under the packages javax.servlet. Here we can find all the classes and interfaces we need to use to work with servlets. The basic elements we need to know are:

  • Servlet interface: It defines the method implemented in any servlet.
  • Class GenericServlet: It is an abstract class that implements the Servlet inteface. It is a generic servlet, and it is not tied to any protocol.
  • HttpServelt: We can find this class inside the package javax.servlet.http. This class inherit from GenericServlet and it is an abstract class too. We will inherit from this class to build our servlets.
  • When a servlet receives a request from a client it receives two objects:
    • ServletRequest: This class contains all the incoming data received in the client request. This object allows us to read all the parameters like the protocol used by the client, the parrameters send by them, and so on. We can obtain an object ServletInputStream to obtain data about the client that it is doing the request. For the HTTP protocol, we can find the subclass HttpServletRequest.
    • ServletResponse: It will contain the servlet response. We can obtain an object ServletOutputStream and/or a Writer to write the response. Again, we have a concrete subclass for the HTTP protocol, HttpServletResponse.

The servlets, like some components in Java EE, have a concrete life cicle and this life cicle is common to all the servlets. The different phases of this life cicle are:

  • The server starts and initializes the servlet.
  • The server processes the clients requests. Each request starts a new thread, and all of them are executed concurrently in the same servlet object.
  • The server destroys the servlet, usually when they have periods without requests or when the server stops.

The different phases of the servlet’s life cicle have associated some specific methods that we can override and use to implement our desired behavior.

Associated to the first phase, the initialization phase, we can find two methods:

public void init() throws ServletException { ... }
public void init(ServletConfig conf) throws ServletException {
	super.init(conf);
	...
}

The first method does not need external configuration parameters, but, for the second one, we can supply these parameters in an object ServletConfig. I should remark that the call to the super.init(conf) is very important due to allow the servlet to use the configuration everywhere. If we want to perform any task during the execution of these methods, we should rewrite one or both methods. It is a good practice to return an UnavailableException if there is any error during the initialization process.

During the second phase, when a request arrives from the client, it launches a new thread that calls the service() method.

public void service(HttpServletRequest request,
		HttpServletResponse response)
			throws ServletException, IOException { ... }

This method obtains the request type: GET, POST, PUT, DELETE, OPTIONS or TRACE and, depending on the type of request, it calls the appropriate method in charge to manage the request. The most important are, in general, GET and POST, the signatures of these methods are:

public void doGet(HttpServletRequest request,
		HttpServletResponse response)
			throws ServletException, IOException { ... }
public void doPost(HttpServletRequest request,
		HttpServletResponse response)
			throws ServletException, IOException { ... }

We can find similar methods for the rest of the request types: doDelete(), doPut(), doOptions(), doTrace().

The last phase, the destruction phase, calls a method to destroy the servlet and destroy any element created during the initializacion. The method signature is:

public void destroy() throws ServletException { ... }

We should pay special attention if our servlet is launching time consuming task, we should implement some way to be sure all the tasks have finished. A counter with some synchronization code to control the number of tasks, or a flag visible for the tasks to stop them if the servlet must be destroyed quickly.

Let’s see a basic code example to see everything we have seen so far.

Basic servlet:

package com.wordpress.binaycoders.examples;

import javax.servlet.*;
import javax.servlet.http.*;

public class BasicServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// code for GET request
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// code for POST request
	}
}

The next step is to configure the access to the servlet. In previous versions of Java EE we should perform this configuration with XML in the web.xml file, but in the Java EE 7 version we can do this with annotations. In any case, here, we are going to see both ways.

For the XML configuration, we should declare the servlet and the URL where is going to be available:

<servlet>
	<servlet-name>basicServlet</servlet-name>
	<servlet-class>com.wordpress.binaycoders.examples.BasicServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>basicServlet</servlet-name>
	<url-pattern>/basicservlet</url-pattern>
</servlet-mapping>

With this configuration the servlet should be available in the URL:

http://localhost:8080/<theapp>/basicservlet

Inside the servlet mapping we can define a pattern instead of a concrete URL, something like:

<servlet-mapping>
	<servlet-name>basicServlet</servlet-name>
	<url-pattern>/basicservlet/*</url-pattern>
</servlet-mapping>

Or we can define a JSP page:

<servlet>
	<servlet-name>basicServlet</servlet-name>
	<jsp-file>/page.jsp</jsp-file>
</servlet>

We can initialize some parameters when the servlet starts:

<servlet>
	<servlet-name>basicServlet</servlet-name>
	<servlet-class>BasicServlet</servlet-class>
	<init-param>
		<param-name>parameter</param-name>
		<param-value>value</param-value>
	</init-param>
</servlet>

And, we can load the servlet when the server starts. Even we can define the order they are going to follow when the server starts using numbers to sort properly the different servlets.

<servlet>
	<servlet-name>basicServlet</servlet-name>
	<servlet-class>BasicServlet</servlet-class>
	<load-on-startup/>
</servlet>
<servlet>
       <servlet-name>basicServlet</servlet-name>
       <servlet-class>BasicServlet</servlet-class>
       <load-on-startup>2</load-on-startup>
</servlet>

In this case, the Java EE 7 brings us the Servlet 3.0 API, and this API allows us to use annotations to configure our servlets.

Declaring the servlet and the URL where is going to be available:

package com.wordpress.binaycoders.examples;

import javax.servlet.*;
import javax.servlet.http.*;

@WebServlet(name="basicServlet", urlPatterns="/basicservlet")
public class BasicServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// code for GET request
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// code for POST request
	}
}

In the same way, we can use annotations to initializate parameters like we have done in the XML.

@WebServlet(urlPatterns = "/basicservlet",
		initParams = { @InitParam(name = "parameter", value = "value") }
)

The way to access to these initialized parameters from our java code is:

getServletConfig().getInitParameter("parameter");

And, in the same way, we have stablished the initialization order for the servlets in the XML, we can do it with annotations:

@WebServlet(name = "basicServlet",
		urlPatterns = "/basicservlet",
		loadOnStartup = "2")

And, to finish the post, let’s see some very basic examples:

Servlet to generate plain text:

package com.wordpress.binaycoders.examples;

import javax.servlet.*;
import javax.servlet.http.*;

@WebServlet(name="basicServlet", urlPatterns="/basicservlet")
public class BasicServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		PrintWriter out = response.getWriter();
    	out.println ("I am the basic servlet. Welcome!");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}
}

Servlet to generate HTML:

package com.wordpress.binaycoders.examples;

import javax.servlet.*;
import javax.servlet.http.*;

@WebServlet(name="basicServlet", urlPatterns="/basicservlet")
public class BasicServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");

		PrintWriter out = response.getWriter();
		out.println ("<!doctype html>");
		out.println ("<html>");
		out.println ("<body>");
		out.println ("<br>I am the basic servlet (HTML). Welcome!");
		out.println ("</body>");
		out.println ("</html>");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}
}

And, that’s all for now.

See you.

Advertisements
Java EE 7: Servlets