Оглавление
4 ° getHeader (заголовок строки):
8° setAttribute(ключ, значение):
3. Демонстрация получения данных формы:
3. Запросите детали пересылки:
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. Детали использования:
1° Чтобы предотвратить проблему «искаженных данных при отправке формы» , вы можете вызвать метод req.setCharacterEncoding("utf-8") перед использованием метода req.getParameter(string).
2° Чтобы предотвратить проблему «искаженных данных, возвращаемых сервером браузеру» , вы можете вызвать метод 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. Запросите детали пересылки:
- URL-адрес в адресной строке браузера не изменится (адрес останется URL-адресом первого сервлета) . Потому что весь процесс «переадресации запроса» выполняется на стороне сервера и не имеет никакого отношения к браузеру , в итоге Tomcat всё равно отвечает браузеру в виде HTTP-ответа.
- Несколько пересылок могут быть выполнены в одном и том же HTTP-запросе; несколько пересылок могут быть выполнены в одном и том же HTTP-запросе, и несколько сервлетов могут совместно использовать данные поля/объекта запроса (поскольку это всегда один и тот же объект запроса).
- «Пересылку запроса» также можно перенаправить в каталог WEB-INF (для использования в проекте).
- «Пересылка запроса» не может получить доступ к ресурсам за пределами текущего WEB-проекта . (404)
- Поскольку адресная строка браузера остановится на первом сервлете, при обновлении страницы запрос будет выдан снова (и данные будут перенесены), поэтому не используйте пересылку запросов в таких ситуациях, как страницы оплаты , в противном случае это приведет к повторные платежи.
Например, 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. Детали использования:
1° Лучший сценарий применения «302» — миграция сайта . Например, если доменное имя веб-сайта изменено, исходное доменное имя будет www.CyanRA9.com и будет перемещено в новое доменное имя www.CyanRA9.cn, но браузер по-прежнему сканирует исходное доменное имя. , для решения проблемы можно использовать перенаправление запроса.
2° При использовании «перенаправления запроса» адресная строка браузера изменится (в конечном итоге оставаясь на URL-адресе нового веб-ресурса), что по сути представляет собой два HTTP-запроса .
3° «Перенаправление запроса» не может совместно использовать данные в поле HttpServletRequest , поскольку по сути это два HTTP-запроса, которые генерируют два разных объекта HttpServletRequest.
4° нельзя перенаправить на ресурсы в /WEB-INF (защищено)
5° Это может быть перенаправлены на ресурсы , отличные от веб-проекта , например, на другие веб-сайты (например, Bing)
.6° Существует два способа перенаправления запросов:(1) соответственно sendRedirect ("/имя веб-проекта/веб-ресурс"); //Рекомендуем первый!
(2) или УстановитьСтатус (302);
соотв. setHeader ("Местоположение", "/Servlet_Demo/new");
7° Вы можете использовать метод getServletContext().getContextPath() для получения пути к текущему веб-проекту ( динамическое получение пути к проекту ). После получения пути к проекту передайте его в путь к проекту в виде конкатенации строк. (путь к проекту + конкретные веб-ресурсы).Метод sendRedirect делает настройку URL более гибкой.
5. Краткое описание сервлета (часть 2)
(1) Освоить общие методы HttpServletRequest (например: разницу между URL и URI; методы получения заголовков запроса; различные способы получения данных отправки формы )
(2) Освоить основной принцип пересылки запросов (тот же объект домена) и способы реализации пересылки запросов.
(3) Освойте конкретные шаги HttpServletResponse для вывода данных в браузер и способы решения проблемы искаженных символов.
(4) Освоить основные принципы перенаправления запросов и конкретную реализацию перенаправления (обратите внимание на разницу в формате перенаправления запросов!)
System.out.println("КОНЕЦ------------------------------------------ ---------------------------------------");