Questions tagged [servlets]

Servlet is a Java application programming interface (API) running on the server machine which can intercept the requests made by the client and can generate/send a response accordingly.

Servlets

A Servlet is a Java application programming interface (API) running on the server machine which can intercept requests made by the client and can generate/send a response accordingly. A well-known example is the HttpServlet which provides methods to hook on HTTP requests using the popular HTTP methods such as GET and POST. You can configure HttpServlets to listen on a certain HTTP URL pattern, which is configurable in web.xml, or more recently with Java EE 6, with @WebServlet annotation. Many Java EE web frameworks are built on top of servlets, such as JSF, JAX-RS, Spring MVC, Struts, Wicket, etcetera. See also What is the difference between JSF, Servlet and JSP?

Lifecycle

When a Servlet is requested for the first time or when the web app starts up, the servlet container will create an instance of it and keep it in memory during the web app's lifetime. The same instance will be reused for every incoming request whose URL matches the servlet's URL pattern. You can access the requested data by HttpServletRequest and handle the response by HttpServletResponse. Both objects are available as method arguments inside of any of the overridden methods of HttpServlet, such as doGet() to preprocess a request and doPost() to post-process a request. See also How do servlets work? Instantiation, sessions, shared variables and multithreading.

Installation

In order to run Servlets, you need:

  • JDK (JRE is only sufficient if the server has its own compiler).
  • A servlet container.
  • Optionally, a Java EE aware IDE (Integrated Development Editor).

There are several servlet containers.

There are also Java EE application servers which in turn also contain a servlet container besides other Java EE APIs such as JSF, JPA, EJB, etc. See also What exactly is Java EE?

Installing a servlet container is generally just a matter of downloading the zip/gz file and extracting it at the location of your choice.

Generally, you'd also like to use an IDE such as Eclipse, IntelliJ or Netbeans so you don't need to manually compile and build the source files with javac over and over. Decent IDEs have plugins to seamlessly integrate the servlet container and import the necessary Java EE APIs into the build path of the project. See also How do I import the javax.servlet API in my Eclipse project?

Hello World #1 (post-process a request)

Post-processing a request such as submitting and validating a POST form is the most commonly known use case for a servlet. The action attribute of an HTML <form> can point to a servlet URL and the method="post" would trigger the servlet's doPost() method where you have all the freedom to control the HTTP request and response.

Assuming that there's a JSP in /WEB-INF/hello.jsp which looks like this...

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Servlet Hello World</title>
        <style>.error { color: red; } .success { color: green; }</style>
    </head>
    <body>
        <form action="hello" method="post">
            <h1>Hello</h1>
            <p>
                <label for="name">What's your name?</label>
                <input id="name" name="name" value="${fn:escapeXml(param.name)}">
                <span class="error">${messages.name}</span>
            </p>
            <p>
                <label for="age">What's your age?</label>
                <input id="age" name="age" value="${fn:escapeXml(param.age)}">
                <span class="error">${messages.age}</span>
            </p>
            <p>
                <input type="submit">
                <span class="success">${messages.success}</span>
            </p>
        </form>
    </body>
</html>

(the fn:escapeXml() is to protect your page against XSS while redisplaying user-controlled input; if JSTL doesn't work in general, then probably your servlet container doesn't support it out of the box (like Tomcat); you can install it by just dropping jstl-1.2.jar in /WEB-INF/lib, see also JSTL info page)

...here's how the com.example.controller.HelloServlet class should look:

package com.example.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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("/hello")
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // Preprocess request: we actually don't need to do any business stuff, so just display JSP.
        request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response);
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // Postprocess request: gather and validate submitted data and display the result in the same JSP.

        // Prepare messages.
        Map<String, String> messages = new HashMap<String, String>();
        request.setAttribute("messages", messages);

        // Get and validate name.
        String name = request.getParameter("name");
        if (name == null || name.trim().isEmpty()) {
            messages.put("name", "Please enter name");
        } else if (!name.matches("\\p{Alnum}+")) {
            messages.put("name", "Please enter alphanumeric characters only");
        }

        // Get and validate age.
        String age = request.getParameter("age");
        if (age == null || age.trim().isEmpty()) {
            messages.put("age", "Please enter age");
        } else if (!age.matches("\\d+")) {
            messages.put("age", "Please enter digits only");
        }

        // No validation errors? Do the business job!
        if (messages.isEmpty()) {
            messages.put("success", String.format("Hello, your name is %s and your age is %s!", name, age));
        }

        request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response);
    }
    
}

Compile the code and put it in the /WEB-INF/classes folder. In this particular case, the class file should end up in /WEB-INF/classes/com/example/controller/HelloServlet.class. An IDE like Eclipse, Netbeans or IntelliJ will do it all automatically when you've created a dynamic web project.

Note that the @WebServlet annotation only works on Java EE 6 / Servlet 3.0 capable containers (Tomcat 7, Glassfish 3, JBoss AS 6, etc) and if a /WEB-INF/web.xml file is present, then its <web-app> root declaration should comply Servlet 3.0 version as well.

<?xml version="1.0" encoding="UTF-8"?>
<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">

</web-app>

If you're using/targeting an older Servlet version, such as Servlet 2.5, then you should remove the annotation and map the servlet in /WEB-INF/web.xml file as follows, which does effectively the same thing:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5"> 

    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.example.controller.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

Either way, it basically tells to the servlet container that it should do the following under the covers:

HelloServlet helloServlet = new HelloServlet(); // Construct servlet.
helloServlet.init(servletConfig); // Initialize servlet with config.
helloServlet.init(); // Initialize servlet without config.
servlets.put("/hello", helloServlet); // Add to servlet mapping.

Deploy the webapp and go to http://localhost:8080/contextname/hello (without .jsp extension!) to open the Hello World page. When you're opening the page like this, by entering URL in address bar or following a link or bookmark, then an HTTP GET request will be fired and the servlet's doGet() method will be called. When a form with method="post" is been submitted on the URL of the servlet, then an HTTP POST request will be fired and the servlet's doPost() method will be called.

Note that the JSP is been placed in /WEB-INF folder to prevent direct access to the JSP when a user enters its URL in the browser address bar. This is mandatory when it is required to invoke the servlet's doGet() method before the JSP is been displayed, for example when some data has to be preloaded.

Hello World #2 (preprocess a request)

Preprocessing a request such as preloading a list which is to be presented immediately on a "plain vanilla" GET request (which is used when you follow a link/bookmark or enter the URL in browser address yourself) is a less commonly known use case for a servlet. While it's used widely in the real world as well, the average basic Servlet tutorial found on the Internet does not explain this at all. However, it is pretty easy: you just have to implement the business job in the doGet() method instead of in doPost().

Here's a basic kickoff example where we're getting a list of products from the database so that it can be presented immediately when the end user opens the product page of a webshop. Only the ProductService class in the below example is another custom class and not described in this wiki since it's beyond the scope, but its list() method should be straightforward enough. The below example assumes it to be an EJB, but it can be anything, see also for example this post.

package com.example.controller;

import java.io.IOException;
import java.util.List;

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

import com.example.business.ProductService;
import com.example.model.Product;

@WebServlet("/products")
public class ProductServlet extends HttpServlet {

    @EJB
    private ProductService productService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // Preprocess request: load list of products for display in JSP.
        List<Product> products = productService.list();
        request.setAttribute("products", products);
        request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
    }
    
}

Here's how the /WEB-INF/products.jsp should look:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Our Products</title>
    </head>
    <body>
        <h1>Products</h1>
        <table>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Description</th>
                <th>Price</th>
            </tr>
            <c:forEach items="${products}" var="product">
                <tr>
                    <td>${product.id}</td>
                    <td><c:out value="${product.name}" /></td>
                    <td><c:out value="${product.description}" /></td>
                    <td><fmt:formatNumber value="${product.price}" type="currency" /></td>
                </tr>
            </c:forEach>
       </table>
    </body>
</html>

(the <c:out> is to protect your page against XSS while redisplaying user-controlled input, it does effectively the same thing as fn:escapeXml())

Deploy the webapp and go to http://localhost:8080/contextname/products (without the .jsp extension!). It'll call the doGet() method of the servlet which loads the products from the DB, stores it in the request scope and forwards the request/response to present the results.

To get a step further, you could filter the products based on a request parameter which is obtained from a GET search form as follows:

<form action="products">
    <input type="text" name="query" />
    <input type="submit" value="Search" />
</form>

or a hyperlink (or bookmark) as follows:

<a href="products?query=java">Search for products with keyword "java"</a>

with

String query = request.getParameter("query");
List<Product> products = productService.find(query);
// ...

This is also how search engines like Google work!

Coding style and recommendations

  • Do NOT call a doGet() method from a doPost() method or the other way around, or have them both call some other common method like processRequest(). This is wrong. Each of those two HTTP methods has its own clear responsibility: preprocessing or post-processing an HTTP request. If you intend to hook on all HTTP methods, you should be overriding the service() method. See also the Front Controller Pattern.

  • Do NOT output HTML in a servlet by using out.print() statements. It only makes it harder to maintain. HTML code belongs in JSP where you have the freedom to write HTML the way you want without fiddling with Java methods and quoted strings. From the other side on, do NOT use scriptlets (embedded raw Java code) inside JSP files. It only makes it harder to maintain. Java code belongs in Java classes where you have the freedom to write Java the way you want without fiddling with ugly <% %> things. See also How can I avoid Java code in JSP files, using JSP 2?

  • Do NOT use <jsp:useBean> if you're already using a servlet to process the model. It will only lead to confusion and maintenance trouble because the <jsp:useBean> follows a different level of MVC approach than when you're using servlets. It's either servlets or <jsp:useBean>, not both.

Specifications

Online Resources and tutorials

Frequently Asked Questions

Related tags

32784 questions
1188
votes
8 answers

How do servlets work? Instantiation, sessions, shared variables and multithreading

Suppose, I have a webserver which holds numerous servlets. For information passing among those servlets I am setting session and instance variables. Now, if 2 or more users send request to this server then what happens to the session variables? Will…
Ku Jon
  • 11,883
  • 3
  • 13
  • 4
852
votes
15 answers

What is the difference between JSF, Servlet and JSP?

I have some questions. These are : How are JSP and Servlet related to each other? Is JSP some kind of Servlet? How are JSP and JSF related to each other? Is JSF some kind of Pre-Build UI based JSP like ASP.NET-MVC?
Cheung
  • 14,537
  • 17
  • 60
  • 90
699
votes
14 answers

How to upload files to server using JSP/Servlet?

How can I upload files to server using JSP/Servlet? I tried this:
However, I only get the…
Thang Pham
  • 35,825
  • 73
  • 192
  • 279
363
votes
5 answers

Design Patterns web based applications

I am designing a simple web-based application. I am new to this web-based domain.I needed your advice regarding the design patterns like how responsibility should be distributed among Servlets, criteria to make new Servlet, etc. Actually, I have few…
mawia
  • 8,513
  • 13
  • 45
  • 57
346
votes
7 answers

How to use Servlets and Ajax?

I'm very new to web apps and Servlets and I have the following question: Whenever I print something inside the servlet and call it by the webbrowser, it returns a new page containing that text. Is there a way to print the text in the current page…
Amir Rachum
  • 67,681
  • 68
  • 159
  • 239
329
votes
15 answers

How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?

I want to develop with Servlets in Eclipse, but it says that the package javax.servlet / jakarta.servlet cannot be resolved. How can I add javax.servlet / jakarta.servlet package to my Eclipse project?
tom
  • 4,571
  • 10
  • 34
  • 38
321
votes
12 answers

What is Java Servlet?

I read many articles to understand java servlet but I did not succeed. Can you please give brief introduction of java servlets (in easy language). Like what is servlet? What are the advantges? And all that. I can't understand the difference…
hardik
  • 7,975
  • 7
  • 26
  • 48
301
votes
10 answers

Difference between getAttribute() and getParameter()

What is the difference between getAttribute() and getParameter() methods within HttpServletRequest class?
priya
  • 3,877
  • 6
  • 20
  • 15
261
votes
10 answers

HttpServletRequest to complete URL

I have an HttpServletRequest object. How do I get the complete and exact URL that caused this call to arrive at my servlet? Or at least as accurately as possible, as there are perhaps things that can be regenerated (the order of the parameters,…
flybywire
  • 232,954
  • 184
  • 384
  • 491
230
votes
11 answers

Maven dependency for Servlet 3.0 API?

How can I tell Maven 2 to load the Servlet 3.0 API? I tried: javax.servlet servlet-api 3.0 provided I use…
deamon
  • 78,414
  • 98
  • 279
  • 415
227
votes
6 answers

Where to place and how to read configuration resource files in servlet based application?

In my web application I have to send email to set of predefined users like finance@xyz.com, so I wish to add that to a .properties file and access it when required. Is this a correct procedure, if so then where should I place this file? I am using…
sansknwoledge
  • 4,067
  • 9
  • 34
  • 56
217
votes
9 answers

Java / Jakarta EE web development, where do I start and what skills do I need?

I want to learn, at least at a basic level, how to build Java web applications (coming from a .NET background). I would like to be able to build, deploy a simple CMS type application from the ground up. What exactly do I need to learn? Tomcat seems…
mrblah
  • 88,033
  • 134
  • 292
  • 404
208
votes
12 answers

java.net.SocketException: socket failed: EPERM (Operation not permitted)

I am working on an Android Studio project with several activities. I am currently trying to read the output from a Java Servlet on localhost but it seems to be crashing due to a socket permission. I've made a new project, used the exact same code…
Aaron Villalobos
  • 8,031
  • 3
  • 5
  • 6
196
votes
3 answers

How to use a servlet filter in Java to change an incoming servlet request url?

How can I use a servlet filter to change an incoming servlet request url from http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 to http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123 ? Update: according to BalusC's…
Frank
  • 28,342
  • 54
  • 158
  • 227
189
votes
5 answers

What is WEB-INF used for in a Java EE web application?

I'm working on a Java EE web application with the following source code directory structure: src/main/java <-- multiple packages containing Java classes src/test/java <-- multiple packages containing JUnit…
Steve Chambers
  • 31,993
  • 15
  • 129
  • 173
1
2 3
99 100