1.5(学习笔记)Cookie
一、Cookie简介
Cookie是网站发送的一小段数据,在用户访问浏览网站时通过浏览器存储在用户的计算机上。
主要用于记录一些用户状态信息,例如记录用户的账号,当前所在地等,根据这些信息网站
可以提供更精确的服务以及个性化的功能。
HTTP本身是无状态的,Cookie可以看做是对其的一种补充。比有个商人叫HTTP经常和我们做交易,
但是HTTP没有记性,他不记得之前和我们做的交易的相关信息,它想了一个办法每次交易后写个纸条,
把一些关键信息存下来,还在给这个纸条设置下有效期,以及各种信息(比如交易双方是谁才有效等)。
然后把这个纸条给我们保存起来,下次交易的时候我们把这个纸条给HTTP,它就会根据记录的信息和我们
交易。这个纸条就是Cookie。
1.Cookie设置过程:
1.1.1用户发送请求(初次请求,此时用户本地没有Cookie)。(相当于我们和商人第一次交易)
1.1.2服务器响应+设置Cookie保存在用户本地。(交易完后商人写个纸条给我们保存。)
1.1.3用户发送请求+Cooike。(下一次交易时,我们把纸条給商人。)
1.1.4服务器响应。(商人根据纸条记录的信息和我们进行交易。)
2.Cookie有效期
Cookie的有效期通过void setMaxAge(int expiry)设置。
expiry以秒为单位指定Cookie的有效期,expiry如果为负则代表该Cookie存储在浏览器内存中,
即浏览器不关闭时有效,关闭后该Cookie无效。(默认为-1)
如果为0则表示删除此Cookie。
为正数则代表该Cookie存活时间,expiry单位为秒。
不同浏览器Cookie不共享。
3.Cookie的域和路径
3.1Cookie的域
Cookie是区分域的,即区分那些域名可以访问Cookie。
例如www.baidu.com的Cookie不会提交到www.google.com上。
Cookie的域默认为当前请求资源的域名。
例如先向www.baidu.com发送请求,服务器会将一些Cookie写到浏览器。
这个Cookie的域就是.baidu.com。后续浏览器再向www.google.com发送请求时
不会发送域为.baidu.com的Cookie.
Cookie的域可以通过public void setDomain(java.lang.String pattern)设置。
pattern必须以‘.’开头,例如.baidu.com
就代表该cookie可以被www.baidu.com服务区读取。
name相同,但域不相同的Cookie认为是不同Cookie。
3.2Cookie的路径
Cookie的路径是区分项目下那些路径可以使用那些Cookie。
默认为‘/’即根目录下(即默认域下所有应用)都可以使用Cookie。
以访问www.google.com为例
假如设置Cookie1路径为/testServlet/则www.google.com下的testServlet可以访问Cookie1。
接着再设置一个Cookie2位/testServlet/temp1/,则Cookie2只能被www.google.com下的/testServlet/temp1/
下的资源访问,/testServlet/下的其他目录,例如/testServlet/temp2/可以访问Cookie1,
但不能访问Cookie2.
路径还可以和域配合使用,
例如先设置域 setDomain(.google.com);
然后设置路径 setPaht("/app1/");
代表只有位于www.google.com服务器下的app1才能使用该Cookie。
二、Cookie实例
Cookie实现保存记住密码。
程序流程:
先访问LoginServlet
LoginServlet功能:
if(Cookie存在){
获取Cookie中username和password;
将值设置到登录界面;
}
请求转发到登录页面;
登录界面点击提交后调用LoginCheckServlet
LoginCheckServlet功能:
if(用户名密码正确 && Cookie为空 && 已选择记住密码){
设置Cookie;//不正确的密码不进行记录
}
检查用户名和密码并输出页面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<!-- http://localhost:8080/ -->
<form name = f1 action = "/TestServlet/LoginCheck" method = "post">
username:<input type = "text" name = "username" value = "${un}"></input><br>
password:<input type = "password" name = "password" value = "${pw}"></input><br>
记住密码 :<input type = "radio" name = "SavePassword" value = "1"><br>
<input type = "submit" value = "登录">
</form>
</body>
</html>
LoginServlet:主要功能如果有Cookie则设置Cookie数据到登录界面,最后跳转到登录界面。
如果是之前已经选择记住密码且登录正确,则登录界面会自动填充之前输入的用户名和密码。
反之,登录界面则没有数据填充。
import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class Login extends HttpServlet{
private String username = null;
private String password = null;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
Cookie[] cookies = req.getCookies();
//如果Cookie存在,获取Cookie信息设置到登录界面。
if(cookies != null) {
username = req.getParameter("username");
password = req.getParameter("password");
findUserAndPasswordCookies(cookies);
req.setAttribute("un", username);
req.setAttribute("pw", password);
}
//请求转发到登录界面
req.getRequestDispatcher("/login.jsp").forward(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(req, resp);
} //从Cookie中寻找用户名以及密码
private void findUserAndPasswordCookies(Cookie[] cookies) {
for(Cookie c:cookies) {//遍历Cookies选择用户名和密码
if("username".equals(c.getName())) {
username = c.getValue();
}
if("password".equals(c.getName())) {
password = c.getValue();
}
}
}
}
LoginCheckServlet:如果没有Cookie,用户密码输入正确,且已勾选记住密码则设置Cookie。
最后后检查密码,并输出界面。
import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class LoginCheck extends HttpServlet{
private String username = null;
private String password = null; @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码格式为utf-8
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
username = req.getParameter("username");
password = req.getParameter("password");
//如果登录密码正确,Cookie为空且用户已选择记住密码,则设置Cookie
if(checkPassword() && req.getCookies() == null &&
"1".equals(req.getParameter("SavePassword"))) {
//设置Cookie
setUserAndPasswordCookies(username, password, req , resp);
}
//检查密码,并输出界面
checkUserAndPassword(username,password, out);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
} //设置Cookie
private void setUserAndPasswordCookies(String username, String password,
HttpServletRequest req ,HttpServletResponse resp) {
//设置Cookie
Cookie usernameCookie = new Cookie("username",username);
Cookie passwordCookie = new Cookie("password",password);
//设置存在时间为一周
usernameCookie.setMaxAge(60*60*24*7);
passwordCookie.setMaxAge(60*60*24*7);
//添加Cookie
resp.addCookie(usernameCookie);
resp.addCookie(passwordCookie);
} //检查输入的用户名和密码是否正确。此处使用固定值测试。
private void checkUserAndPassword(String username,String password, PrintWriter out) {
//打印HTML头部代码
printHtmlPage(out,true);
if(checkPassword()) {
out.println("<h1>欢迎" + username + "登录!</h1>");
}else {
out.println("<h1>登录失败!</h1>");
}
//打印HTML尾部代码
printHtmlPage(out,false);
} //打印HTML页面,head为True打印HTML头部代码,为false打印尾部HTML代码
private void printHtmlPage(PrintWriter out, boolean head) {
if(head) {
out.println("<!DOCTYPE html>\r\n" +
"<!-- http://localhost:8080/TestServlet/Test.html -->\r\n" +
"<html>\r\n" +
"<head>\r\n" +
"<meta charset=\"UTF-8\">\r\n" +
"<title>Insert title here</title>\r\n" +
"</head>\r\n" +
"<body>");
}else {
out.println("</body>\r\n" +
"</html>");
}
} //检查用户名、密码,正确返回true,反之返回false
private boolean checkPassword() {
if("hcf".equals(username) && "123456".equals(password))
return true;
else
return false;
}
}
先访问LoginServlet,输入用户名hcf,密码123456.
勾选记住密码然后点击登录,弹出登录成功界面。
然后再次访问LoginServlet,此时的登录页面已经填充好了用户名和密码。
参考资料:https://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_path
http://www.cnblogs.com/andy-zhou/p/5360107.html
1.5(学习笔记)Cookie的更多相关文章
- Web客户端数据存储学习笔记——Cookie
今天对登录访问的安全以及web客户端存储做了一些大致的学习,决定在这方面加深理解,记录在博客里.第一个接触到的是Cookie... WHAT? WHY? HOW? 在学习cookie的使用时发现其名称 ...
- 重温Servlet学习笔记--Cookie对象
首先要了解cookie必须得先了解http协议,,Cookie是http协议指定的,先由服务器保存cookie到浏览器,在下次浏览器请求服务器时把上次请求得到的cookie归还给服务器,cookie以 ...
- Web安全测试学习笔记(Cookie&Session)
一,Session:含义:有始有终的一系列动作\消息1, 隐含了“面向连接” 和“保持状态”两种含义2, 一种用来在客户端与服务器之间保持状态的解决方案3, 也指这种解决方案的存储结构“把××保存在s ...
- 20151224jquery学习笔记---cookie插件
hello,祝自己平安夜快乐. Cookie 是网站用来在客户端保存识别用户的一种小文件.一般来用库可以保存用户登录信息.购物数据信息等一系列微小信息.一. 使用 cookie 插件官方网站: htt ...
- JS学习笔记 - cookie设置、读取、删除
<script> // 设置cookie function setCookie(name, value, iDay) { var oDate = new Date(); oDate.set ...
- [原创]java WEB学习笔记30:Cookie Demo 之显示最近浏览的记录
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- [原创]java WEB学习笔记29:Cookie Demo 之自动登录
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- [原创]java WEB学习笔记28: 会话与状态管理Cookie 机制
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Python3+Selenium3+webdriver学习笔记11(cookie处理)
#!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记11(cookie处理)'''from selenium im ...
- Javaweb学习笔记5—Cookie&Session
今天来讲javaweb的第五阶段学习. Cookie和Session同样是web开发常用到的地方. 老规矩,首先先用一张思维导图来展现今天的博客内容. ps:我的思维是用的xMind画的,如果你对我的 ...
随机推荐
- region xx not deployed on any region server
ERROR: Region { meta => month_hotstatic,860010-2288000000_201405_5_exit_00000047486,1400144486405 ...
- 转:一个Restful Api的访问控制方法(简单版)
最近在做的两个项目,都需要使用Restful Api,接口的安全性和访问控制便成为一个问题,看了一下别家的API访问控制办法. 新浪的API访问控制使用的是AccessToken,有两种方式来使用该A ...
- 【poj3415-长度不小于k的公共子串个数】后缀数组+单调栈
这题曾经用sam打过,现在学sa再来做一遍. 基本思路:计算A所有的后缀和B所有后缀之间的最长公共前缀. 分组之后,假设现在是做B的后缀.前面的串能和当前的B后缀产生的公共前缀必定是从前往后单调递增的 ...
- Codeforces Round #475 Div. 2 A B C D
A - Splits 题意 将一个正整数拆分成若干个正整数的和,从大到小排下来,与第一个数字相同的数字的个数为这个拆分的权重. 问\(n\)的所有拆分的不同权重可能个数. 思路 全拆成1,然后每次将2 ...
- [Leetcode Week11]Kth Largest Element in an Array
Kth Largest Element in an Array 题解 题目来源:https://leetcode.com/problems/kth-largest-element-in-an-arra ...
- Oracle基础 08 用户角色 user/role
--查询帐户的状态select username,account_status from dba_users where username='SCOTT'; --创建用户create user jo ...
- 【C++】隐式类型转换和 explicit关键字
来自:黄邦勇帅 1. 当类中带有一个参数的构造函数时,将执形对象的隐式转换,比如有类 A,有一个带有一个参数的构造函数A(int i){}则当出现语句A m=1;就会调用带有一个参数的构造函数来创建对 ...
- tkinter之事件绑定
- PostgreSQL9.6.3的REDIS测试
安装redis_fdwcd /usr/local/srcgit clone https://github.com/pg-redis-fdw/redis_fdw.gitcd redis_fdw/git ...
- Laravel5.5新特性
1.新的报错页面 报错更加美观,并标记显示出错误的代码 2.包的自动配置 在conposer.json文件中加入包中的配置,下载后就会自动配置到app.php 文件中,使用更方便 在之前的 Larav ...