JavaWeb Express Servlet (перенаправление и перенаправление запросов)

Оглавление

1. HttpServletRequest

        1. Введение: 

        2. Часто используемые методы: 

            1-й getRequestURI(): 

            2° getRequestURL() :

            3° getRemoteHost() : 

            4 ° getHeader (заголовок строки): 

            5° getParameter(name) : 

            6° getParameterValues(name) : 

            7° getMethod() :

            8° setAttribute(ключ, значение): 

            9° getAttribute(ключ) : 

            10° getRequestDispatcher() :

        3. Демонстрация получения данных формы: 

        4. Детали использования: 

2. Переадресация запроса

        1.Основное введение: 

        2. Примеры применения: 

        3. Запросите детали пересылки: 

Например, HttpServletResponse

        1.Основное введение: 

        2. Часто используемые методы: 

        3.Решение проблемы с искаженным кодом: 

4. Запросить перенаправление

        1.Основное введение: 

        2. Примеры применения: 

        3. Детали использования: 

5. Краткое описание сервлета (часть 2)


1. HttpServletRequest

        1. Введение: 

        Объект HttpServletRequest представляет запрос клиента.Когда клиент / браузер обращается к серверу через протокол HTTP , вся информация в заголовке HTTP-запроса инкапсулируется в этот объект ;
        Вызвав соответствующий API через объект HttpServletRequest, вы можете получить информацию запроса от клиента.
        Диаграмма классов интерфейса HttpServletRequest выглядит следующим образом: 

        2. Часто используемые методы: 

            1-й getRequestURI(): 

                Получите запрошенный универсальный идентификатор ресурса (путь к ресурсу), например:  /Servlet_Demo/countServlet.

            2° getRequestURL() :

                Получите запрошенный универсальный указатель ресурса (абсолютный путь), например: http://localhost:8080/Servlet_Demo/countServlet
                PS: URL-адрес — это подмножество URI (более конкретный).

            3° getRemoteHost() : 

                Получить имя хоста клиента ;

            4 ° getHeader (заголовок строки): 

                Получить заголовок запроса ;

            5° getParameter(name) : 

                Получите параметры запроса ; ( имя может быть текстом, паролем, радио, выбором или значением атрибута имени текстовой области )

            6° getParameterValues(name) : 

                Получите запрошенные параметры (несколько значений) ; например: массив, возвращаемый флажком.

            7° getMethod() :

                Метод получения запроса , например: GET, POST и т. д.

            8° setAttribute(ключ, значение): 

                Установить данные домена ;

            9° getAttribute(ключ) : 

                Получить данные о домене ;

            10° getRequestDispatcher() :

                Получите объект переадресации запросов (основной объект, реализующий «пересылку запросов»).

       3. Демонстрация получения данных формы: 

                Статическая страница RegisterEX.html выглядит следующим образом: 

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

                Эффект страницы показан ниже: 

                Код класса HttpServletRequestMethods выглядит следующим образом: 

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

                Эффект операции: (изображение GIF ниже)

        4. Детали использования: 

        Чтобы предотвратить проблему «искаженных данных при отправке формы» , вы можете вызвать метод req.setCharacterEncoding("utf-8") перед использованием метода req.getParameter(string).

        Чтобы предотвратить проблему «искаженных данных, возвращаемых сервером браузеру» , вы можете вызвать метод resp.setContentType("text/html; charset=utf-8") перед получением объекта PrintWriter. (Соответствует заголовку ответа Content-Type ответа Http)


2. Переадресация запроса

        1.Основное введение: 

        Когда бизнес сложен, для выполнения запроса может потребоваться несколько сервлетов (например, конвейерная работа цепочки сервлетов). Как показано ниже: 

        Пересылка запроса означает , что после того, как веб-ресурс получает запрос клиента, он уведомляет сервер о необходимости вызова другого веб-ресурса для обработки .

        Объект HttpServletRequest предоставляет метод getRequestDispatcher , который возвращает объект RequestDispatcher . Переадресацию запроса можно реализовать , вызвав метод пересылки этого объекта .

        Объект HttpServletRequest также является объектом домена. Разработчики могут использовать объект HttpServletRequest для переноса данных на другие веб-ресурсы для обработки через объект запроса при пересылке .

        Обычно используемые методы следующие:

  •         метод setAttribute
  •         метод getAttribute
  •         метод удаления атрибута
  •         метод getAttributeNames

        2. Примеры применения: 

                Необходимо определить два ресурса сервлета: VerifyServlet и ReplyServlet. Первый используется для проверки данных, отправленных формой, и позволяет Tomcat вызывать ReplyServlet для обработки проверенных данных; второй используется для обработки данных и передачи их обратно в браузер.

               Код Register.html выглядит следующим образом: 

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

                Код класса VerifyServlet выглядит следующим образом: 

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

               Код класса ReplyServlet выглядит следующим образом: 

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

                Эффект операции: (изображение GIF ниже)

        3. Запросите детали пересылки: 

  1.         URL-адрес в адресной строке браузера не изменится (адрес останется URL-адресом первого сервлета) . Потому что весь процесс «переадресации запроса» выполняется на стороне сервера и не имеет никакого отношения к браузеру , в итоге Tomcat всё равно отвечает браузеру в виде HTTP-ответа.
  2.         Несколько пересылок могут быть выполнены в одном и том же HTTP-запросе; несколько пересылок могут быть выполнены в одном и том же HTTP-запросе, и несколько сервлетов могут совместно использовать данные поля/объекта запроса (поскольку это всегда один и тот же объект запроса).
  3.         «Пересылку запроса» также можно перенаправить в каталог WEB-INF (для использования в проекте).
  4.         «Пересылка запроса» не может получить доступ к ресурсам за пределами текущего WEB-проекта . (404)
  5.         Поскольку адресная строка браузера остановится на первом сервлете, при обновлении страницы запрос будет выдан снова (и данные будут перенесены), поэтому не используйте пересылку запросов в таких ситуациях, как страницы оплаты , в противном случае это приведет к повторные платежи.

Например, HttpServletResponse

        1.Основное введение: 

         Каждый раз, когда выдается HTTP-запрос, Tomcat создает объект HttpServletResponse и передает его программе сервлета для использования .
        HttpServletRequest представляет запрошенную информацию, а HttpServletResponse представляет всю информацию ответа. Если вам нужно установить информацию, возвращаемую клиенту, вы можете установить ее через объект HttpServletResponse ( в конце концов, Tomcat все равно возвращает данные клиенту в виде HTTP-ответ. ).
        Диаграмма классов HttpServletResponse выглядит следующим образом: 

        2. Часто используемые методы: 

        1. Поток байтов getOutputStream():

                Обычно используется для загрузки файлов (обработка двоичных данных)

        2. Поток символов getWriter(): (использовался в предыдущем примере)

                Обычно используется для отображения деталей строки
        Δ :

                Одновременно можно использовать только один из двух потоков — если вы используете поток байтов, вы не можете использовать поток символов, и наоборот, иначе будет сообщено об ошибке.

        3.Решение проблемы с искаженным кодом: 

        Способ 1 – старый метод (самый лучший):

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

                Метод setContentType настроит как сервер, так и клиент использовать кодировку набора символов utf-8, а также установит заголовок ответа, но setContentType должен быть вызван до получения объекта потока .
        Способ 2 — Новый метод (тоже ОК):

                resp .setCharacterEncoding("utf-8");        //Сначала настройте сервер на использование кодировки utf-8

                соответственно setHeader ("Content-Type", "text/html; charset = utf-8");         /*Устанавливаем кодировку на стороне браузера через заголовок ответа */


4. Запросить перенаправление

        1.Основное введение: 

         Перенаправление запроса означает: после того, как веб- ресурс получает запрос клиента, он уведомляет клиента о доступе к другому веб- ресурсу.Это называется перенаправлением запроса.
        При перенаправлении запроса сервлет, ответственный за функцию перенаправления , изменит код состояния ответа на 302 (указывая на перенаправление запроса), а затем установит атрибут Location, чтобы сообщить браузеру, к какому ресурсу обращаться в следующем запросе . [Достигнуто с помощью метода  sendRedirect("/имя веб-проекта/веб-ресурс") ]

        2. Примеры применения: 

                Страница с гиперссылкой требует, чтобы гиперссылка вела на сервлет, и сервлет уведомит браузер о необходимости доступа к другому сервлету посредством «перенаправления запроса». (Здесь сервлет настраивается с использованием аннотаций)

                Код redirection.html выглядит следующим образом: 

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

                Код класса OldServlet выглядит следующим образом: 

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

               Код класса NewServlet выглядит следующим образом: 

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

                Эффект операции: (изображение GIF ниже)

        3. Детали использования: 

        Лучший сценарий применения «302»  миграция сайта . Например, если доменное имя веб-сайта изменено, исходное доменное имя будет www.CyanRA9.com и будет перемещено в новое доменное имя www.CyanRA9.cn, но браузер по-прежнему сканирует исходное доменное имя. , для решения проблемы можно использовать перенаправление запроса.

         При использовании «перенаправления запроса» адресная строка браузера изменится (в конечном итоге оставаясь на URL-адресе нового веб-ресурса), что по сути представляет собой два HTTP-запроса .

        «Перенаправление запроса» не может совместно использовать данные в поле HttpServletRequest , поскольку по сути это два HTTP-запроса, которые генерируют два разных объекта HttpServletRequest.
        нельзя перенаправить на ресурсы в /WEB-INF (защищено)
        Это может быть перенаправлены на ресурсы , отличные от веб-проекта , например, на другие веб-сайты (например, Bing)
        .6° Существует два способа перенаправления запросов:

               (1) соответственно sendRedirect ("/имя веб-проекта/веб-ресурс"); //Рекомендуем первый!

                (2) или УстановитьСтатус (302);

                      соотв. setHeader ("Местоположение", "/Servlet_Demo/new");

        Вы можете использовать метод getServletContext().getContextPath() для получения пути к текущему веб-проекту ( динамическое получение пути к проекту ). После получения пути к проекту передайте его в путь к проекту в виде конкатенации строк. (путь к проекту + конкретные веб-ресурсы).Метод sendRedirect делает настройку URL более гибкой.


5. Краткое описание сервлета (часть 2)

       (1) Освоить общие методы HttpServletRequest (например: разницу между URL и URI; методы получения заголовков запроса; различные способы получения данных отправки формы )

        (2) Освоить основной принцип пересылки запросов (тот же объект домена) и способы реализации пересылки запросов.

       (3) Освойте конкретные шаги HttpServletResponse для вывода данных в браузер и способы решения проблемы искаженных символов.

        (4) Освоить основные принципы перенаправления запросов и конкретную реализацию перенаправления (обратите внимание на разницу в формате перенаправления запросов!)

        System.out.println("КОНЕЦ------------------------------------------ ---------------------------------------"); 

Supongo que te gusta

Origin blog.csdn.net/TYRA9/article/details/131851094
Recomendado
Clasificación