Руководство Java Servlet для начинающих

1- Введение

Статья основана на:
  • Eclipse 4.6 (NEON)

  • Servlet 3.0

  • Tomcat 8

2- Что такое Servlet?

Java Servlet это программа работающая на Веб или на приложении сервера (Application Server) и действует как промежуточный уровень между запросом из веб браузера или другого клиентского  HTTP (Client) и базой данных или приложениями на HTTP сервере (HTTP Server).

Используя Servlet, вы можете получить ввод от пользователей через формы на веб страницах, от базы данных или другого реусурса, и создать динамические веб страницы.

3- Жизненный цикл Servlet

Изображение ниже иллюстрирует жизненный цикл Servlet. С момента создания, обработки от пользователя, до момента разрушения.

Существует 5 шагов:

  1. Скачать класс Servlet в память.
  2. Создать объект Servlet.
  3. Вызвать метод init() в Servlet.
  4. Вызвать метод service() вServlet.
  5. Вызвать метод destroy() в Servlet.

Шаги 1, 2 & 3 выполняются один единственный раз, когда Servlet загружен в первый раз. По умолчанию Servlet не загружаются (load) пока он не получит первый запрос от пользователя. Вы можете заставить Servlet Container (Servlet Контейнер) загрузить Servlet при запуске.

Шаг 4 выполняется много раз, каждый раз при запросе от пользователя к  Servlet.
Bước 5 выполняется когда контейнер Servlet (Servlet Container) разгружает (unloaded)  Servlet.
Вы можете посмотреть следующие изображения чтобы лучше понять про жизненный цикл Servlet.
При отправлении запроса (request) пользователя к  Servlet, Servlet вызывает метод  service() чтобы обработать запрос пользователя, service() вызывает один из двух методов  doGet() или  doPost(). В вашем  Servlet, вам нужно переопределить и обработать эти методы.
Так, когда пользователь отправляет запрос  Servlet, Servlet создается в момент получения первого запроса, одновременно вызывается метод init() в servlet чтобы инициализировать его, init() вызывается один единственный раз. Метод  destroy() используется для разрушения servlet, вызывается единственный раз когда вы отменяете развертывание (undeloy) веб приложения или отключаете (shutdown) Web Server (Веб Сервер).

4- Установка Tomcat Web Server

Чтобы начать с Servlet, вам необходимо скачать  Tomcat Web Server и объявить его с Eclipse. Вы можете посмотреть руководство по ссылке:

5- Создать Web Project чтобы начать с Servlet

  • File/New/Other
  • Project Name: ServletTutorial
Эта изображение созданного Project:
Создать файл index.html:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

   <h1>Hello World</h1>

</body>
</html>

6- Установка Eclipse для запуска на tomcat

До сих пор мы ничего не сделали с  Servlet. И теперь мы конфигурируем, чтобы запустить веб-приложение выше. Затем мы начнем с Servlet.
В eclipse, нажмите на правую кнопку мыши на Project  ServletTutorial , выберите Properties
Выберите местоположение установки вашего  Tomcat 8.
Щелкните правой кнопкой мыши на проект ServletTutorial, выберите " Run As / Run on Server".
Website работает в  браузере на Eclipse.
Принцип работы:
Когда вы вводите ссылку:
Тогда вебсайт возвращает содержимое страницы index.html, это понятно. Однако, если вы вводите ссылку:
Это означает, что вы не указали ясно какую страницу, webserver будет искать страницу по умолчанию, который объявляен в теге < welcome-file> который вы объявили в web.xml, чтобы возвратить.
Примечание: /ServletTutorial называется Context-Path, каждый вебсайт имеет Context-Path, вы можете конфигурировать для него другое значение, или оставить пустым. Если оставляете пустым, вы можете получить доступ в ваш веб через:
  • http://localhost:8080
  • http://localhost:8080/index.html
При запуске с Tomcat по умолчанию он использует название проекта как  Context-Path.
Consider the following illustration:

7- Некоторые классы участвующие в примере

Некоторые классы, которые будут участвовать в следующем примере данной статьи.
Constants.java
package org.o7planning.tutorial.beans;

public class Constants {

  public static final String ATTRIBUTE_USER_NAME_KEY ="ATTRIBUTE_USER_NAME_KEY";
   
  public static final String SESSION_USER_KEY ="SESSION_USER_KEY";
   
  public static final String CALLBACK_URL_KEY ="CALLBACK_URL_KEY";
   
}
UserInfo.java
package org.o7planning.tutorial.beans;

public class UserInfo {

   public String userName;
   private int post;
   private String country;
   
   public UserInfo(String userName, String country, int post)  {
       this.userName= userName;
       this.country= country;
       this.post= post;
   }

   public int getPost() {
       return post;
   }

   public void setPost(int post) {
       this.post = post;
   }

   public String getCountry() {
       return country;
   }

   public void setCountry(String country) {
       this.country = country;
   }

   public void setUserName(String userName) {
       this.userName = userName;
   }

   public UserInfo(String userName) {
       this.userName = userName;
   }

   public String getUserName() {
       return this.userName;
   }
}

8- Создать ваш первый Servlet

HelloServlet.java
package org.o7planning.tutorial.servlet;

import java.io.IOException;

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


public class HelloServlet extends HttpServlet {
   
   private static final long serialVersionUID = 1L;

   
   public HelloServlet() {
   }

   @Override
   protected void doGet(HttpServletRequest request,
           HttpServletResponse response) throws ServletException, IOException {
       
       ServletOutputStream out = response.getOutputStream();
       
       out.println("<html>");
       out.println("<head><title>Hello Servlet</title></head>");
       
       out.println("<body>");
       out.println("<h3>Hello World</h3>");
       out.println("This is my first Servlet");
       out.println("</body>");
       out.println("<html>");
   }

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

}
Это изображение Hello Servlet  созданное  со многими ошибками. Эти ошибки просто из-за того, что вы еще объявили библиотеку Servlet.
Нужно объявить библиотеку Servlet, эти библиотеки являьтся библиотекой Runtime в Servlet, она есть на Web Server, здесь мы используем Tomcat, поэтому, объявите их.  

Щелкните правой кнопкой мыши на проект и выберите Properties:
Теперь проект не имеет сообщение об ошибке.
Next you need to declare HelloServlet and a path to access it in web.xml. You need to add the following configuration:
<!-- Define servlet, named helloServlet -->
<servlet>
   <servlet-name>helloServlet</servlet-name>
   <servlet-class>org.o7planning.tutorial.servlet.HelloServlet</servlet-class>
</servlet>

<!-- Defines the path to access this Servlet -->
<servlet-mapping>
   <servlet-name>helloServlet</servlet-name>
   <url-pattern>/hello</url-pattern>
</servlet-mapping>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">
   <display-name>ServletTutorial</display-name>

   
   <servlet>
       <servlet-name>helloServlet</servlet-name>
       <servlet-class>org.o7planning.tutorial.servlet.HelloServlet</servlet-class>
   </servlet>

   <servlet-mapping>
       <servlet-name>helloServlet</servlet-name>
       <url-pattern>/hello</url-pattern>
   </servlet-mapping>


   <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>


</web-app>
Перезапустите проект через нажатие правой кнопки мыши на выбор:
  • Run As/Run on Server
Вы можете посмотреть принцип его работы в иллюстрации ниже:
Когда Servlet вызывается, в зависимости от ситуации, вызывается один из двух методов  doGet(..) или doPost(..).
  • В частности, когда вызывается doGet(..) и когда вызывается doPost(..) мы обсудим позже.
В doGet() или doPost() вы можете получить объекты ServletOutputStream, это выходной поток (output stream), он отправляет данные браузеру пользователя. Вызвать  ServletOutputStream.println(..), чтобы записать текст в поток (stream).
// The output stream to send data to user's browser

ServletOutputStream out = response.getOutputStream();

9- Инициализированные параметры Servlet

Когда объявляется servlet в web.xml вы можете передать параметры инициализации для него.
InitParamServlet.java
package org.o7planning.tutorial.servlet;

import java.io.IOException;

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

public class InitParamServlet extends HttpServlet {

   private static final long serialVersionUID = 1L;

   private String emailSupport1;

   public InitParamServlet() {
   }

   // Method này luôn luôn được gọi 1 lần ngay sau khi đối tượng Servlet được tạo ra.
   @Override
   public void init(ServletConfig config) throws ServletException {
       super.init(config);

       // Lấy ra thông tin tham số khởi tạo của Servlet
       // (Theo Cấu hình của Servlet này trong web.xml).
       this.emailSupport1 = config.getInitParameter("emailSupport1");
   }

   @Override
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {

       // Bạn có thể lấy ra tham số khởi tạo theo cách khác.
       String emailSupport2 = this.getServletConfig().getInitParameter("emailSupport2");

       ServletOutputStream out = response.getOutputStream();

       out.println("<html>");
       out.println("<head><title>Init Param</title></head>");

       out.println("<body>");
       out.println("<h3>Init Param</h3>");
       out.println("<p>emailSupport1 = " + this.emailSupport1 + "</p>");
       out.println("<p>emailSupport2 = " + emailSupport2 + "</p>");
       out.println("</body>");
       out.println("<html>");
   }

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

}
Конфигурация servlet в web.xml:
<servlet>
    <servlet-name>initParamServlet</servlet-name>
    <servlet-class>org.o7planning.tutorial.servlet.InitParamServlet</servlet-class>
    
    <init-param>
        <param-name>emailSupport1</param-name>
        <param-value>abc@example.com</param-value>
    </init-param>

    <init-param>
        <param-name>emailSupport2</param-name>
        <param-value>tom@example.com</param-value>
    </init-param>

</servlet>    


<servlet-mapping>
    <servlet-name>initParamServlet</servlet-name>
    <url-pattern>/initParam</url-pattern>
</servlet-mapping>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">
   <display-name>ServletTutorial</display-name>

   
   <servlet>
       <servlet-name>helloServlet</servlet-name>
       <servlet-class>org.o7planning.tutorial.servlet.HelloServlet</servlet-class>
   </servlet>

   <servlet-mapping>
       <servlet-name>helloServlet</servlet-name>
       <url-pattern>/hello</url-pattern>
   </servlet-mapping>


   <servlet>
       <servlet-name>initParamServlet</servlet-name>
       <servlet-class>org.o7planning.tutorial.servlet.InitParamServlet</servlet-class>
       
       <init-param>
           <param-name>emailSupport1</param-name>
           <param-value>abc@example.com</param-value>
       </init-param>
       
       <init-param>
           <param-name>emailSupport2</param-name>
           <param-value>tom@example.com</param-value>
       </init-param>
       
   </servlet>    
   
   
   <servlet-mapping>
       <servlet-name>initParamServlet</servlet-name>
       <url-pattern>/initParam</url-pattern>
   </servlet-mapping>


   
   <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>


</web-app>
Перезапустить веб приложение:

10- Конфигурация Servlet используя Annotation

С Servlet начиная от версии 3.0 можно конфигурировать Servlet используя Annotation, в этом проекте мы используем Servlet версии 3.x, так что мы можем использовать Annotation для конфигурации. Рассмотрим иллюстрированный пример.
AnnotationExampleServlet.java
package org.o7planning.tutorial.servlet;

import java.io.IOException;

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


// You can configure one or multiple paths can access this Servlet
@WebServlet(urlPatterns = { "/annotationExample" , "/annExample" },
     initParams = {
         @WebInitParam(name = "emailSupport1", value = "abc@example.com"),
         @WebInitParam(name = "emailSupport2", value = "tom@example.com")
     }         
)
public class AnnotationExampleServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    
    private String emailSupport1;

    public AnnotationExampleServlet() {
    }


    // In any case, init() is guaranteed to be called before the servlet handles its first request.
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    
        this.emailSupport1 = config.getInitParameter("emailSupport1");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        String emailSupport2 = this.getServletConfig().getInitParameter("emailSupport2");

        ServletOutputStream out = response.getOutputStream();

        out.println("<html>");
        out.println("<head><title>Init Param</title></head>");

        out.println("<body>");
        out.println("<h3>Servlet with Annotation configuration</h3>");
        out.println("<p>emailSupport1 = " + this.emailSupport1 + "</p>");
        out.println("<p>emailSupport2 = " + emailSupport2 + "</p>");
        out.println("</body>");
        out.println("<html>");
    }

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

}
Вы можете получить доступ к этому Servlet в одном из этих 2 ссылок:

11- Servlet Url Pattern

Есть 4 способа конфигурации ссылки для Servlet:
URL Pattern Examples
/* http://example.com/contextPath
http://example.com/contextPath/status/abc
/status/abc/* http://example.com/contextPath/status/abc
http://example.com/contextPath/status/abc/mnp
http://example.com/contextPath/status/abc/mnp?date=today
http://example.com/contextPath/test/abc/mnp
*.map http://example.com/contextPath/status/abc.map
http://example.com/contextPath/status.map?date=today
http://example.com/contextPath/status/abc.MAP
/ Đây là Servlet mặc định.
Когда пользователь вводит ссылку в браузере, то она будет отправлена в WebContainer. WebContainer должен решить, какой Servlet будет обслуживать этот запрос от пользователя.

На изображении ниже показано, как WebContainer решает  использовать  какой Servlet для обслуживания запроса от клиента.
Например, создать Servlet  с URL-pattern со звездочкой, например:
  • url-pattern = "/any/*";
AsteriskServlet.java
package org.o7planning.tutorial.servlet;

import java.io.IOException;

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

@WebServlet(urlPatterns = { "/any/*" })
public class AsteriskServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;

  public AsteriskServlet() {
  }

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {

      ServletOutputStream out = response.getOutputStream();

      out.println("<html>");
      out.println("<head><title>Asterisk</title></head>");

      out.println("<body>");
     
      out.println("<h3>Hi, your URL match /any/*</h3>");
     
      out.println("</body>");
      out.println("<html>");
  }

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

}
Эти URL имеющие следующий вид, обслуживаются AsteriskServlet (/any/*).

Servlet по умолчанию: 

Servlet с url-pattern = /

Это servlet по умолчанию, servlet будет использоваться для обработки запроса (request), который имеет ссылку несовпадающую ни с каким  url-pattern другого Servlet объявленный в вашем приложении.
Давайте посмотрим иллюстрированный пример с Servlet по умолчанию:
MyDefaultServlet.java
package org.o7planning.tutorial.servlet;

import java.io.IOException;

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

@WebServlet(urlPatterns = { "/" })
public class MyDefaultServlet extends HttpServlet {

   private static final long serialVersionUID = 1L;

   public MyDefaultServlet() {
   }

   @Override
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {

       ServletOutputStream out = response.getOutputStream();

       out.println("<html>");
       out.println("<head><title>Page not found</title></head>");

       out.println("<body>");
       out.println("<h3>Sorry! Page not found</h3>");
       out.println("<h1>404</h1>");
       out.println("Message from servlet: " + this.getClass().getName());
       out.println("</body>");
       out.println("<html>");
   }

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

}
Вы можете перезапустить веб приложение, а также перейти по ссылке:
Ссылка выше имеет  servletPath = /news/tomAndJerry, которая не совпадает ни с какой ссылкой Servlet, которую вы объявили. В то же время " Servlet по умолчанию" будет обслуживать этот запрос.

12- Получить основную информацию Servlet

Вы можете получить информацию, которая относится к услуге Servlet, например:
  1. Информация request от client.
  2. Информация Server 
  3. Информация Client
  4. Информация Header высыланное по запросу ....
ExampleInfoServlet.java
package org.o7planning.tutorial.servlet;

import java.io.IOException;
import java.util.Enumeration;

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

@WebServlet("/other/exampleInfo")
public class ExampleInfoServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;

  public ExampleInfoServlet() {
      super();
  }

  @Override
  protected void doGet(HttpServletRequest request,
          HttpServletResponse response) throws ServletException, IOException {
      ServletOutputStream out = response.getOutputStream();

      out.println("<style> span {color:blue;} </style>");

      String requestURL = request.getRequestURL().toString();
      out.println("<br><span>requestURL:</span>");
      out.println(requestURL);

      String requestURI = request.getRequestURI();
      out.println("<br><span>requestURI:</span>");
      out.println(requestURI);

      String contextPath = request.getContextPath();
      out.println("<br><span>contextPath:</span>");
      out.println(contextPath);

      out.println("<br><span>servletPath:</span>");
      String servletPath = request.getServletPath();
      out.println(servletPath);

      String queryString = request.getQueryString();
      out.println("<br><span>queryString:</span>");
      out.println(queryString);

      String param1 = request.getParameter("text1");
      out.println("<br><span>getParameter text1:</span>");
      out.println(param1);

      String param2 = request.getParameter("text2");
      out.println("<br><span>getParameter text2:</span>");
      out.println(param2);

      // Server Infos
      out.println("<br><br><b>Server info:</b>");

      out.println("<br><span>serverName:</span>");
      String serverName = request.getServerName();
      out.println(serverName);

      out.println("<br><span>serverPort:</span>");
      int serverPort = request.getServerPort();
      out.println(serverPort + "");

      // Client Infos
      out.println("<br><br><b>Client info:</b>");

      out.println("<br><span>remoteAddr:</span>");
      String remoteAddr = request.getRemoteAddr();
      out.println(remoteAddr);

      out.println("<br><span>remoteHost:</span>");
      String remoteHost = request.getRemoteHost();
      out.println(remoteHost);

      out.println("<br><span>remoteHost:</span>");
      int remotePort = request.getRemotePort();
      out.println(remotePort + "");

      out.println("<br><span>remoteUser:</span>");
      String remoteUser = request.getRemoteUser();
      out.println(remoteUser);

      // Header Infos
      out.println("<br><br><b>headers:</b>");

      Enumeration<String> headers = request.getHeaderNames();
      while (headers.hasMoreElements()) {
          String header = headers.nextElement();
          out.println("<br><span>" + header + "</span>: "
                  + request.getHeader(header));
      }

      // Servlet Context info:
      out.println("<br><br><b>Servlet Context info:</b>");
      ServletContext servletContext = request.getServletContext();

      // Location of web application in hard disk
      out.println("<br><span>realPath:</span>");
      String realPath = servletContext.getRealPath("");
      out.println(realPath);
  }

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

}
Смотрите иллюстрацию ниже, с информацией, которая вас интересует:
Перезапустить веб приложение и получить доступ к ссылке:
Полученные результаты:

13- Forward (Пересылка)

Пересылка (Forward): Когда запрос (request) браузера  отправлен к Servlet, он может переслать запрос на другую страницу (или другой servlet). Адрес на браузере пользователя  так же является ссылкой первой страницы, но содержание страницы создавается страницой пересылки.

Пересылающая страница обязательно должна быть  одной страницей (или Servlet) в вашем веб приложении.

С Forward вы можете использовать request.setAttribute() для передачи данных от страницы 1 к странице 2.
ForwardDemoServlet.java
package org.o7planning.tutorial.servlet.other;

import java.io.IOException;

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

import org.o7planning.tutorial.beans.Constants;

@WebServlet("/other/forwardDemo")
public class ForwardDemoServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;

   @Override
   protected void doGet(HttpServletRequest request,
           HttpServletResponse response) throws ServletException, IOException {
       // Get parameter on URL      
       // http://localhost:8080/ServletTutorial/other/forwardDemo?forward=true        
       String forward = request.getParameter("forward");

       if ("true".equals(forward)) {
           System.out.println("Forward to ShowMeServlet");

           // Send data to next page (page forward to)
           request.setAttribute(Constants.ATTRIBUTE_USER_NAME_KEY,
                   "Hi, I'm Tom come from Walt Disney !");

           RequestDispatcher dispatcher = request.getServletContext()
                   .getRequestDispatcher("/showMe");
           dispatcher.forward(request, response);

           return;
       }
       ServletOutputStream out = response.getOutputStream();
       out.println("<h3>Text of ForwardDemoServlet</h3>");
       out.println("- servletPath=" + request.getServletPath());
   }

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

}
Перезапустить  Webserver и запустить поочередно 2 URL:
В случае 1: Нет Forward, данные которые видите на страницах созданы с помощью  ForwardDemoServlet.
В Случае 2: Есть пересылка (forward) в Servlet ShowMeServlet. В этом случае URL на странице не меняется,  когда данные создавались  ShowMeServlet.
Forward (пересылка) часто используется в некоторых ситуациях,например пользователь запрашивает servlet A, однако эта страница требует сначала login, в servlet A проверяется , если еще не сделан login, то пересылает на servlet Login.
Вернемся к  RequestDispatcher, у нас есть два метода, чтобы получить объект RequestDispatcher.
Ситуация, когда   request.getServletContext ().getRequestDispatcher(url) возвращает RequestDispatcher с относительным расположением к  contextPath (расположен относительно к корневой папке вебсайта).
  • http://localhost:8080/contextPath
  • http://localhost:8080/ServletTutorial
При вызыове  request.getRequestDispatcher(url) возвращает RequestDispatcher  имеет расположение относительное текущей странице
  • http://localhost:8080/ServletTutorial/other/forwardDemo
Примечание:
  • Перенаправление (Redirect) позволяет вам перенаправлять на сайты, включая те, что за пределами вебсайта.
  • ​​​​​​​Пересылка (Forward) позволяет только пересылку к страницам в вебсайте, а также может передавать данные между двумя страницами через request.setAttribute.

14- Redirect (Перенаправление)

Перенаправление (Redirect): Когда запрос (request) от пользователя к Servlet (Страница А), этот Servlet может направить запрос на другую страницу (страница B), и закончить свою задачу. Страница может быть перенаправлена на страницу в вашем приложении, или может быть любой страницей. Адрес на браузере пользователя теперь отображает ссылку страницы B.
В отличии от пересылки  (Forward). С Redirect вы не можете использовать request.setAttribute (..) для передачи данных от страницы А на страницу B.
ShowMeServlet.java
package org.o7planning.tutorial.servlet.other;

import java.io.IOException;

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

import org.o7planning.tutorial.beans.Constants;

@WebServlet("/showMe")
public class ShowMeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

    // Get value of Attribute (Sent from forward page)
    String value = (String) request
            .getAttribute(Constants.ATTRIBUTE_USER_NAME_KEY);

    ServletOutputStream out = response.getOutputStream();

    out.println("<h1>ShowMeServlet</h1>");
    out.println(value);
}

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

}
RedirectDemoServlet.java
package org.o7planning.tutorial.servlet.other;

import java.io.IOException;

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

@WebServlet("/other/redirectDemo")
public class RedirectDemoServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;

  @Override
  protected void doGet(HttpServletRequest request,
          HttpServletResponse response) throws ServletException, IOException {
      // Get parameter on the URL
      // http://localhost:8080/ServletTutorial/other/redirectDemo?redirect=true
      String redirect = request.getParameter("redirect");

      if ("true".equals(redirect)) {
          System.out.println("Redirect to ShowMeServlet");
          // ContextPath always be "" or "/contextPath".    

          String contextPath = request.getContextPath();

          // ==> /ServletTutorial/showMe
          response.sendRedirect(contextPath + "/showMe");
          return;
      }

      ServletOutputStream out = response.getOutputStream();
      out.println("<h3>Text of RedirectDemoServlet</h3>");
      out.println("- servletPath=" + request.getServletPath());
  }

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

}
Перезапустить webserver и получить доступ поочередно к 2 следующим ссылкам на браузере:
С первой ссылкой получили:
Со 2-ой ссылкой, request перенаправил на ShowMeServlet, ссылка  URL которую вы видите на браузере - это ссылка servlet ShowMeServlet

15- Сессия (Session)

Объект HttpSession описывает одна сессия (session) пользователя. Сессия пользователя хранит много информации о пользователе, и через разные запросы (request), отправленные на HTTP server.

Когда пользователь в первый раз заходит на ваш сайт, пользователь получает только один ID с отличающийся от других пользователей. Этот ID часто хранится в cookie или параметре request 
Here is how you access the session object:
protected void doGet(HttpServletRequest request,
   HttpServletResponse response)
       throws ServletException, IOException {

   HttpSession session = request.getSession();
}
Вы можете хранить значения в объекте session, и получить их потом, возможно на другой странице. Прежде всего, давайте посмотрим, как вы можете сохранить значения в объекте session
// Get HttpSession object
HttpSession session = request.getSession();

// Suppose user has successfully logged.
UserInfo loginedInfo = new UserInfo("Tom", "USA", 5);

// Storing user information in Session under 1 attribute.
// You can retrieve user information in Session
session.setAttribute(Constants.SESSION_USER_KEY, loginedInfo);
И получить информацию, хранящуюся в Session на  определенной странице
// Get HttpSession object.
HttpSession session = request.getSession();

// Retrieving UserInfo object is stored in session
UserInfo loginedInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
Посмотреть полный пример:
LoginServlet.java
package org.o7planning.tutorial.servlet.session;

import java.io.IOException;

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

import org.o7planning.tutorial.beans.Constants;
import org.o7planning.tutorial.beans.UserInfo;

@WebServlet(urlPatterns = { "/login" })
public class LoginServlet extends HttpServlet {

   private static final long serialVersionUID = 1L;

   public LoginServlet() {
   }

   @Override
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {

       ServletOutputStream out = response.getOutputStream();


       // Get HttpSession object
       HttpSession session = request.getSession();

       // Suppose a user has successfully logged.
       UserInfo loginedInfo = new UserInfo("Tom", "USA", 5);
     
       // Storing user information in Session under 1 attribute.
       // You can retrieve user information in Session
       session.setAttribute(Constants.SESSION_USER_KEY, loginedInfo);

       out.println("<html>");
       out.println("<head><title>Session example</title></head>");

       out.println("<body>");
       out.println("<h3>You are logined!, info stored in session</h3>");

       out.println("<a href='userInfo'>View User Info</a>");
       out.println("</body>");
       out.println("<html>");
   }

}
UserInfoServlet.java
package org.o7planning.tutorial.servlet.session;

import java.io.IOException;

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

import org.o7planning.tutorial.beans.Constants;
import org.o7planning.tutorial.beans.UserInfo;

@WebServlet(urlPatterns = { "/userInfo" })
public class UserInfoServlet extends HttpServlet {

   private static final long serialVersionUID = 1L;

   public UserInfoServlet() {
   }

   @Override
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {

       ServletOutputStream out = response.getOutputStream();


       // Get HttpSession object
       HttpSession session = request.getSession();


       // Get UserInfo object stored in session after user login successful.
       UserInfo loginedInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);

       // If not logined, redirect to login page (LoginServlet).
       if (loginedInfo == null) {
           // ==> /ServletTutorial/login
           response.sendRedirect(this.getServletContext().getContextPath() + "/login");
           return;
       }

       out.println("<html>");
       out.println("<head><title>Session example</title></head>");

       out.println("<body>");

       out.println("<h3>User Info:</h3>");

       out.println("<p>User Name:" + loginedInfo.getUserName() + "</p>");
       out.println("<p>Country:" + loginedInfo.getCountry() + "</p>");
       out.println("<p>Post:" + loginedInfo.getPost() + "</p>");

       out.println("</body>");
       out.println("<html>");
   }

}
Запуск примера:

16- Руководство использования Servlet-Filter

Далее вы можете посмотреть статью о Servlet Filter (Фильтр servlet):

17- Руководство программирования JSP

После  Servlet вы можете изучить дальше  JSP по ссылке: