JavaWeb Express Servlet (request forwarding and request redirection)

Table of contents

1. HttpServletRequest

        1 Introduction: 

        2. Commonly used methods: 

            1st getRequestURI() : 

            2° getRequestURL() :

            3° getRemoteHost() : 

            4° getHeader(String header) : 

            5° getParameter(name) : 

            6° getParameterValues(name) : 

            7° getMethod() :

            8° setAttribute(key, value) : 

            9° getAttribute(key) : 

            10° getRequestDispatcher() :

        3. Demonstration of obtaining form data: 

        4. Usage details: 

2. Request forwarding

        1.Basic introduction: 

        2. Application examples: 

        3. Request forwarding details: 

三、HttpServletResponse

        1.Basic introduction: 

        2. Commonly used methods: 

        3.Solution to garbled code problem: 

4. Request redirection

        1.Basic introduction: 

        2. Application examples: 

        3. Usage details: 

5. Summary of Servlet (Part 2)


1. HttpServletRequest

        1 Introduction: 

        The HttpServletRequest object represents the client's request. When the client / browser accesses the server through the HTTP protocol, all information in the HTTP request header is encapsulated in this object ;
        By calling the corresponding API through the HttpServletRequest object, you can obtain the request information from the client.
        The class diagram of the HttpServletRequest interface is as follows: 

        2. Commonly used methods: 

            1st getRequestURI() : 

                Get the requested uniform resource identifier (resource path); eg:  /Servlet_Demo/countServlet

            2° getRequestURL() :

                Get the requested Uniform Resource Locator (absolute path); eg: http://localhost:8080/Servlet_Demo/countServlet
                PS: URL is a subset of URI (more specific).

            3° getRemoteHost() : 

                Get the client’s hostname ;

            4° getHeader(String header) : 

                Get request header ;

            5° getParameter(name) : 

                Get the parameters of the request ; ( name can be text, password, radio, select or the name attribute value of textarea )

            6° getParameterValues(name) : 

                Get the requested parameters (multiple values) ; eg: array returned by checkbox

            7° getMethod() :

                The method of obtaining the request ; eg: GET, POST, etc.

            8° setAttribute(key, value) : 

                Set domain data ;

            9° getAttribute(key) : 

                Get domain data ;

            10° getRequestDispatcher() :

                Get the request forwarding object (the core object that implements "request forwarding")

       3. Demonstration of obtaining form data: 

                The static page registerEX.html is as follows: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
    <style>
        table,tr,td {
            border:2px solid cornflowerblue;
            border-collapse: collapse;
            margin-left:auto;
            margin-right:auto;
            /*padding: 10px;*/
        }
        #tr_1 {
            text-align: center;
        }
    </style>
</head>
<body>
<form action="http://localhost:8080/Servlet_Demo/httpServletRequestMethods" method="post">
<table>
    <tr>
        <th colspan="2">User Register</th>
    </tr>
    <tr>
        <td>username:</td>
        <td><input type="text" name="username"/></td>
    </tr>
    <tr>
        <td>password:</td>
        <td><input type="password" name="password"/></td>
    </tr>
    <tr>
        <td>Choose your favorite fruit:</td>
        <td><input type="checkbox" name="fruit" value="apple"/>Apple<br/>
            <input type="checkbox" name="fruit" value="strawberry"/>Strawberry<br/>
            <input type="checkbox" name="fruit" value="grape"/>Grape</td>
    </tr>
    <tr id="tr_1">
        <td><input type="submit" value="register"/></td>
        <td><input type="reset" value="reset"/></td>
    </tr>
</table>
</form>
</body>
</html>

                The page effect is as shown below: 

                The HttpServletRequestMethods class code is as follows: 

package down;

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

import java.io.IOException;

/**
    (1)若重写后的doPost方法中没有做任何处理,是默认的super.doPost(req, resp);
        这种情况下,浏览器会报405状态码(方法不允许)
    (2)HTTP请求的内容主要分为两大类 ———— 请求头和请求体(也叫请求参数)
 */

//通过注解方式配置url
@WebServlet(urlPatterns = {"/httpServletRequestMethods"})
public class HttpServletRequestMethods extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取请求的统一资源标识符URI
        String requestURI = req.getRequestURI();
        System.out.println("URI = " + requestURI);

        //2.获取请求的统一资源定位符URL
        //PS:URL是URI的一个子集(更具体)。
        StringBuffer requestURL = req.getRequestURL();
        System.out.println(("URL = " + requestURL));

        //3.获取客户端的主机地址
        String remoteHost = req.getRemoteHost();
        System.out.println("Host's IP = " + remoteHost);
            //获取客户端的IP地址
        String remoteAddr = req.getRemoteAddr();
        System.out.println("Addr = " + remoteAddr);

        //4.获取请求头
            //客户端的主机名(IP + 端口)
        String host = req.getHeader("Host");
        System.out.println("Host = " + host);
            //请求的发起地址
        String referer = req.getHeader("Referer");
        System.out.println("Referer = " + referer);
            //请求的用户信息
        String userAgent = req.getHeader("User-Agent");
        System.out.println("User-Agent = " + userAgent);
        System.out.println("Browser = " + userAgent.split(" ")[userAgent.split(" ").length - 1]);

/*======================================获取表单数据======================================*/
        //5.获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("text = " + username);
        System.out.println("password = " + password);

        //6.获取请求的参数(多个值)
        String[] fruits = req.getParameterValues("fruit");
        for (String fruit : fruits) {
            System.out.println("The checkbox elements you choose:" + fruit);
        }

        //7.获取请求的方式(GET POST etc)
        String method = req.getMethod();
        System.out.println("method = " + method);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

                Operation effect: (GIF picture below)

        4. Usage details: 

        To prevent the problem of "garbled data in form submission" , you can call the req.setCharacterEncoding("utf-8") method before using the req.getParameter(string) method.

        To prevent the problem of "garbled data returned by the server to the browser" , you can call the resp.setContentType("text/html; charset=utf-8") method before obtaining the PrintWriter object. (Corresponding to the response header Content-Type of the Http response)


2. Request forwarding

        1.Basic introduction: 

        When the business is complex, a request may require multiple Servlets to complete (eg: pipeline operation of Servlet chain). As shown below: 

        Request forwarding means that after a web resource receives a client request, it notifies the server to call another web resource for processing .

        The HttpServletRequest object provides the getRequestDispatcher method, which returns a RequestDispatcher object. Request forwarding can be implemented by calling the forward method of this object .

        The HttpServletRequest object is also a domain object. Developers can use the HttpServletRequest object to bring data to other web resources for processing through the request object when forwarding .

        Commonly used methods are as follows -

  •         setAttribute method
  •         getAttribute method
  •         removeAttribute method
  •         getAttributeNames method

        2. Application examples: 

                It is required to define two servlet resources, VerifyServlet and ReplyServlet. The former is used to verify the data submitted by the form and allows Tomcat to call ReplyServlet to process the verified data; the latter is used to process the data and feed it back to the browser.

               The register.html code is as follows: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
</head>
<body>
    <h1>User Register</h1>
    <form action="http://localhost:8080/Servlet_Demo/verifyServlet" method="post">
        username:<input type="text" name="username"/> <br/><br/>
        <input type="submit" value="register"/>
    </form>
</body>
</html>

                The VerifyServlet class code is as follows: 

package down.req;

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

import java.io.IOException;

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
@WebServlet(urlPatterns={"/verifyServlet"})
public class VerifyServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("VerifyServlet's doPost is invoked~");

        req.setCharacterEncoding("utf-8");

        String username = req.getParameter("username");
        if ("Cyan".equals(username)) {
            req.setAttribute("status", "Manager");
        } else {
            req.setAttribute("status", "Employee");
        }

        /**
         (1) /replyServlet是要转发的servlet的url
         (2) "/"会被Tomcat解析成"/Servlet_Demo/",即当前Web工程路径
            如果开头没写/,默认会隐含一个/。
         (3) forward(request,response)表示把当前servlet的request对象和response对象,
            传递给下一个servlet使用 (相同)
         */
        //获取分发器
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/replyServlet");
        requestDispatcher.forward(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

               The ReplyServlet class code is as follows: 

package down.req;

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

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

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
@WebServlet(urlPatterns = {"/replyServlet"})
public class ReplyServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReplyServlet's doPost is invoked~");

        String username = req.getParameter("username");
        String status = (String) req.getAttribute("status");

        resp.setContentType("text/html; charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print("" +
                "<table border=\"2px\"; bordercolor=\"pink\" cellspacing=\"0\" cellpadding=\"10px\">" +
                    "<tr>" +
                        "<td colspan = 2>The data you submitted : </td>" +
                    "</tr>" +
                    "<tr>" +
                        "<th>username: </th>" +
                        "<th>" + username + "</th>" +
                    "</tr>" + "<tr><th>status: </th><th>" + status + "</th>" +
                    "</tr>" +
                "</table>");

        writer.flush();
        writer.close();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

                Operation effect: (GIF picture below)

        3. Request forwarding details: 

  1.         The URL in the browser address bar will not change (the address will remain the URL of the first servlet) . Because the entire process of "request forwarding" is performed on the server side and has nothing to do with the browser ; in the end, Tomcat still responds to the browser in the form of an HTTP response.
  2.         Multiple forwardings can be made in the same HTTP request; multiple forwardings can be made in the same HTTP request, and multiple Servlets can share the data of the request field/object (because it is always the same request object).
  3.         "Request forwarding" can also be forwarded to the WEB-INF directory (for project use)
  4.         "Request forwarding" cannot access resources outside the current WEB project . (404)
  5.         Because the browser address bar will stop at the first servlet, if the page is refreshed, the request will be issued again (and the data will be carried), so do not use request forwarding in situations such as payment pages , otherwise it will cause repeated payments.

三、HttpServletResponse

        1.Basic introduction: 

         Every time an HTTP request is issued, Tomcat will create an HttpServletResponse object and pass it to the Servlet program for use .
        HttpServletRequest represents the requested information, while HttpServletResponse represents all response information. If you need to set the information returned to the client, you can set it through the HttpServletResponse object ( in the end, Tomcat still returns the data to the client in the form of an HTTP response. ).
        The HttpServletResponse class diagram is as follows: 

        2. Commonly used methods: 

        1. Byte stream getOutputStream():

                Commonly used for downloading files (processing binary data)

        2. Character stream getWriter(): (used in the previous example)

                Commonly used to echo string
        Δ details:

                Only one of the two streams can be used at the same time - if you use the byte stream, you cannot use the character stream, and vice versa, otherwise an error will be reported.

        3.Solution to garbled code problem: 

        Method 1 - the old method (the best):

                resp.setContentType("text/html; charset = utf-8"); 

                The setContentType method will set both the server and the client to use utf-8 character set encoding, and also set the response header, but setContentType must be called before obtaining the stream object .
        Method 2 - New method (also OK):

                resp .setCharacterEncoding("utf-8");        //First set the server to use utf-8 encoding

                resp. setHeader ("Content-Type", "text/html; charset = utf-8");         /*Set the browser-side encoding through the response header */


4. Request redirection

        1.Basic introduction: 

         Request redirection means: after a web resource receives a client request, it notifies the client to access another web resource. This is called request redirection.
        In request redirection, the servlet responsible for the redirection function will modify the response status code to 302 (indicating request redirection), and then set a Location attribute to inform the browser which resource to access in the next request . [Achieved through sendRedirect("/web project name/web resource") method] 

        2. Application examples: 

                A page with a hyperlink requires the hyperlink to lead to a servlet, and the servlet will notify the browser to access another servlet through "request redirection". (Servlet is configured here using annotations)

                The redirection.html code is as follows: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Redirection Demo</title>
</head>
<body>
    <h1>⭐408资料分享⭐</h1>
    <a href="http://localhost:8080/Servlet_Demo/old" target="_self">
        快点我!点我下载数据结构1800题!
    </a>
</body>
</html>

                The OldServlet class code is as follows: 

package down.resp;

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

import java.io.IOException;

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
@WebServlet(urlPatterns = {"/old"})
public class OldServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
            (1) sendRedirect方法本质上就会返回302(重定向)状态码,并且设置Location响应头;
            (2) 与请求转发不同,“请求重定向”的解析不是在服务器端进行的,而是由浏览器解析;
                此处的"/"会被浏览器解析为"http://localhost:8080/";
            (3) So, “请求重定向”时,sendRedirect方法中的格式必须是“/Web应用名/Web资源”
                注意第一个斜杠!(如果开头没有写斜杠,浏览器默认会以当前地址栏为准!注意区分!)
         */
        resp.sendRedirect("/Servlet_Demo/new");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

               The NewServlet class code is as follows: 

package down.resp;

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

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

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
@WebServlet(urlPatterns={"/new"})
public class NewServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //注意此处MIME类型的使用
        resp.setContentType("application/x-tar; charset=utf-8");
        //如果想看到浏览器地址栏的变化,可以使用"text/html"MIME类型

        PrintWriter writer = resp.getWriter();
        writer.print("数据结构1800题pdf!");
        writer.flush();
        writer.close();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

                Operation effect: (GIF picture below)

        3. Usage details: 

        The best application scenario of "302"  - website migration . For example, if the domain name of the website is changed, the original domain name is www.CyanRA9.com and is moved to the new domain name www.CyanRA9.cn, but the browser still crawls the original domain name. In this case, a request redirection can be used to solve the problem.

         When using "request redirection", the browser address bar will change (eventually staying at the URL of the new web resource), which is essentially two HTTP requests .

        "Request redirection" cannot share data in the HttpServletRequest field , because it is essentially two HTTP requests, which will generate two different HttpServletRequest objects.
        cannot be redirected to resources under /WEB-INF (protected)
        It can be redirected to resources other than the Web project , such as to other websites (such as Bing).
        There are two ways to redirect requests -

               (1) resp. sendRedirect ("/web project name/web resource"); //Recommend the first one!

                (2) or setStatus (302);

                      resp.setHeader("Location", "/Servlet_Demo/new");

        You can use the getServletContext().getContextPath() method to obtain the project path of the current Web project ( dynamically obtain the project path ). After obtaining the project path, pass it to the project path in the form of string concatenation (project path + specific web resources). The sendRedirect method makes URL configuration more flexible.


5. Summary of Servlet (Part 2)

       (1) Master the common methods of HttpServletRequest (eg: the difference between URL and URI; methods of obtaining request headers; various ways of obtaining form submission data )

        (2) Master the underlying principle of request forwarding (same domain object) and how to implement request forwarding.

       (3) Master the specific steps of HttpServletResponse to echo data to the browser, and how to solve the problem of garbled characters.

        (4) Master the underlying principles of request redirection and the specific implementation of redirection (note the difference with request forwarding format!)

        System.out.println("END---------------------------------------------------------------------------------"); 

Guess you like

Origin blog.csdn.net/TYRA9/article/details/131851094