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