Hello world servlet

Before getting into the technical details, let's create an extremely simple hello world servlet. To do it, we setup a Gradle project with the build file, build.gradle, the servlet class in the file, src/main/java/packt/java9/by/example/mastermind/servlet/HelloWorld.java, and last but not least, we have to create the file src/main/webapp/WEB-INF/web.xml. The gradle.build file will look the following:

apply plugin: 'java' 
apply plugin: 'jetty'

repositories {
jcenter()
}

dependencies {
providedCompile "javax.servlet:javax.servlet-api:3.1.0"
}

jettyRun {
contextPath '/hello'
}

The Gradle build file uses two plugins, java and jetty. We have already used the java plugin in the previous chapter. The jetty plugin adds tasks such as jettyRun that load the Jetty servlet container and start up the application. The jetty plugin is also an extension of the war plugin that compiles web applications into a Web Archive (WAR) packaging format.

The WAR packaging format is practically the same as JAR; it is a zip file and it contains a lib directory that contains all the JAR files that the web application depends on. The classes of the application are in the directory, WEB-INF/classes, and there is a WEB-INF/web.xml file that describes servlet URL mapping, which we will explore in detail soon.

Since we want to develop an extremely simple servlet, we add the servlet API as a dependency to the project. This is, however, not a compile dependency. The API is available when the servlet runs in the container. Still, it has to be available when the compiler compiles our code; therefore, a dummy implementation is provided by the artifact specified as providedCompile. Because it is specified that way, the build process will not package the library into the generated WAR file. The generated file will contain nothing that is specific to Jetty or any other servlet container.

The servlet container will provide the actual implementation of the servlet library. When the application is deployed and started in a Jetty, the Jetty-specific implementation of the servlet library will be available on the classpath. When the application is deployed to a Tomcat, the Tomcat specific implementation will be available.

We create a class in our project, as follows:

package packt.java9.by.example.mastermind.servlet; 

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class HelloWorld extends HttpServlet {

private String message;

@Override
public void init() throws ServletException {
message = "Hello, World";
}

@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h1>" + message + "</h1>");
}

@Override
public void destroy() {
}
}

When the servlet is started, the init method is invoked. When it is put out of service, the destroy method is called. These methods can be overridden and provide a more fine-grained control than the constructor and other finalization possibilities. A servlet object may be put into service more than once, and after calling destroy, the servlet container may invoke init again; thus, this cycle is not strictly tied to the life cycle of the object. Usually, there is not much that we do in these methods, but sometimes, you may need some code in them.

Also, note that a single servlet object may be used to serve many requests, even at the same time; thus, the servlet classes and methods in it should be fairly thread-safe. The specification demands that a servlet container uses only one servlet instance in case the container runs in a non-distributed environment. In case the container runs on the same machine in several processes, each executing a JVM, or even on different machines, there can be many servlet instances that handle the requests. Generally, the servlet classes should be designed such that they do not assume that only one thread is executing them, but at the same time, they should also not assume that the instance is the same for different requests. We just cannot know.

What does it mean in practice? You should not use instance fields that are specific to a certain request. In the example, the field initialized to hold the message holds the same value for each and every request; essentially, the variable is almost a final constant. It is used only to demonstrate some functionality for the init method.

The doGet method is invoked when the servlet container gets an HTTP request with the GET method. The method has two arguments. The first one represents the request, and the second one represents the response. The request can be used to collect all information that comes in the request. In the preceding example, there is nothing like that. We do not use any of the inputs. If a request comes to our servlet, then we answer the Hello, World string, no matter what. Later, we will see examples when we read the parameters from the request. The response gives methods that can be used to handle the output. In the example, we fetch PrintWriter, which is to be used to send characters to the body of the HTTP response. This is the content that appears in the browser. The mime type we send is text/html, and this is set by calling the setContentType method. This will get into the HTTP header field, Content-Type. The standard and the JavaDoc documentation of the classes define all the methods that can be used, and also how these should be used.

Finally, we have a web.xml file that declares the servlets that are implemented in our code. This is, just as the name of the file indicates, an XML file. It declaratively defines all the servlets that are included in the archive and also other parameters. In the example, the parameters are not defined, only the servlet and the mapping to the URL. Since we have only one single servlet in this example, the WAR file, it is mapped to the root context. All and every GET request that arrives to the servlet container and to this archive will be served by this servlet:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5"
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_2_5.xsd">

<servlet>
<display-name>HelloWorldServlet</display-name>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>packt.java9.by.example.mastermind.servlet.HelloWorld</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

</web-app>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.35.247