1. Что такое сервлет?
Вернемся на 25 лет назад, когда моя страна была подключена к Интернету менее двух лет назад. Компьютеры тогда выглядели так:
В то время веб-технологии были не очень развиты, и каждый открывал браузер и мог просматривать только некоторые静态
страницы, такие как изображения, текстовая информация и т. д.
С течением времени статические страницы уже не могут удовлетворить потребности большинства пользователей.
Пользователи не могут просто просматривать изображения и текст при открытии браузера, верно? Что, если пользователь все еще хочет отправить форму, нажать кнопку и взаимодействовать с браузером?
Чтобы решить проблему динамического взаимодействия между пользователями и браузерами, в 1997 году компания SUN (придумавшая JDK) запустилаServlet
Технологии.
Сервер - это веб-компонент, разработанный на основе технологии Java, которая работает на стороне сервера иServlet容器
управлять. В основном используется для обработки запросов пользователей и генерировать动态
Информация.
Сервлет на самом деле соответствуетServlet规范
Написан класс Java.
Мы знаем, что у класса должен быть основной метод для независимой работы, но у класса Servlet нет основного метода. Как это работает?
Ответ заключается в том, чтобы запустить его в контейнере сервлетов.
Вы можете думать о сервлете как о приложении, а мобильный телефон эквивалентен контейнеру сервлета. Приложение не может быть запущено само по себе, оно должно быть запущено на телефоне.Сервлет не запускается независимо, потому что нет основного метода, и его нужно запускать в контейнере сервлета.
2. Установка и использование Tomcat
2.1 Введение в Tomcat
Ранее мы упоминали, что сервлет должен быть помещен вservlet容器
беги внутрь, покаTomcat
Это контейнер, который может запускать сервлеты.
Почему Tomcat рекомендуется? Потому что это свободный, открытый источник и простой в использовании.
Tomcat 响应用户请求的过程如下:
-
- Пользователь отправляет HTTP-запрос на Tomcat (веб-сервер) через браузер.
-
- После того, как Tomcat получает запрос, он отправляет информацию о запросе в контейнер сервлета и передает ее контейнеру сервлета.
请求对象
и响应对象
.
- После того, как Tomcat получает запрос, он отправляет информацию о запросе в контейнер сервлета и передает ее контейнеру сервлета.
-
- Контейнер сервлета загружает сервлет, сначала создайте
Servlet实例
. Затем скажите экземпляру сервлета сказать: Эй! Ребят, у меня юзер请求对象
и响应对象
, вы можете справиться с этим.
- Контейнер сервлета загружает сервлет, сначала создайте
-
- Экземпляр сервлета из
请求对象
Получите информацию о запросе клиента, а затем обработайте ее соответствующим образом.
- Экземпляр сервлета из
-
- Экземпляр сервлета передает результаты обработки
响应对象
, отправленный клиенту через объект ответа.
- Экземпляр сервлета передает результаты обработки
Примечание:
- Объект запроса: HttpServletRequest
- Объект ответа: HttpServletResponse
2.2 Установка и настройка Tomcat
Примечание: JDK необходимо установить и настроить перед установкой Tomcat.
- Скачать и разархивировать
链接:https://pan.baidu.com/s/1Ey-gg8tpHT9P-xNOUcrZmg
提取码:1234
- начать кот
Перейдите в каталог bin и дважды щелкните файл startup.sh.Откройте браузер и введите:
http://localhost:8080/
Когда появится следующий экран, это означает, что ваша установка прошла успешно! ! !
3. Спецификация сервлета
-
- Спецификация сервлета определяет этапы разработки файлов динамических ресурсов (фактически сервлетов).
-
- Спецификация сервлета определяет сервер Tomcat
调用
Правила для сервлетов.
- Спецификация сервлета определяет сервер Tomcat
-
- Спецификация сервлета определяет сервер Tomcat
管理
Правила для экземпляров сервлетов.
- Спецификация сервлета определяет сервер Tomcat
Зачем определять эти спецификации?
Потому что нет ни правил, ни квадрата. Поскольку Tomcat также соответствует спецификациям сервлета других людей, в противном случае, когда вы закончите писать программу и передадите ее Tomcat для запуска, Tomcat увидит, что вы не соответствуете спецификациям сервлета, и людям будет лень заботиться о вас.
4. Разработать сервлет
4.1 Создайте новый проект javaweb
Здесь мы используем идею для создания проекта javaweb.
Каталог проекта:
4.2 Конфигурация IDEA Tomcat
1. Выберите «Выполнить» в верхней строке меню и выберите «Редактировать конфигурацию».
2. Щелкните знак «+», выберите Сервер Tomcat и выберите Локальный.
3.Сервер приложений Выберите локальный каталог установки Tomcat. Порт HTTP по умолчанию — 8080.
4. Выберите Развертывание и нажмите справа
+
выберите Артефакт.5. Выберите веб-проект, контекст приложения можно настроить, что эквивалентно пути доступа по умолчанию для нашего проекта.
6. Напишите index.jsp
7. Запустите Томкэт
Ввод URL-адреса браузера:
http://localhost:8080/myProject/
4.3 Разработка сервлета
1. Импортируйте пакет jar
Создайте новый каталог lib в каталоге WEB-INF и поместите каталог bin Tomcat вservlert-api.jar
Поместите его в проект lib.
2. Добавьте пакет jar в качестве библиотеки в проект.
Примечание. Поскольку пакет jar представляет собой скомпилированный код Java, это эквивалентно добавлению в проект кода Java, указанного Tomcat.
Выберите каталог lib, щелкните правой кнопкой мыши и выберите «Добавить как библиотеку».3. Создайте новый класс сервлета
Спецификация сервлета: чтобы Tomcat управлял вновь созданным классом Servlet, он должен наследовать класс HttpServlet в jar-пакете Tomcat.
Создайте класс Java, который наследует родительский класс HTTPServlet, сделайте его классом реализации интерфейса сервлета и переопределить родительский классdoGet
иdoPost
метод.
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 这里用来处理用户的 get 请求
System.out.println("接收到用户的 get 请求");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 这里用来处理用户的 post 请求
System.out.println("接收到用户的 post 请求");
}
}
4. Настройте web.xml
Зачем настраивать web.xml?
Вы создали класс сервлета в соответствии со спецификацией сервлета, но старший брат Томкэт этого не знает! Так что тебе нужно сказать старшему брату.
web.xml эквивалентен привратнику Tomcat. Вам необходимо зарегистрироваться на привратнике и внедрить информацию о классе для интерфейса сервлета.注册
на сервер Томкэт.
Вам необходимо зарегистрировать имя класса сервлета, путь к проекту, в котором находится класс, и путь запроса.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--将 Servlet接口实现类交给Tomcat管理-->
<servlet>
<servlet-name>userServlet</servlet-name> <!--Servlet接口实现类名称-->
<servlet-class>com.xxl.controller.UserServlet</servlet-class><!--声明servlet接口实现类类路径-->
</servlet>
<servlet-mapping>
<servlet-name>userServlet</servlet-name>
<url-pattern>/user</url-pattern> <!--设置Servlet类的请求路径,必须以 / 开头-->
</servlet-mapping>
</web-app>
- servlet-name: Имя класса сервлета.
- класс сервлета: путь к проекту, в котором находится класс сервлета.
- url-pattern: путь, по которому пользователь запросил сервлет.
5. Тест
Запустите проект и введите в браузере:
http://localhost:8080/myProject/user
Проверьте консольную печать:
注:
Браузер напрямую вводит URL, а нажатие клавиши Enter — это GET-запрос, который аналогичен гиперссылке в html, например:
<a href="/myProject/user">点击访问 UserServlet</a>
6. Аннотированная разработка
Время шло под звук клавиатуры, набирающей код, казалось, все было мирно, но однажды что-то случилось.
это黑云压城城欲摧
Днем швейцар Томкэтаweb.xml
Читая газету и покусывая семена дыни в комнате охраны, за дверью внезапно раздался топот копыт.
Таким образом, этот день вдруг наступил десять тысяч сервлетов Web.xml, найдут регистрацию.
web.xml взгляните на ситуацию蚌埠住了!
, и быстро сообщите об этом официальным лицам Tomcat.
Томкэт задумался: "Эти 10 000 сервлетов должны быть зарегистрированы в год Обезьяны и Месяц Лошади? Забудьте, пусть не регистрируются, пусть приносят свои标记
Ну, я могу узнать этот знак. "
так вservlet3.0
После версии нам не нужно настраивать каждый сервлет в web.xml, достаточно добавить аннотацию. Формат аннотации:
@WebServlet(name = "servlet的名字",value = "访问路径")
或者:
@WebServlet("/访问路径") //默认以类名作为名字
Например:
@WebServlet(name = "userServlet",value = "/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 这里用来处理用户的 get 请求
System.out.println("哈哈哈哈哈哈我头上有注解");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 这里用来处理用户的 post 请求
System.out.println("接收到用户的 post 请求");
}
}
или:
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 这里用来处理用户的 get 请求
System.out.println("哈哈哈哈哈哈我头上有注解");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 这里用来处理用户的 post 请求
System.out.println("接收到用户的 post 请求");
}
}
На данный момент web.xml пуст:Даже в web.xml ничего не настроено, потому что мы добавили
注解
, чтобы Tomcat также мог его распознать, давайте снова запросим сервлет и обнаружим, что запрос также может быть успешным.
Запустите проект и введите в браузере:
http://localhost:8080/myProject/user
注
: имя и путь запроса должны быть уникальными, иначе Tomcat не будет знать, какой сервлет передать после получения запроса пользователя.
5. HTTP-протокол
5.1 Введение
Зачем изучать протокол HTTP?
Потому что только зная Http-протокол, можно разобраться в процессе передачи информации по сети, и можно узнать, что делает сервлет.
Протокол Http в основном используется в архитектуре клиент-сервер. Как Http-клиент, браузер отправляет запрос на веб-сервер через URL-адрес.Обычно используемые Http-запросы в основном включают запросы GET и POST-запросы. После того, как веб-сервер обработает запрос пользователя, он отправляет ответную информацию клиенту.
информация в Интернете есть二进制
Передаваемая информация инкапсулируется в пакеты протокола Http один за другим. Пакеты протокола HTTP включают в себя пакеты запросов и пакеты ответов.
5.2 HTTP-запрос
Формат сообщения HTTP-запроса в основном включает в себя: строку запроса, заголовок запроса, запросить пустую строку и запросить данные.
Например, тело сообщения запроса GET:
GET /login.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
请求行
В основном он включает в себя: метод запроса, запрошенный URL-адрес и запрошенный протокол версии Http, например:
GET /login.html HTTP/1.1
Формат заголовка запроса: Имя заголовка запроса: Значение заголовка запроса, например:
Host: localhost
Вот полный заголовок запроса:
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Пустая строка запроса — это пустая строка, которая означает, что серверу не будет заголовков запросов, начинающихся со следующей строки.
Запрос GET не имеет тела запроса, только запрос POST имеет тело запроса, и тело запроса передается в виде пар ключ-значение, а тело запроса POST представляет собой пару ключ-значение.
5.3 HTTP-ответ
Формат сообщения HTTP-ответа в основном включает в себя: строку состояния, заголовок ответа, пустую строку и соответствующие данные. Например, ниже приведено полное тело ответа:
HTTP/1.1 200 OK
Date: Wed, 22 Dec 2021 09:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
<head></head>
<body>
一颗雷布斯
</body>
</html>
Строка состояния: номер версии протокола HTTP, код состояния, сообщение о состоянии.
Первая строка — это строка состояния (HTTP/1.1), указывающая, что версия HTTP — 1.1, код состояния — 200, а сообщение о состоянии — ok.
Вторая и третья строки — это заголовки ответа, описывающие некоторую дополнительную информацию, которую должен использовать клиент.
Четвертая строка — пустая.
Окончательный html-код — это тело ответа.
5.4 Разница между GET и POST
- GET включает параметры запроса в URL-адрес, а POST передает параметры через тело запроса.
- GET небезопасен, поскольку параметры отображаются непосредственно в URL-адресе, поэтому его нельзя использовать для передачи конфиденциальной информации.
- Параметры, передаваемые в URL-адресе для запросов GET, ограничены по длине, а POST — нет.
6. Приветственная страница
Обычно мы посещаем веб-сайт, вводя простой URL-адрес, например:
https://www.baidu.com
вместо:
https://image.baidu.com/search/index?tn=baiduimage&ct=201326592
Из-за этого длинного пути мы просто не можем вспомнить. Поэтому, когда пользователь посещает веб-сайт, мы обычно устанавливаем страницу по умолчанию, например домашнюю страницу Baidu по умолчанию:Итак, как установить страницу приветствия по умолчанию в нашем проекте?
Также настроен в web.xml. Настройте правила:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Тогда нам нужноweb
илиwebapp
Создайте страницу приветствия в каталоге.
Порядок отображения страницы приветствия по умолчанию — сверху вниз, если он не настроен, он будет найден из этих файлов.
Например, мы не настроили страницу приветствия при первом создании этого проекта, но содержимое index.jsp отображается по умолчанию после запуска программы.
Конечно, мы также можем установить пользовательскую страницу приветствия, например:
login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login.html</title>
</head>
<body>
<h1>家人们!家人们!欢迎来到登录页面!</h1>
</body>
</html>
Запустите программу:
7. HttpServletRequest
7.1 Что такое HttpServletRequest?
Отправляем Http сервер через браузер Http请求协议包
, сервер HTTP будет автоматически обслуживать этоHttp请求协议包
генерировать请求对象
и响应对象
.
А HttpServletRequest представляет запрос клиента. Вся информация в HTTP-запросе инкапсулирована в этот объект. Мы можем использовать этот объект, чтобы делать следующие вещи:
- Прочитайте информацию о запросе в пакете протокола запроса Http.
- Запросить файл ресурсов с Http-сервера
7.2 Получить информацию о строке запроса
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取请求行中【url】信息
String url = request.getRequestURL().toString();
// 2. 获取请求行中【method】信息
String method = request.getMethod();
// 3. 获取请求行中【URI】信息,URI: "/网站名/资源文件名"
String uri = request.getRequestURI();
System.out.println("请求 URL: " + url);
System.out.println("请求 method: " + method);
System.out.println("请求 URI: " + uri);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 这里用来处理用户的 post 请求
System.out.println("接收到用户的 post 请求");
}
}
Запустите проект и введите в браузере:
http://localhost:8080/myProject/user
Консоль выводит результат:
7.3 Получить информацию о параметрах заголовка запроса
Мы используем следующие методы для получения информации о параметрах заголовка запроса:
String parameter = request.getParameter("参数名");
7.3.1 Получение информации о параметрах заголовка запроса GET
Во-первых, мы добавляем параметры запроса к пути запроса браузера.&
разделены, например:
http://localhost:8080/myProject/user?name=一颗雷布斯&age=23
Измените код:
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求头的 name 参数
String name = request.getParameter("name");
// 获取请求头的 age 参数
String age = request.getParameter("age");
System.out.println("name: "+name);
System.out.println("age: "+age);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 这里用来处理用户的 post 请求
System.out.println("接收到用户的 post 请求");
}
}
Запустите программу и просмотрите информацию о печати консоли:
7.3.2 Получение информации о параметрах заголовка POST-запроса
Давайте сначала изменим код страницы приветствия по умолчанию login.html и добавим информацию о форме формы:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login.html</title>
<style>
div {
width: 300px;
height: 300px;
margin: 0 auto;
}
</style>
</head>
<body>
<div>
<form action="/myProject/user" method="post">
<lable>姓名:</lable>
<input type="text" name="name"></br>
<lable>密码:</lable>
<input type="password" name="password"></br>
<input type="submit" value="登录">
</form>
</div>
</body>
</html>
Измените код сервлета:
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 这里用来处理用户的 get 请求
System.out.println("接收到用户的 get 请求");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取 post 请求的 name 参数
String name = request.getParameter("name");
// 获取 post 请求的 password 参数
String password = request.getParameter("password");
System.out.println("name: "+name);
System.out.println("password: "+password);
}
}
Введите данные на странице браузера, пароль 123456, и нажмите кнопку входа:Просмотр информации о печати консоли:
7.3.3 POST-запрос для решения проблемы с получением параметров мусора
В приведенном выше примере мы обнаружили, что английский и цифры могут быть выведены нормально, но китайские иероги искажены. Почему?
Когда браузер отправляет запрос GET, параметры запроса сохраняются в请求头
, HTTP-сервер декодирует пакет протокола запроса после его получения.
Tomcat отвечает за его декодирование. Поскольку Tomcat используетutf-8
Набор символов, этот набор символов может объяснить текст для всех стран, так что даже китайский язык не будет искажен.
Когда браузер отправляет запрос POST, параметры запроса сохраняются в请求体
, HTTP-сервер декодирует пакет протокола запроса после его получения.
Запрос объекта запроса отвечает за декодирование содержимого тела запроса. Поскольку запрос использует значение по умолчаниюISO-8859-1
набор символов, этот набор символов东欧语
Набор символов, поэтому он будет искажен при встрече с китайским языком.
так вPost
Чтобы решить проблему искаженных символов в режиме запроса, объект запроса должен сначала повторно декодировать содержимое тела запроса, используя набор символов utf-8.
request.setCharacterEncoding("utf-8");
Давайте повторно изменим код сервлета:
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 这里用来处理用户的 get 请求
System.out.println("接收到用户的 get 请求");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Tomcat 通知请求对象,使用 utf-8 字符集对请求体内容重写解码
request.setCharacterEncoding("utf-8");
// 获取 post 请求的 name 参数
String name = request.getParameter("name");
// 获取 post 请求的 password 参数
String password = request.getParameter("password");
System.out.println("name: "+name);
System.out.println("password: "+password);
}
}
Введите информацию на странице браузера и нажмите кнопку входа, чтобы просмотреть информацию о печати консоли:
8. HttpServletResponse
8.1 Что такое HttpServletRequest?
После того, как мы обработаем запрос пользователя, мы должны ответить пользователю, а HttpServletResponse — это объект ответа, который может делать следующие вещи:
- Запишите результат в двоичной форме в
响应体
- установить заголовок ответа
content-type
значение атрибута - установить заголовок ответа
location
атрибут, чтобы позволить браузеру отправить запрос на указанный Http-сервер.
8.2 Ответ отправляет результат в браузер
Мы положили результат реагирования вHttp响应包
Затем в теле ответа браузер компилирует и анализирует двоичное содержимое тела ответа, чтобы отобразить его содержимое.
Формат синтаксиса:
PrintWriter writer = response.getWriter();
writer.println(响应结果内容);
Давайте изменим код сервлета:
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result1 = "<h1>2022: Where there is a well,there is a way<h2>";
String result2 = "海鸟跟鱼相爱,只是一场意外";
PrintWriter writer = response.getWriter();
writer.println(result1);
writer.println(result2);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 这里用来处理用户的 post 请求
System.out.println("接收到用户的 post 请求");
}
}
Запустите проект и введите в браузере:
http://localhost:8080/myProject/user
Просмотрите результат ответа браузера:
8.3 Установка типа содержимого заголовка ответа
Из приведенного выше примера мы видим, что английский язык и цифры могут выводиться нормально, но китайский язык искажается Мы можем установить формат типа содержимого заголовка ответа, чтобы браузер мог выводить китайский язык.
Установите формат синтаксиса типа контента:
response.setContentType("content-type 的格式");
Давайте изменим код сервлета:
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result1 = "<h1>2022: Where there is a well ,there is a way<h2>";
String result2 = "海鸟跟鱼相爱,只是一场意外";
// 设置响应头 content-type 的格式
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println(result1);
writer.println(result2);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 这里用来处理用户的 post 请求
System.out.println("接收到用户的 post 请求");
}
}
Запустите проект и введите в браузере:
http://localhost:8080/myProject/user
Просмотрите результат ответа браузера:
8.4 Отправить запрос на указанный Http-сервер
Мы можем установить атрибут местоположения в заголовке ответа, чтобы позволить браузеру перейти к указанному URL-адресу. Формат синтаксиса:
response.sendRedirect("网址");
Давайте изменим код сервлета:
@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 浏览器接收到 http 响应包之后,如果发现响应头中存在 location 属性
// 2. 则自动通过地址栏向 location 指定网站发送请求
// 3. sendRedirect 方法控制浏览器的请求行为
response.sendRedirect("http://www.baidu.com");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 这里用来处理用户的 post 请求
System.out.println("接收到用户的 post 请求");
}
}
Запустите проект и введите в браузере:
http://localhost:8080/myProject/user
Просмотрите результат ответа браузера:
9. Перенаправление и переадресация запросов
9.1 Взаимный доступ между сервлетами
Если однажды вы скажете Http-серверу: я хочу съесть желтую тушеную курицу. В результате ваш сценарий доступа выглядит так:
Позже вы полностью破防
A: "? Я хочу съесть желтое куриное рагу, нужен доступ к сайту столько раз, что сломал ах, больше нет!"
Поэтому, чтобы улучшить взаимодействие с пользователем, спецификация сервлета определяет правила для вызова друг друга между несколькими сервлетами.
Независимо от того, сколько сервлетов задействовано в запросе, пользователю нужно только инициировать запрос к браузеру.一次
Запросы, сервлеты взаимодействуют друг с другом, и пользователь получает результат ответа.
Существует два правила вызова друг друга между несколькими сервлетами:
-
- перенаправить решение
-
- Решение для переадресации запросов
9.2 Перенаправление
- принцип:
Сначала пользователь обращается к oneServlet через браузер, но oneServlet не может решить проблему пользователя. Итак, oneServlet будет TwoServlet访问地址
написать в заголовок ответа
изlocation
в свойствах.
После того, как браузер получит пакет ответа Http, он снова отправит запрос к twoServlet на сервере Http в соответствии со значением местоположения в заголовке ответа. twoServlet для обработки запроса пользователя.
фактическиперенаправитьЭто равносильно тому, что вы пойдете к Лю Бэю, чтобы занять денег. Лю Бэй сказал, что у меня нет денег, поэтому идите к Цао Цао. Затем вы пошли к Цао Цао, чтобы занять денег, и, наконец, получили деньги.
- особенность:
- Браузер отправляет как минимум два запроса, только первый раз отправляет сам пользователь через браузер, а вторые отправляются браузером автоматически.
- Метод запроса перенаправления — это метод GET.
- Поскольку адрес запроса меняется, меняется и адресная строка браузера.
- Помимо доступа к ресурсам внутри http-сервера, вы также можете получить доступ к внешним ресурсам веб-сайта. Например, Baidu и т. д.
- Браузер доступ к серверу несколько раз, увеличивая время ожидания пользователя.
- Метод реализации
response.sendRedirect("网址");
- кейс
Новый OneServlet
@WebServlet("/one")
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendRedirect("/myProject/two");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Новый TwoServlet
@WebServlet("/two")
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("我是 twoServlet,我帮你解决问题!");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Запустите проект и используйте браузер для доступа к OneServlet:
http://localhost:8080/myProject/one
Просмотрите результат ответа браузера:
9.3 Переадресация запроса
1. Принцип
Сначала пользователь обращается к oneServlet через браузер, но oneServlet не может решить проблему пользователя. Итак, oneServlet передает объект запроса и объект ответа в TwoServlet, а затем twoServlet обрабатывает запрос пользователя.
фактическизапрос на переадресациюЭто равносильно тому, что вы идете к Лю Бэю, чтобы занять денег.У Лю Бэя нет денег, когда он касается своего кармана, но Лю Бэй - праведник, поэтому он отведет вас, чтобы найти Цао Цао, чтобы занять деньги, и, наконец, вы одолжите деньги. от Цао Цао.
2. Особенности
- В процессе переадресации запроса браузер отправляет запрос только один раз.
- Для переадресации запросов внутри HTTP-сервера могут запрашиваться только внутренние ресурсы сервера.
- В процессе пересылки запроса браузер отправляет только один пакет протокола запроса Http. Таким образом, все сервлеты, участвующие в этом запросе, используют один и тот же пакет протокола запроса.
- Поскольку запрос перенаправляется внутри Http-сервера, адресная строка браузера остается неизменной.
3. Реализация
RequestDispatcher requestDispatcher = request.getRequestDispatcher("下一个servlet请求路径");
// 将本次 Http 请求协议包的【请求对象】和【响应对象】交给下一个 servlet
requestDispatcher.forward(request,response);
4. Кейс
Изменять только OneServlet
@WebServlet("/one")
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 因为是http 服务器内部做请求转发,相当于调用同一个项目的资源,所以直接写 servlet的访问路径就行
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/two");
// 将本次 Http 请求协议包的【请求对象】和【响应对象】交给下一个 servlet
requestDispatcher.forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Запустите проект и используйте браузер для доступа к OneServlet:
http://localhost:8080/myProject/one
Просмотрите результат ответа браузера:Резюме: перенаправлено
重
Это означает снова и снова, то есть браузер отправляет более двух запросов на сервер. Хотя переадресация запросов происходит внутри сервера, браузер запрашивает ее только один раз.
10. Обмен данными между сервлетами
数据共享
: после обработки запроса первым сервлетом данные передаются второму сервлету для использования.
Спецификация сервлета предоставляет четыре способа решения проблемы обмена данными.
10.1. ServletContext
1. Глобальный охват
Объект ServletContext является объектом с глобальной областью действия.
Объект глобальной области действия эквивалентен объекту в классе.公用的区域
, учитель поместил сюда некоторые общедоступные элементы, которые могут использовать все ученики (Servlet).
2. Как использовать
Добавить общие данные в объект глобальной области
// 1. 获取全局作用域对象
ServletContext servletContext = request.getServletContext();
// 2. 将共享数据添加到全局作用域对象
servletContext.setAttribute("key",value);
Получить общие данные из объекта глобальной области
// 1. 获取全局作用域对象
ServletContext servletContext = request.getServletContext();
// 2. 从全局作用域对象获取共享数据
Object value = servletContext.getAttribute("key");
3. Кейс Изменить OneServlet
@WebServlet("/one")
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取全局作用域对象
ServletContext servletContext = request.getServletContext();
// 2. 将共享数据添加到全局作用域对象
servletContext.setAttribute("info","祝今年期末考试的你科科必过!祝今年考研、考公的你一定上岸!");
// 3. 重定向
response.sendRedirect("/myProject/two");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Изменить два сервлета
@WebServlet("/two")
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取全局作用域对象
ServletContext servletContext = request.getServletContext();
// 2. 从全局作用域对象获取共享数据
String info = (String)servletContext.getAttribute("info");
response.setContentType("text/html;charset=utf-8");
// 3. 将共享数据发送到浏览器
response.getWriter().println(info);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Запустите проект и используйте браузер для доступа к OneServlet:
http://localhost:8080/myProject/one
Просмотрите результат ответа браузера:
10.2. Cookie
1. Введение
Файл cookie — это объект в спецификации сервлета. Если два сервлета принадлежат одному и тому же веб-сайту, объект Cookie можно использовать для обмена данными.
2. Принцип
Пользователь запрашивает OneServlet, OneServlet создает файл cookie для хранения данных, связанных с текущим пользователем. После выполнения OneServlet записывает Cookie в заголовок ответа и возвращает его текущему браузеру.
После того, как браузер получает пакет ответа HTTP, он сохраняет информацию о файле cookie в浏览器的缓存
середина.
Через некоторое время пользователь получает доступ к TwoServlet через тот же браузер. Браузер записывает информацию о файлах cookie из кеша в заголовок запроса пакета HTTP-запроса.
На этом этапе TwoServlet может получить общие данные, предоставленные OneServlet, путем чтения информации о файлах cookie в заголовке запроса.
По сути, принцип использования файлов cookie аналогичен тому, когда вы (браузер) впервые идете в спортзал (HTTP-сервер), и персонал тренажерного зала выдает вам членскую карту (Cookie). В следующий раз, когда вы пойдете в этот тренажерный зал, персонал внутри узнает, кто вы, после получения членской карты.
3. Как использовать
Создавайте файлы cookie, сохраняйте общие данные
// 1.创建一个 cookie 对象,保存共享数据
Cookie cookie = new Cookie("key","value");
// 2. 将 cookie 信息写入到响应头,交给浏览器
response.addCookie(cookie);
Получить общие данные
// 1. 调用请求对象从请求头得到浏览器返回的 Cookie 信息
Cookie cookies[] = request.getCookies();
// 2. 遍历数据获取 cookie 的 key 与 value
for(Cookie cookie:cookies) {
// 3. 获取 key 的值
String key = cookie.getName();
// 4. 获取 value 的值
String value = cookie.getValue();
}
4. Кейс Изменить OneServlet
@WebServlet("/one")
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.创建一个 cookie 对象,保存共享数据
Cookie cookie = new Cookie("name","jay");
// 2. 将 cookie 信息写入到响应头,交给浏览器
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Изменить два сервлета
@WebServlet("/two")
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 调用请求对象从请求头得到浏览器返回的 Cookie 信息
Cookie cookies[] = request.getCookies();
// 2. 遍历数据获取 cookie 的 key 与 value
for(Cookie cookie:cookies) {
// 3. 获取 key 的值
String key = cookie.getName();
// 4. 获取 value 的值
String value = cookie.getValue();
System.out.println("key: "+key+" value: "+value);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Запустите проект и сначала получите доступ к OneServlet:
http://localhost:8080/myProject/one
Затем посетите TwoServlet:
http://localhost:8080/myProject/two
Просмотрите распечатку консоли:
Уведомление:
- Файл cookie эквивалентен карте.
- В файле cookie может храниться только одна пара ключ-значение.
- Ключ и значение пары ключ-значение могут иметь только тип String.
- Ключ в паре ключ-значение не может быть китайским.
5. Сроки уничтожения файлов cookie
По умолчанию объекты cookie сохраняются в кеше браузера. Поэтому, как только вы закроете браузер, объект Cookie будет уничтожен.
Чтобы продлить срок действия файлов cookie, мы можем хранить информацию о файлах cookie на жестком диске локального компьютера и устанавливать время жизни файлов cookie.
В пределах диапазона времени выживания закрытие браузера или сервера не приведет к уничтожению файла cookie. Когда время жизни истекло, файл cookie автоматически удаляется.
Установить время жизни куки на жестком диске:
Cookie cookie = new Cookie("name","jay");
//cookie 在硬盘上存活 2 分钟
cookie.setMaxAge(120);
10.3. Session
1. Введение
Session
является объектом в спецификации сервлета. Если два сервлета находятся на одном веб-сайте, объект Session можно использовать для обмена данными. Мы привыкли называть Session объектом сеанса.
2. Принцип
Пользователь запрашивает OneServlet, OneServlet создает объект Session для хранения данных, связанных с текущим пользователем. После выполнения OneServlet сохраните сеанс в памяти Http-сервера.
Затем пользователь получает доступ к двум сервлетам через тот же браузер. Два сервлета могут получать общие данные, предоставляемые OneServlet, через сеанс в памяти HTTP-сервера.
По сути, Session можно рассматривать как серверный сейф.
3. Как использовать
Создать сеанс для сохранения общих данных
// 1. 创建 session 对象
HttpSession session = request.getSession();
// 2. 将数据保存到服务器内存中(保险柜)
session.setAttribute("key",共享数据);
Получить общие данные
// 1. 获取 session
HttpSession session = request.getSession();
// 2. 从 session 中获取共享数据
Object 共享数据 = session.getAttribute("key");
4. Кейс
Изменить OneServlet
@WebServlet("/one")
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 创建 session 对象
HttpSession session = request.getSession();
// 2. 将数据保存到服务器内存中(保险柜)
session.setAttribute("key",123);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Изменить два сервлета
@WebServlet("/two")
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取 session
HttpSession session = request.getSession();
// 2. 从 session 中获取共享数据
Object info = session.getAttribute("key");
System.out.println("从session中获取信息:"+info);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Запустите проект и сначала получите доступ к OneServlet:
http://localhost:8080/myProject/one
Затем посетите TwoServlet:
http://localhost:8080/myProject/two
Просмотрите распечатку консоли:Уведомление:
- Объекты HttpSession могут хранить любые типы общих данных.
- HttpSession эквивалентен коллекции карт, поэтому можно хранить любое количество общих данных.
10.4. HttpServletRequest
1. Введение
На том же веб-сайте между двумя сервлетами через请求转发
способ позвонить,
Поскольку они используют один и тот же пакет протокола запроса, сервлеты используют один и тот же объект запроса. Следовательно, этот объект запроса можно использовать для обеспечения совместного использования данных между двумя сервлетами.
Этот объект запроса называется请求作用域对象
.
2. Как использовать
Используйте объект запроса для сохранения общих данных
// 数据类型可以是任意类型
req.setAttribute("key",数据);
Используйте объект запроса для получения общих данных
// 从请求对象获取共享数据
Object 数据 = req.getAttribute("key");
3. Кейс
Изменить OneServlet
@WebServlet("/one")
public class OneServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用请求对象保存共享数据
request.setAttribute("info","我一路向北,离开有你的季节。");
// 请求转发
request.getRequestDispatcher("/two").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Изменить два сервлета
@WebServlet("/two")
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 从请求对象中获取共享数据
Object info = request.getAttribute("info");
response.setContentType("text/html;charset=utf-8");
response.getWriter().println(info);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Запустите проект и используйте браузер для доступа к OneServlet:
http://localhost:8080/myProject/one
Просмотрите результат ответа браузера:
11. Фильтр-фильтр
1. Введение
Фильтр — это интерфейс в спецификации сервлета, который в основном используется, чтобы указать Tomcat выполнить запрос пользователя перед вызовом определенного файла ресурсов.拦截
.
Например, если пользователь хочет просмотреть информацию о своей корзине перед входом на веб-сайт, запрос пользователя должен быть перехвачен в это время.
2. Как использовать
- Создайте новый класс фильтра и реализуйте метод doFilter в интерфейсе фильтра.
- Настройте класс фильтра в web.xml
<!--配置过滤器-->
<filter>
<filter-name>userFilter</filter-name>
<filter-class>com.xxl.filter.UserFilter</filter-class>
</filter>
<!-- 告诉 Tomcat 在用户调用何种资源文件时需要被当前过滤器拦截-->
<filter-mapping>
<filter-name>userFilter</filter-name>
<url-pattern>拦截路径</url-pattern>
</filter-mapping>
3. Кейс
Новый пользовательский фильтр
public class UserFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
}
Поместите фото красоты в проект:Настройте UserFilter в web.xml, чтобы заблокировать фотографию.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置过滤器-->
<filter>
<filter-name>userFilter</filter-name>
<filter-class>com.xxl.filter.UserFilter</filter-class>
</filter>
<!-- 告诉 Tomcat 在用户调用何种资源文件时需要被当前过滤器拦截-->
<filter-mapping>
<filter-name>userFilter</filter-name>
<url-pattern>/girl.jpg</url-pattern>
</filter-mapping>
</web-app>
Улучшите код UserFilter, чтобы определить, превышает ли возраст параметр 18 лет.
public class UserFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 1. 通过【拦截请求对象】获取请求参数信息
String age = servletRequest.getParameter("age");
// 2. 如果年龄合法
if (Integer.parseInt(age) > 18) {
// 3. 将拦截请求对象和响应对象交还给 Tomcat,由 Tomcat 继续调用资源文件,放行
filterChain.doFilter(servletRequest,servletResponse);
}else{
servletResponse.setContentType("text/html;charset=utf-8");
servletResponse.getWriter().println("看啥美女!写你的作业去!");
}
}
}
результат операции:
4. Аннотированная разработка
Нет необходимости настраивать в web.xml, просто аннотируйте класс фильтра напрямую:
@WebFilter(filterName = "filter名字",urlPatterns = "拦截路径")
Измените код UserFilter:
@WebFilter(filterName = "userFilter",urlPatterns = "/girl.jpg")
public class UserFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 1. 通过【拦截请求对象】获取请求参数信息
String age = servletRequest.getParameter("age");
// 2. 如果年龄合法
if (Integer.parseInt(age) > 18) {
// 3. 将拦截请求对象和响应对象交还给 Tomcat,由 Tomcat 继续调用资源文件,放行
filterChain.doFilter(servletRequest,servletResponse);
}else{
servletResponse.setContentType("text/html;charset=utf-8");
servletResponse.getWriter().println("看啥美女!写你的作业去!");
}
}
}
Работает так же.