Технология сеанса — подробное объяснение файлов cookie и сеанса

Java EE

Разговорная технология

(1) Обзор, использование и классификация

(1) Основной обзор

Обзор: сеансы — это несколько запросов и ответов между браузером и сервером.

То есть из браузеразапуск сервера доступа,прибытьКонец доступа к серверу,пока не закроешь браузерконтент, созданный за это времяНесколько запросов и ответов, в совокупности называемые сеансом между браузером и сервером

(2) Зачем использовать разговорные технологии?

По сути, сессионная проблема решает проблему коммуникации между клиентом и сервером.Через некоторые сессионные технологии данные каждого пользователя могут храниться в виде куки/сессии, что удобно пользователям для доступа к веб-ресурсам в будущем .

Гипотетический сценарий: после того, как A и B зайдут в интернет-магазин, A купит клавиатуру HHKB, а B купит акустическую гитару, и все они будут сохранены.

Цель: сохранить информацию об учетной записи, спросить, следует ли автоматически входить в систему в будущем при входе в систему, или проанализировать, какой тип продуктов нравится пользователю на основе ранее просмотренных и приобретенных продуктов, и сделать точные толчки.

Итак, можем ли мы использовать объект HttpServletRequest и объект ServletContext, которые мы изучили ранее, для сохранения этих данных? ответ отрицательный

Причины, по которым нельзя использовать HttpServletRequest: В одном из наших сеансов есть несколько запросов и ответов, и каждый запрос от клиента браузера будет генерировать объект HttpServletRequest, который будет сохранять только информацию этого запроса, например, добавление в корзину и оплата покупки — это разные запросы. , видно, что данные плохо сохраняются и обрабатываются

Причины, по которым ServletContext нельзя использовать: Объект ServletContext является общим для всего веб-приложения.Если данные хранятся здесь, несомненно, будет невозможно различить атрибуцию конкретной информации.

(3) Классификация

Технология клиентских сессий — файлы cookie

Технология сеанса сервера - Session

Технология cookie

(1) Базовые знания

(1 Обзор

Файлы cookie можно просто понимать как некоторые информационные файлы, временно хранящиеся в вашем браузере сервером.Они записывают некоторый контент, который вы вводите на веб-сайте, или некоторые параметры.При следующем посещении того же веб-сайта сервер будет активно запрашивать этот файл cookie. информации, если она существует, она будет предоставлять некоторые специальные функции в зависимости от содержания, такие как запоминание пароля учетной записи и т. д.

Подвести итог:

  • Взаимодействие между веб-страницами передает данные через протокол HTTP, который является протоколом без сохранения состояния (после отправки данных связь между браузером и сервером будет закрыта, и во время этого взаимодействия необходимо повторно установить новое соединение).
  • Сервер не может подтвердить информацию о пользователе, поэтому он отправляет пропуск каждому пользователю и подтверждает информацию о пользователе через этот

(2) Конкретный процесс

Браузер обращается к серверу, и если серверу необходимо записать статус пользователя, он отправляет cookie-файл в браузер с ответом, и браузер сохраняет cookie-файл. Когда браузер снова обращается к серверу, браузер отправляет запрошенный URL-адрес и файл cookie на сервер.

(3) Спецификация

  • Максимальный размер файла cookie — 4 КБ;

  • Сервер может хранить до 20 файлов cookie в клиентском браузере;

  • Браузер может хранить до 300 файлов cookie.

    Приведенные выше данные являются спецификацией HTTP для файлов cookie, но некоторые браузеры могут вносить некоторые расширения в спецификацию файлов cookie, например, размер каждого файла cookie составляет 8 КБ, и он может сохранять до 500 файлов cookie и т. д.

Файлы cookie не передаются между разными браузерами

(2) Общие API

//用于在其响应头中增加一个相应的Set-Cookie头字段
addCookie

//用于获取客户端提交的Cookie
GetCookie
public Cookie(String name,String value)
   
//该方法设置与 cookie 关联的值。
setValue

//该方法获取与 cookie 关联的值。
getValue

//该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie只会在当前 session 会话中持续有效。
setMaxAge

//该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭
getMaxAge

//该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。
setPath

//该方法获取 cookie 适用的路径。
getPath

//该方法设置 cookie 适用的域
setDomain

//该方法获取 cookie 适用的域
getDomain

(1) Примечание:

  • Файлы cookie не являются междоменными
  • Cookie сохраняет искаженные китайские символы: китайский относится к символам Unicode, английские символы данных Ascii, учетная запись китайского языка для 4 или 3 символов, английские учетные записи для 2 символов, символы Unicode необходимо кодировать, когда Cookie использует символы Unicode
Cookie cookie = new Cookie("xxx",URLEncoder.encode(name,"UTF-8"));

(2) Срок действия

Срок действия файла cookie можно установить с помощью метода setMaxAge().

  • Если MaxAge является положительным числом, браузер запишет файл cookie на жесткий диск. Пока он еще не достиг MaxAge секунд, файл cookie будет действителен при входе на веб-сайт [независимо от того, закрыт ли браузер или компьютер ] Если MaxAge является отрицательным числом, файл cookie является временным и действителен в этом браузере. Если вы закроете браузер, файл cookie станет недействительным и не будет записан на жесткий диск. Значение файла cookie по умолчанию равно -1.
  • Если MaxAge равен 0, это означает удаление файла cookie.

(3) Удаление и изменение

Файлы cookie хранятся аналогично коллекциям карт, которые делятся на имена и значения, за исключением того, что оба они имеют тип String.

Исправлять

String name = "刮风这天";
Cookie cookie = new Cookie("country",URLEncoder.encode(name,"UTF-8"));

Удалить

String name = "刮风这天";
Cookie cookie = new Cookie("country",URLEncoder.encode(name,"UTF-8"));

cookie.setMaxAge(0);
response.addCookie(cookie);

printWriter.writer("Cookie已经被删除了")

(3) Доменное имя файла cookie

Атрибут домена файла cookie определяет доменное имя, которое запускает и получает доступ к файлу cookie, а значение Deomain указывается как «имя домена».

Механизм конфиденциальности и безопасности файлов cookie определяет, что файлы cookie не могут быть междоменными. Даже если это доменное имя одного уровня, разные доменные имена второго уровня не могут быть переданы, например:www.ideal.com 和 www.image..com

Если я хочу, чтобы файлы cookie между веб-страницами с одним и тем же доменным именем первого уровня могли обращаться друг к другу, мне нужно использовать метод домена

Cookie cookie = new Cookie("name","admin");
cookie.setMaxAge(1000);
cookie.setDomain(".ideal.com);
response.addCookie(cookie);
printWriter.writer("使用www.ideal.com域名添加了一个Cookie,只要一级域名是ideal.com即可访问")

(4) Путь к файлам cookie

Атрибут пути файла cookie определяет путь, который разрешает доступ к файлу cookie.

Вообще говоря, при освобождении файла cookie можно использовать ресурсы всей веб-страницы, но если для получения файла cookie требуется только определенный сервлет, другие ресурсы не могут или не должны быть получены.

Cookie cookie = new Cookie("name","admin");
cookie.setPath("/Servlet);
cookie.setMaxAge(1000);
response.addCookie(cookie);
printWriter.writer("该Cookie只能在Servlet1中可以访问到")

(5) Атрибуты безопасности файлов cookie

Протокол HTTP не только не имеет состояния, но и небезопасен! Если вы не хотите, чтобы файлы cookie передавались по незащищенным протоколам, вы можете установить для безопасного атрибута файла cookie значение true, и браузер будет передавать файл cookie только по безопасным протоколам, таким как HTTPS и SSL.

Установка безопасного атрибута не будет шифровать содержимое файла cookie. Если вы хотите обеспечить безопасность, лучше всего использовать алгоритм md5 для шифрования

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应的消息体的数据格式以及编码
        resp.setContentType("text/html;charset=utf-8");

        //获取所有Cookie
        Cookie[] cookies = req.getCookies();
    	////没有cookie为lastTime
        boolean flag = false;
        //遍历cookie数组
        if(cookies != null && cookies.length > 0){
            for (Cookie cookie : cookies) {
                //获取cookie的名称
                String name = cookie.getName();
                //判断名称是否是:lastTime
                if("lastTime".equals(name)){
                    //非第一次访问

                    flag = true;//有访问记录的time

                    //设置Cookie的value
                    //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
                    Date date  = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String str_date = sdf.format(date);
                    System.out.println("编码前:"+str_date);
                    //URL编码
                    str_date = URLEncoder.encode(str_date,"utf-8");
                    System.out.println("编码后:"+str_date);
                    cookie.setValue(str_date);
                    //设置cookie的存活时间
                    cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
                    resp.addCookie(cookie);

                    //响应数据
                    //获取Cookie的value,时间
                    String value = cookie.getValue();
                    System.out.println("解码前:"+value);
                    //URL解码:
                    value = URLDecoder.decode(value,"utf-8");
                    System.out.println("解码后:"+value);
                    resp.getWriter().write("<h1>欢迎回来,您上次访问时间为:"+value+"</h1>");

                    break;
                }
            }
        }

        if(cookies == null || cookies.length == 0 || flag == false){
            //没有,第一次访问

            //设置Cookie的value
            //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
            Date date  = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String str_date = sdf.format(date);
            System.out.println("编码前:"+str_date);
            //URL编码
            str_date = URLEncoder.encode(str_date,"utf-8");
            System.out.println("编码后:"+str_date);

            Cookie cookie = new Cookie("lastTime",str_date);
            //设置cookie的存活时间
            cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
            resp.addCookie(cookie);

            resp.getWriter().write("<h1>您好,欢迎您首次访问</h1>");
        }
    }

Символ[32] представляет пробелы в коде ASSCI, поэтому старайтесь не использовать пробелы в формате представления даты, но если вы хотите использовать пробелы или специальные символы,

Кроме того, я также могу сделать аналоговый дисплей Demo, последний просмотр записи о продукте, потренироваться

Session

(I. Обзор

Сеанс — это еще один механизм записи состояния браузера, файлы cookie сохраняются в браузере, а сеансы сохраняются на сервере. Когда пользователь использует браузер для доступа к серверу, служба записывает информацию о пользователе на сервере в той или иной форме, которая является сеансом.

Зачем использовать сеанс? Поскольку сеанс может хранить объекты, файлы cookie могут хранить только строки, что может решить многие проблемы, которые не могут решить файлы cookie.

(2) API

//获取Session被创建时间
long getCreationTime()

//获取Session的id
String getId()

//返回Session最后活跃的时间
long getLastAccessedTime()

//获取ServletContext对象
ServletContext getServletContext()

//设置Session超时时间
void setMaxInactiveInterval(int var1)

//获取Session超时时间
int getMaxInactiveInterval()

//获取Session属性
Object getAttribute(String var1)

//获取Session所有的属性名
Enumeration getAttributeNames()

//设置Session属性
void setAttribute(String var1, Object var2)

//移除Session属性
void removeAttribute(String var1)

//销毁该Session
void invalidate()

//该Session是否为新的
boolean isNew()

Сеанс имеет методы, аналогичные запросу и ServletContext. фактическиСессия также является объектом домена. Сессия как механизм записи состояния браузера,Пока объект Session не уничтожен, связь между сервлетами может осуществляться через объект Session.

настраивать

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession httpSession = request.getSession();
		httpSession.setAttribute("name", "test");
	}

Получать

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession httpSession = request.getSession();
		String value = (String) httpSession.getAttribute("name");
		System.out.println(value);
	}

(3) Жизненный цикл и срок действия

При первом доступе пользователя к сервлету сервера, jsp и другим динамическим ресурсам сеанс будет автоматически создан, а объект сеанса сохранен в памяти, поэтому в приведенном выше примере можно напрямую использовать объект запроса для получения объекта сеанса.

Если вы получаете доступ к статическим ресурсам, таким как HTML, изображение и т. д., сеанс не будет создан.

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

По мере того, как все больше и больше пользователей будут обращаться к серверу, будет все больше и больше сеансов. Для предотвращения переполнения памяти сервер удалит из памяти сессию, которая долгое время не была активной, это время также является тайм-аутом сессии.

Время ожидания сеанса по умолчанию составляет 30 минут. Существует три способа изменить время ожидания сеанса.

первый способ: Устанавливается в файле tomcat/conf/web.xml, значение времени составляет 20 минут, все веб-приложения действительны————<session-timeout>20<session-timeout>

второй способ: Устанавливается в одном файле web.xml, действителен для одного веб-приложения, в случае конфликта приоритет имеет ваше собственное веб-приложение.

Третий способ: установить методом setMaxInactiveInterval()

httpSession.setMaxInactiveInterval(60);

(4) Небольшая разница между сеансом и файлом cookie

  • Цикл сеанса относится к неактивному времени. Если мы установим сеанс на 10 с, в течение 10 с, если к сеансу нет доступа, атрибуты в сеансе будут недействительными. Если вы получите доступ к сеансу в течение 9 с, время будет повторно приурочен.

  • Если кот перезапущен, или веб-приложение перезагружено, или сеанс закрыт, сеанс также станет недействительным.Мы также можем сделать сеанс недействительным с помощью функции.Метод invalidate() делает недействительными все атрибуты в сеансе и часто используется для безопасного выхода.

  • Если вы хотите, чтобы атрибут сеанса был недействительным, вы можете использовать метод removeAttribute

  • Жизненный цикл файла cookie рассчитывается в соответствии с накопленным временем, независимо от того, посещал ли пользователь сеанс или нет.

(5) Сессия

Вопрос: я устанавливаю свойство Session в Aservlet и получаю свойство A в Bservlet

Создайте новую страницу в браузере и снова посетите Bservlet и сообщите об исключении нулевого указателя.

Теперь возникает вопрос: как сервер реализует сеанс для обслуживания браузера пользователя? Другими словами: почему сервер может предоставлять разные сеансы для разных пользовательских браузеров?

Протокол HTTP не имеет состояния, и сеанс не может определить, является ли он одним и тем же пользователем на основе HTTP-соединения. Итак: сервер отправляет файл cookie с именем JESSIONID в браузер пользователя, и его значение является значением идентификатора сеанса. Фактически, Session использует файлы cookie, чтобы определить, является ли это одним и тем же пользователем.

Проще говоря: причина, по которой Session может идентифицировать разных пользователей, зависит от файлов cookie.

Файл cookie автоматически передается сервером в браузер, и нам не нужно создавать его вручную. Значение maxAge файла cookie по умолчанию равно -1, что означает, что он используется только текущим браузером, а файл cookie не сохраняется на жестком диске.

Обзор процесса:

  • При доступе к Aservlet сервер создаст объект Session, выполнит наш программный код, выполнит наш программный код и автоматически выдаст cookie в браузер пользователя.
  • Когда я использую тот же браузер для доступа к BServlet, браузер передаст значение файла cookie на сервер через протокол Http, и сервер будет знать, какой сеанс использовать.
  • Когда мы используем браузер нового сеанса для доступа к BServlet, новый браузер не имеет файла cookie, и сервер не может определить, какой сеанс использовать, поэтому значение не может быть получено.

(6) Использование сеанса после того, как браузер отключит файлы cookie.

Возможны две ситуации: 1. Файлы cookie отключены в браузере пользователя. Большинство мобильных браузеров не поддерживают файлы cookie.

Java Web предлагает решение: перезапись URL-адреса

Класс HttpServletResponse предоставляет два метода для перезаписи URL-адреса:

encodeURL(String url)

encodeRedirectURL(String url)

Следует отметить, что эти два метода автоматически определят, поддерживает ли браузер файлы cookie.Если он поддерживает файлы cookie, переписанный URL-адрес не будет иметь jsessionid.[Конечно, даже если браузер поддерживает файлы cookie, первый раз при выводе URL-адреса , jsessionid по-прежнему будет отображаться (потому что нет файла cookie, который нужно принести)]

пример

String url = "/web-01/Servlet5";
response.sendRedirect(response.encodeURL(url));

Принцип перезаписи URL-адреса:

Перепишите информацию об идентификаторе сеанса в сводку URL-адреса, и сервер анализирует переписанный URL-адрес, чтобы получить идентификатор сеанса. Таким образом, даже если браузер отключает файлы cookie, идентификатор сеанса передается через сервер, и сессия по-прежнему может использоваться для записи пользовательского статуса.

(7) Сессионный кейс

Случай 1: Используйте сеанс для завершения простого входа пользователя

Сначала создайте класс пользователя

public class User {
	private String username = null;
	private String password = null;
	
	public User() {
	}

	public User(String username, String password) {
		super();
		this.username = username;
		this.password = password;
	}

......各种set get方法

Моделирование базы данных с помощью простых коллекций

public class UserDB {
	private static List<User> list =new ArrayList<>();
	
	static {
		list.add(new User("admin","888"));
		list.add(new User("aaa","111"));
		list.add(new User("bbb","222"));
	}
	
	//通过用户名密码查找用户
	public static User find(String username, String password) {
		
		for (User user:list) {
			if (user.getUsername().equals(username)&& user.getPassword().equals(password)) {
				return user;
			}
		}
		return null;
	}
}

Представление формы мы пишем в jsp (имитация может сказать jsp позже)

public class UserDB {
	private static List<User> list =new ArrayList<>();
	
	static {
		list.add(new User("admin","888"));
		list.add(new User("aaa","111"));
		list.add(new User("bbb","222"));
	}
	
	//通过用户名密码查找用户
	public static User find(String username, String password) {
		
		for (User user:list) {
			if (user.getUsername().equals(username)&& user.getPassword().equals(password)) {
				return user;
			}
		}
		return null;
	}
}

Получите данные, представленные формой, и узнайте, есть ли в базе соответствующий логин и пароль

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		User user = UserDB.find(username, password);
		
		//如果找不到,就是用户名或者密码出错了
		if (user == null) {
			response.getWriter().write("用户名或者密码错误,登陆失败 !");
			return;
		}
		
		//标志着用户已经登录
		HttpSession httpSession = request.getSession();
		httpSession.setAttribute("user", user);
		
		//跳转到其他页面,告诉用户已经登录成功
		response.sendRedirect(response.encodeURL("test.jsp"));
	}

Вариант 2. Используйте Session для предотвращения повторной отправки форм

Опасности дублирования отправки:

Постоянно публикуется на веб-странице голосования для достижения эффекта смахивания голосов.

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

Два распространенных дублирующих представления

Первый: вернуться и отправить повторно

Второй: задержка сети, многократные нажатия на кнопку отправки

Схематическая карта

решение:

Проблемы с сетевой задержкой:

Для второго типа сетевой задержки, которая приводит к многократной отправке данных на сервер, это проблема на стороне клиента.Мы можем использовать javaScript, чтобы предотвратить

→ Когда пользователь нажимает кнопку отправки в первый раз, данные отправляются на сервер.Когда пользователь снова нажимает кнопку отправки, данные не отправляются на сервер.

Слушатели используют события прослушивателя. Разрешить пользователю отправлять форму только один раз:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>表单提交</title>
<script type="text/javascript">
	//定义一个全局标识量:是否已经提交过表单数据
	var isCommitted = false;

	function doSubmit() {
		//false表示的是没有提交过,于是就可以让表单提交给Servlet
		if (isCommited == false){
			is Commited = true;
			return true;
		}else{
			return false;
		}	
	}
</script>
</head>
<body>
	<form action="/web-01/Lservlet" method="post" onsubmit="return doSubmit()">
		用户名:<input type="text" name="username"><br /> <input
			type="submit" value="提交">
	</form>
</body>
</html>

Обновите и отправьте вопрос:

Мы знаем, что Session можно использовать для определения того, вошел ли пользователь в систему или нет. Также говорится о принципе сеанса: разные пользовательские браузеры будут иметь разные сеансы. А почему бы не запросить и ServletContext? Объект домена запроса может быть только HTTP-запросом, и данные объекта домена запроса не могут быть получены при отправке данных формы. ServletContext представляет собой все веб-приложение.Если несколько пользовательских браузеров обращаются одновременно, данные объекта домена ServletContext будут многократно перезаписаны, то есть данные объекта домена не имеют смысла.

К этому моменту мы разобрались, что в форме тоже есть скрытое поле, и данные можно отправлять на сервер через скрытое поле.

О: Определите, соответствуют ли данные объекта домена сеанса данным, представленным скрытым доменом jsp.

B: Определите, являются ли данные скрытого поля пустыми [если они пусты, это прямой доступ к сервлету страницы обработки формы]

C: Определить, пусты ли данные Сессии [сервлет решил, стоит ли повторять отправку, лучше сразу удалить данные Сессии, иначе до ее удаления снова приходит запрос со стороны клиента, и он может быть сопоставлен снова. , что приводит к дублированию коммита. Если данные объекта домена сеанса пусты, это доказывает, что данные были отправлены! 】

D: Какие именно данные мы храним в объекте домена сеанса? Просто число? Кажется, это тоже работает. Поскольку до тех пор, пока данные объекта домена сеанса и данные, полученные скрытым доменом jsp, совпадают с числами, в любом случае после принятия решения о повторной отправке на сервлет данные сеанса будут немедленно удалены. Более профессиональный подход: данные, хранящиеся в объекте домена Session, представляют собой случайное число [Token--token].

public class TokenProcessor {
	private TokenProcessor() {
	}

	private final static TokenProcessor TOKEN_PROCESSOR = new TokenProcessor();

	public static TokenProcessor getInstance() {
		return TOKEN_PROCESSOR;
	}

	public String makeToken() {
		// 这个随机生成出来的Token的长度是不确定的
		String token = String.valueOf(System.currentTimeMillis() + new Random().nextInt(99999999));
		try {
			// 我们想要随机数的长度一致,就要获取到数据指纹
			MessageDigest messageDigest = MessageDigest.getInstance("md5");
			byte[] md5 = messageDigest.digest(token.getBytes());

			// 如果我们直接 return new String(md5)出去,得到的随机数会乱码
			// 因为随机数是任意的01010101010,在转换成字符串的时候,会差gb2312的码表
			// gb2312码表不一定支持该二进制数据,得到的就是乱码
			// 于是经过base64编码成了明文的数据
			BASE64Encoder base64Encoder = new BASE64Encoder();
			return base64Encoder.encode(md5);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}
}

Создайте случайное число токена, используйте getRequestDispatcher для перехода на страницу jsp (адрес по-прежнему сервлет)

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 生出随机数
		TokenProcessor tokenProcessor = TokenProcessor.getInstance();
		String token = tokenProcessor.makeToken();

		// 将随机数存进Session中
		request.getSession().setAttribute("token", token);

		// 跳转到显示页面
		request.getRequestDispatcher("/login3.jsp").forward(request, response);

Скрытое поле Jsp получает значение Session

<form action="/web-01/Mservlet" >

    用户名:<input type="text" name="username">
    <input type="submit" value="提交" id="button">

    <%--使用EL表达式取出session中的Token--%>
    <input type="hidden" name="token" value="${token}" >

</form>

Оценка на странице отправки формы обработки: имеет ли скрытое поле jsp значение, является ли значение в сеансе пустым и равны ли значение в сеансе и значение, полученное скрытым полем jsp

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter printWriter = response.getWriter();
		String serverValue = (String) request.getSession().getAttribute("token");
		String clienValue = request.getParameter("token");

		if (serverValue != null && clienValue != null && serverValue.equals(clienValue)) {
			printWriter.write("处理请求");
			// 清除Session域对象数据
			request.getSession().removeAttribute("token");
		} else {
			printWriter.write("请不要重复提交数据");
		}
	}

Принцип реализации очень прост

Сохраните токен в поле сеанса

Затем скрытый домен главной страницы получает токен

При первом посещении мы судим, имеет ли видение ценность, и если да, то сравниваем его. После правильного сравнения мы обрабатываем запрос, а затем удаляем данные, хранящиеся в сеансе.

Когда мы приедем снова, наша сессия не будет иметь значения, и запрос на стойке регистрации не будет принят!

(8) Разница между сеансом и файлом cookie

Сравните с хранилищем

Файлы cookie могут хранить только строки и кодировать строки, отличные от ASCII, если они должны быть сохранены.

Сеанс может хранить данные любого типа, вы можете думать о сеансе как о контейнере.

Сравните конфиденциальность и безопасность

Файлы cookie хранятся в браузере и видны клиенту. Информация легко утекает. При использовании файлов cookie лучше всего зашифровать файл cookie.

Сеансы хранятся на сервере и прозрачны для клиента. Нет проблемы утечки конфиденциальной информации.

Сравните со сроком годности

Файлы cookie хранятся на жестком диске, нужно только установить для атрибута maxAge относительно большое положительное целое число, даже если браузер закрыт, файл cookie все еще существует.

Сеанс хранится на сервере, а значение атрибута maxInactiveInterval устанавливается для определения периода действия сеанса. И сеанс зависит от файла cookie с именем JSESSIONID, который имеет атрибут maxAge по умолчанию, равный -1. Если браузер закрыт, Сессия с сервера не умирает, но тоже недействительна.

Из сравнения нагрузки на сервер

Сессия хранится на сервере, и каждый пользователь будет генерировать сессию.Если есть много пользователей с одновременным доступом, сессия не может быть использована, и сессия будет потреблять много памяти.

Файлы cookie хранятся на стороне клиента. Не занимает ресурсы сервера. Крупные веб-сайты, такие как baidu и Sina, обычно используют файлы cookie для отслеживания сеансов.

Сравните с поддержкой браузера

Файлы cookie бесполезны, если в вашем браузере отключены файлы cookie!

Если браузер отключает файлы cookie, Session может выполнять отслеживание сеанса путем перезаписи URL-адреса.

Сравните домены

Файлы cookie могут устанавливать атрибут домена для достижения междоменного

Сессия действительна только в пределах текущего доменного имени, а не между доменными именами

конец:

Если есть какие-либо недостатки или ошибки в содержании, вы можете оставить сообщение для меня, чтобы сделать комментарии, все! ^_^

Если это может вам помочь, то следуйте за мной! (Серия статей будет обновляться по мере возможности на официальном аккаунте)

Мы не знаем друг друга здесь, но мы все усердно работаем над своей мечтой ❤

Публичный аккаунт, который настаивает на продвижении оригинальной технологии Java: в идеале — более двух дней.