Hướng dẫn lập trình Java Servlet cho người mới bắt đầu
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- Giới thiệu

Tài liệu này được viết dựa trên:
  • Eclipse 4.5 (MARS) (ok for Eclipse 4.4 LUNA)

  • Servlet 3.0

  • Tomcat 8

Document History:
  • 05-07-2014: Document based on (Eclipse 4.3, Servlet 3.0, Tomcat 7.x)
  • 18-11-2014: Update to (Eclipse 4.4, Servlet 3.0, Tomcat 8.x)
  • 17-07-2015: Update to (Eclipse 4.5, Servlet 3.0, Tomcat 8.x, add more examples...)

2- Servlet là gì?

Java Servlets là chương trình chạy trên một Web hoặc ứng dụng máy chủ và hành động như một lớp trung gian giữa một yêu cầu đến từ một trình duyệt Web hoặc HTTP khách khác và cơ sở dữ liệu hoặc các ứng dụng trên máy chủ HTTP.

Sử dụng Servlets, bạn có thể thu thập đầu vào từ người dùng thông qua các hình thức trang web, từ một cơ sở dữ liệu hoặc một nguồn khác, và tạo ra các trang web động.

3- Vòng đời của Servlet

Hình dưới đây minh họa về vòng đời của một Servlet. Từ khi nó được tạo ra, sử lý các đòi hỏi từ người dùng, cho tới lúc nó bị hủy.
Có 5 bước:
  1. Tải Servlet Class vào bộ nhớ.
  2. Tạo đối tượng Servlet.
  3. Gọi method servlets init()
  4. Gọi method servlets service().
  5. Gọi method servlets destroy().

Bước 1, 2 và 3 được thực thi một lần duy nhất, khi mà servlet được nạp lần đầu. Mặc định các servlet không được tải lên cho tới khi nó nhận một đòi hỏi đầu tiên từ người dùng. Bạn có thể buộc ServletContainer (Bộ chứa các servlet) tải các servlet khi nó khởi động.

Bước 4 được thực thi nhiều lần, mỗi khi có đòi hỏi từ phía người dùng tới servlet.
Bước 5 nó được thực thi khi bộ chứa servlet (Servlet Container) trút bỏ (unloaded) servlet.
Bạn có thể xem hình minh họa tiếp theo để hiểu hơn về vòng đời của Servlet.
Khi yêu cầu (request) của người dùng tới Servlet, servlet sẽ gọi phương thức service() để phục vụ yêu cầu của người dùng, service() sẽ gọi một trong hai phương thức doGet() hoặc doPost(). Trong servlet của bạn, bạn cần ghi đè và sử lý tại các phương thức này.

Như vậy khi người dùng gửi yêu cầu một Servlet, servlet sẽ được tạo ra tại thời điểm có yêu cầu lần đầu tiên tới, đồng thời sẽ gọi  phương thức init() của servlet để khởi tạo cho nó, init() được gọi duy nhất 1 lần. Phương thức destroy() dùng để hủy servlet, nó sẽ được gọi một lần duy nhất khi gỡ bỏ triển khai (undeloy) ứng dụng web hoặc tắt (shutdown) web server.
 

4- Cài đặt Tomcat Web Server

Để bắt đầu với Servlet, bạn cần download Tomcat Web Server và khai báo nó với Eclipse. Bạn có thể xem hướng dẫn tại:

5- Tạo Web Project bắt đầu với Servlet

  • File/New/Other
  • Project Name: ServletTutorial
Đây là hình ảnh Project được tạo ra:
Tạo file 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- Cấu hình Eclipse để chạy Web trên tomcat

Cho tới lúc này, chúng ta vẫn chưa làm gì tới Servlet. Và giờ chúng ta cấu hình để chạy được ứng dụng web kia. Sau đó chúng mới bắt đầu với Servlet.
Trên eclipse, nhấn phải vào Project ServletTutorial, chọn Properties:
Chọn đến vị trí cài đặt Tomcat 8 của bạn.
Nhấn phải chuột vào project ServletTutorial, chọn "Run As/Run on Server".
Website chạy trên trình duyệt của Eclipse.
Nguyên tắc hoạt động:
Khi bạn nhập vào đường dẫn: Thì website sẽ trả về nội dung trang index.html, điều này hoàn toàn dễ hiểu.

Tuy nhiên, nếu bạn nhập vào đường dẫn: Điều đó có nghĩa là bạn không chỉ định rõ trang nào, webserver sẽ tìm trang mặc định khai báo trong thẻ <welcome-file> mà bạn khai báo trong web.xml để trả về.

Ghi chú: /ServletTutorial được gọi là Context-Path, mỗi website đều có Context-Path, bạn có thể cấu hình cho nó một giá trị khác, hoặc để rỗng. Trong trường hợp rỗng bạn có thể truy cập vào web của bạn theo cách:

  • http://localhost:8080
  • http://localhost:8080/index.html
Khi chạy với Tomcat mặc định nó lấy tên Project làm Context-Path. Khi lập trình bạn không phải lo lắng gì về điều này.
Hãy xem hình minh họa sau:

7- Một số class tham gia vào các ví dụ

Một số class sẽ tham gia vào các ví dụ tiếp theo của tài liệu này.
  • 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- Tạo Servlet đầu tiên của bạn

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);
   }

}
Đây là hình ảnh HelloServlet vừa được tạo ra với đầy lỗi. Các lỗi này đơn giản chỉ là bạn chưa khai báo thư viện Servlet.
Cần khai báo thư viện Servlet, các thư viện này chỉ là các thư viện Runtime của Servlet, nó có sẵn trên các Web Server, ở đây chúng ta dùng Tomcat, vì vậy hãy khai báo chúng.

 Nhấn phải chuột vào Project chọn Properties:
Lúc này project đã không còn thông báo lỗi.
Tiếp theo bạn cần khai báo HelloServlet và đường dẫn để truy cập vào nó trong web.xml. Bạn cần thêm đoạn cấu hình sau:
<!-- Định nghĩa servlet có tên helloServlet, gắn với class HelloServlet -->
<servlet>
   <servlet-name>helloServlet</servlet-name>
   <servlet-class>org.o7planning.tutorial.servlet.HelloServlet</servlet-class>
</servlet>

<!-- Định nghĩa đường dẫn truy cập vào Servlet này -->
<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>
Chạy lại project bằng cách nhấn phải chuột chọn:
  • Run As/Run on Server
Bạn có thể xem nguyên tắc hoạt động của nó theo hình minh họa dưới đây:
Khi một Servlet được gọi tới, tùy tình huống mà một trong hai phương thức doGet(..) hoặc doPost(..) sẽ được gọi.
  • Cụ thể khi nào gọi doGet(..) và khi nào gọi doPost(..) chúng ta sẽ bàn sau.
Trong doGet() hoặc doPost() bạn có thể lấy ra đối tượng ServletOutputStream, đây là luồng đầu ra gửi dữ liệu về trình duyệt của người dùng. Gọi ServletOutputStream.println(..) để ghi các dòng text vào trong luồng.
// Luồng đầu ra, gửi dữ liệu về phía trình duyệt của người dùng.

ServletOutputStream out = response.getOutputStream();

9- Tham số khởi tạo Servlet

Trong khi khai báo servlet trong web.xml bạn có thể truyền các tham số khởi tạo cho nó.
  • 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);
    }

}
Cấu hình trong 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>
Chạy lại ứng dụng web:

10- Cấu hình Servlet sử dụng Annotation

Với Servlet version 3.0 trở lên bạn có thể cấu hình Servlet sử dụng Annotation, trong project này chúng ta đang sử dụng Servlet phiên bản 3.x vì vậy chúng ta có thể sử dụng Annotation để cấu hình. Hãy xem một ví dụ minh họa.
  • 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;

// Bạn có thể cấu hình một hoặc nhiều đường dẫn truy cập vào Servlet này.
@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() {
   }

   // Method được gọi trước lần phục vụ đầu tiên của servlet này.
   @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);
   }

}
Bạn có thể truy cập Servlet này theo một trong 2 đường dẫn sau:

11- Servlet Url Pattern

Có 4 cách để cấu hình một đường dẫn cho Servlet:
URL Pattern Ví dụ
/* 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.
Khi người dùng nhập vào một đường dẫn trên trình duyệt, nó sẽ được gửi tới WebContainer. WebContainer cần phải quyết định xem Servlet nào sẽ phục vụ yêu cầu này từ phía người dùng.

Hình dưới đây minh họa cách WebContainer quyết định sử dụng Servlet nào để phục vụ yêu cầu từ Client.
Ví dụ tạo một Servlet với url-pattern có dấu hoa thị, chẳng hạn:
  • 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);
   }

}
Các URL có dạng sau đều được phục vụ bởi AsteriskServlet (/any/*).

Servlet mặc định:

Servlet với url-pattern = /

Là một servlet mặc định, servlet  này sẽ được sử dụng để sử lý các request mà có đường dẫn không khớp với bất kỳ một url-pattern nào của các Servlet được khai báo trong ứng dụng của bạn.
Hãy xem một ví dụ minh họa với Servlet mặc định:
  • 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);
    }

}
Bạn có thể chạy lại ứng dụng web, và truy cập đường dẫn:
Đường dẫn ở trên có servletPath = /news/tomAndJerry, không khớp với đường dẫn của Servlet nào bạn đã khai báo. Khi đó "Servlet mặc định" sẽ phục vụ request này.

12- Lấy các thông tin cơ bản của Servlet

Bạn có thể lấy ra các thông tin liên quan tới lần phục vụ của Servlet chẳng hạn:
  1. Thông tin request từ client.
  2. Thông tin Server
  3. Thông tin Client
  4. Thông tin Header gửi theo request
  5. ....
  • 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);
   }

}
Hãy xem hình minh họa dưới đây, với các thông tin mà bạn quan tâm:
Chạy lại ứng dụng web và truy cập vào đường dẫn:
Kết quả nhận được:

13- Forward (Chuyển tiếp)

Chuyển tiếp (Forward): Khi một yêu cầu (request) tới một Servlet, nó có thể chuyển tiếp yêu cầu tới một trang khác (hoặc một servlet khác). Địa chỉ trên trình duyệt của người dùng vẫn là đường dẫn của trang đầu tiên, nhưng nội dung của trang do trang được chuyển tiếp tới tạo ra.

Trang được chuyển tiếp tới bắt buộc phải là môt trang (hoặc Servlet) thuộc vào ứng dụng web của bạn.

Với Forward bạn có thể sử dụng request.setAttribute() để truyền dữ liệu từ trang 1 sang trang thứ 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 {
      // Lấy parameter trên URL
      // http://localhost:8080/ServletTutorial/other/forwardDemo?forward=true      
     String forward = request.getParameter("forward");

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

         // Có thể gửi dữ liệu sang trang mới.
         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);
 }

}
Chạy lại Webserver và chạy lần lượt 2 URL:
Trong trường hợp 1: Không có forward, dữ liệu nhìn thấy trên trang là của ForwardDemoServlet tạo ra.
Trường hợp 2: Có forward sang servlet ShowMeServlet. Trong trường hợp này URL trên trang là không đổi, trong khi dữ liệu là của ShowMeServlet tạo ra.
Forward (chuyển tiếp) thường được sử dụng trong một số tình huống chẳng hạn người dùng yêu cầu servlet A, tuy nhiên trang này bắt buộc phải login trước, trong servlet A kiểm tra thấy nếu chưa login thì chuyển tiếp sang servlet Login.
Quay lại với RequestDispatcher, chúng ta có 2 cách để lấy đối tượng RequestDispatcher.
Trường hợp request.getServletContext().getRequestDispatcher(url) trả về RequestDispatcher có vị trí tương đối với contextPath (có vị trí tương đối với thư mục gốc của website).
  • http://localhost:8080/contextPath
  • http://localhost:8080/ServletTutorial
Trường hợp request.getRequestDispatcher(url) trả về RequestDispatcher có vị trí tương đối với trang hiện tại.
  • http://localhost:8080/ServletTutorial/other/forwardDemo
Vì vậy URL truyền vào bạn cần tính đến ví trí tương đối này.

Chú ý:

  • Redirect (Chuyển hướng) cho phép bạn chuyển hướng tới các trang bao gồm cả các trang nằm ngoài Website.
  • Forward (Chuyển tiếp) chỉ cho phép chuyển tới các trang nằm trong Website, đồng thời có thể chuyển dữ liệu giữa 2 trang thông qua request.setAttribute.

14- Redirect (Chuyển hướng)

Chuyển hướng (Redirect): Khi một yêu cầu (request) từ phía người dùng tới một Servlet (Trang A), servlet này có thể chuyển yêu cầu này tới một trang khác (Trang B), và kết thúc nhiệm vụ của nó. Trang được chuyển hướng tới có thể là trang trong ứng dụng của bạn, hoặc có thể là một trang bất kỳ. Địa chỉ trên trình duyệt của người dùng lúc này sẽ hiển thị đường dẫn của trang B.

Khác với chuyển tiếp (Forward). Với Redirect bạn không thể sử dụng request.setAttribute(..) để truyền dữ liệu từ trang A sang trang 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 {

       // Lấy giá trị trong Attribute gửi tới (Từ trang forward).
       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 {
        // Lấy parameter trên 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 luôn luôn là "" hoặc "/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);
    }

}
Chạy lại webserver và gõ lần lượt 2 đường dẫn sau lên trình duyệt:
Với đường dẫn thứ nhất nhận được:
Với đường dẫn thứ 2, request đã chuyển hướng sang ShowMeServlet, đường dẫn URL bạn thấy trên trình duyệt là đường dẫn của servlet ShowMeServlet.

15- Phiên làm việc (Session)

Đối tượng HttpSession mô tả một phiên làm việc (session) của người dùng. Một phiên làm việc của người dùng chứa nhiều thông tin người dùng trên nhiều yêu cầu (request) đã gửi tới HTTP server.

Khi lần đầu tiên người dùng vào trang web của bạn, người dùng sẽ nhận được một ID duy nhất phân biệt với các người dùng khác. ID này thường được lưu trữ trong cookie hoặc tham số của request.

Here is how you access the session object:
protected void doGet(HttpServletRequest request,
   HttpServletResponse response)
       throws ServletException, IOException {

   HttpSession session = request.getSession();
}
Bạn có thể lưu trữ các giá trị vào đối tượng session, và lấy chúng ra sau đó, có thể là tại một trang khác. Trước hết, hãy xem cách bạn có thể lưu trữ giá trị vào trong đối tượng session:
// Lấy ra đối tượng HttpSession
HttpSession session = request.getSession();

// Giả sử người dùng đã login thành công.
UserInfo loginedInfo = new UserInfo("Tom", "USA", 5);

// Lưu trữ thông tin người dùng vào Session theo 1 thuộc tính.
// Bạn có thể lấy lại thông tin người dùng theo thuộc tính này.
session.setAttribute(Constants.SESSION_USER_KEY, loginedInfo);
Và lấy lại các thông tin đã lưu trữ trong Session tại một trang nào đó.
// Lấy ra đối tượng HttpSession
HttpSession session = request.getSession();

// Lấy ra đối tượng UserInfo đã được lưu vào session
// sau khi người dùng login thành công.
UserInfo loginedInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
Xem ví dụ đầy đủ:
  • 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();

       // Lấy ra đối tượng HttpSession
       HttpSession session = request.getSession();

       // Giả sử người dùng đã login thành công.
       UserInfo loginedInfo = new UserInfo("Tom", "USA", 5);

       // Lưu trữ thông tin người dùng vào Session theo 1 thuộc tính.
       // Bạn có thể lấy lại thông tin người dùng theo thuộc tính này.
       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();

       // Lấy ra đối tượng HttpSession
       HttpSession session = request.getSession();

       // Lấy ra đối tượng UserInfo đã được lưu vào session
       // sau khi người dùng login thành công.
       UserInfo loginedInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);

       // Chưa login, chuyển hướng về trang login (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>");
   }

}
Chạy ví dụ:

16- Hướng dẫn sử dụng Servlet-Filter

Tiếp theo bạn có thể xem tiếp tài liệu về Filter trong Servlet:

17- Hướng dẫn lập trình JSP

Tiếp theo Servlet bạn có thể tìm hiểu tiếp JSP tại đây: