April 10, 2020
Estimated Post Reading Time ~

Sling Servlets 01 - What is a Servlet?

What is a servlet?

A servlet in its very core is a Java class, which can handle network requests (for e.g. HTTP requests). Servlets are usually used to implement web applications. This java class does not have any main() method, only some callback methods.

Servlets run on the java enabled web-server or the application server. They handle requests from the web server, process it, produce the response, then send the response back to the server. This means servlet lives and dies within a web container. A web container is responsible for invoking methods in a servlet. It knows what callback methods a servlet has.

Servlets run in a servlet container that handles the networking side (e.g. parsing an HTTP request, connection handling, etc.). One of the best known open source servlet container is Tomcat.

Properties of Servlet

  • Servlets work on the server-side
  • Servlets are capable of handling requests obtained from the webserver.

Execution of servlet

It involves eight basic steps -
  1. The client sends an HTTP request to the webserver.
  2. The web server receives the request and forwards it to the web container.
  3. Web container spins a thread for each request.
  4. The web container passes the request to the corresponding servlet.
  5. Since servlet cannot understand HTTP, it is a java program, it only understands objects, so web container converts the request into a valid request object.
  6. The servlet processes the request and generates a response in the form of output. A servlet has callback methods for this processing (for e.g. doGet(), doPost() etc.).
  7. The servlet sends the response back to the webserver.
  8. The web server sends the response back to the client after converting it into HTTP response and the client browser displays it on the screen.

How does a container know which servlet client is requested for?

  • There is a file called web.xml which is the master file for the web container.
  • We have information about servlet in this file -
              1. servlets
                   a. servlet-name
                   b. servlet-class
              2. servlet-mappings
                   a. servlet-name
                   b. url-pattern
  • Every servlet in the web app should have an entry in this file
  • So this lookup happens => url-pattern -> servlet-name -> servlet-class

Advantages

  • Servlets provide a way to generate dynamic documents that is both easier and faster to run.
  • Provide all the powerful features of Java, such as Exception Handling, Garbage Collection, etc.
  • Enables easy portability across web servers.
  • I can communicate with different servlets and servers.
  • Since all web applications are stateless protocol, the servlet uses its own API to maintain the session.

Disadvantages

  • Designing in a servlet is difficult and slows down the application.
  • Writing complex business logic makes the application difficult to understand.
  • We need a Java Runtime Environment on the server to run Servlets. CGI is a complete language independent protocol, so we can write CGIs in whatever languages available (including Java if we want to).

Servlet APIs

  • javax.servlet (Basic)
  • javax.servlet.http (Advance)

Code Example

To create a simple servlet demo, we need to perform the following steps -
  • Create a java dynamic web project using maven with the following pom.xml.
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.redquark.aem.servlets</groupId>
  <artifactId>SimpleServlet</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SimpleServlet Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/jsp-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
  </dependencies>
  <build>
    <finalName>SimpleServlet</finalName>
    <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
  </build>
</project>
  • Now add the following code in the index.html file
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Simple Servlet Demo</title>
    </head>
    <body>
 <a href="welcome">Click to call Servlet</a>
    </body>
</html>
  • Add the following code in SimpleHTTPServlet.java file
package org.redquark.aem.servlets;

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

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

/**
 * @author Anirudh Sharma
 *
 */
public class SimpleHTTPServlet extends HttpServlet {

 private static final long serialVersionUID = 4389328665759581789L;
 private String message;

 public void init() throws ServletException {
  message = "Simple HTTP Servlet Demo";
 }

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

  // Setting up the content type of web page
  response.setContentType("text/html");
  // Writing the message on the web page
  PrintWriter out = response.getWriter();
  out.println("<h1>" + message + "</h1>");
  out.println("<p>" + "Hello Friends!" + "</p>");
 }

 public void destroy() {
  /*
   * Empty. This will be called if we require some operation to happen at the end
   * of Servlet life cycle
   */
 }
}
  • Finally, add the following code in the web.xml file to define the servlet mappings
<web-app>
 <display-name>Simple Servlet</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>

 <servlet>
  <servlet-name>SimpleHTTPServlet</servlet-name>
  <servlet-class>org.redquark.aem.servlets.SimpleHTTPServlet</servlet-class>
 </servlet>

 <servlet-mapping>
  <servlet-name>SimpleHTTPServlet</servlet-name>
  <url-pattern>/welcome</url-pattern>
 </servlet-mapping>

</web-app>
  • Click on the index.html file -> Run on the server (You need to configure Apache Tomcat server to do this)

Concept of serialVersionUID

A version number is attached to each serializable class by the serialization runtime. This version number is called serialVersionUID which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization.

If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException.

A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification.

However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization.

Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible since such declarations apply only to the immediately declaring class serialVersionUID fields are not useful as inherited members.

Conclusion

In the first part of the Sling Servlets series, we discussed the anatomy of a simple java servlet. We have not yet discussed the nitty-gritty details of servlets in the Sling framework, which we will see in more detail from the next part onwards.

You can find the complete code on my GitHub.



By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.