一、Cookie的临时存储和定时存储
Cookie解决了不同请求的数据共享问题。是由服务器保存在客户端的小文本文件,包含了用户的信息,可以避免用户重复输入用户名和密码进行登录。浏览器请求Cookie,服务器响应时返回Cookie,浏览器存储返回的Cookie。
1、临时存储:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8");//设置服务器的编码,默认是ISO-8859-1 response.setContentType("text/html; charset = utf-8");//告诉浏览器服务器的编码格式 Cookie cookie=new Cookie("passwsord","123456"); response.addCookie(cookie); }
请求:
响应:
当访问本工程的一个不存在Cookie的Servlet时:、
可以看出请求中依旧存在Cookie,但是响应中已经没有Cookie的相关信息了:
当关闭了浏览器再次打开访问工程下的一个不存在的Servlet时:
响应和请求中均无Cookie的相关信息:
这是因为在第一次访问带有Cookie的Servlet时,Cookie被创建,但是因为Cookie存储在了浏览器的运行内存中,浏览器关闭后创建的Cookie随之消失。
2、定时存储:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8");//设置服务器的编码,默认是ISO-8859-1 response.setContentType("text/html; charset = utf-8");//告诉浏览器服务器的编码格式 Cookie cookie=new Cookie("passwsord","123456"); cookie.setMaxAge(7*24*3600);//七天 response.addCookie(cookie); }
第一次访问带有Cookie的Servlet:
请求和响应中均有Cookie。
访问同一工程下的不具有Cookie的Servlet:
请求中有Cookie,响应中没有Cookie。
关闭浏览器重新访问不带Cookie的Servlet:
请求中带有Cookie,响应中没有。这是因为此时Cookie被设定了有效期,在有效期内可以在电脑硬盘中找到,即使关闭浏览器,在有效期内Cookie依旧存在。
3、注意事项
(1)Cookie不能存储中文。
(2)一个Cookie对象只能存储一个键值对。
二、Cookie的有效路径
1、程序实现:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");//设置服务器的编码,默认是ISO-8859-1
response.setContentType("text/html; charset = utf-8");//告诉浏览器服务器的编码格式
Cookie cookie=new Cookie("passwsord","123456");
cookie.setPath("/CookieDemo_war_exploded/abc");
cookie.setMaxAge(7*24*3600);//有效期七天
response.addCookie(cookie);
}
效果:
当访问http://localhost:8080/CookieDemo_war_exploded/abc下的Servlet时,请求和响应中均有Cookie。
当改变路径访问虚拟路径不是abc的Servlet时,请求和响应中都没有Cookie的信息。(如果不对路径进行限制,请求中应该有Cookie信息)
三、Cookie的获取
1、先创建Cookie对象,设置Cookie的键和值:
Cookie cookie1=new Cookie("password1","123456");
Cookie cookie2=new Cookie("password2","123458");
Cookie cookie3=new Cookie("password3","123454");
Cookie cookie4=new Cookie("password4","123452");
cookie1.setMaxAge(1*24*3600);
cookie2.setMaxAge(1*24*3600);
cookie3.setMaxAge(1*24*3600);
cookie4.setMaxAge(1*24*3600);
response.addCookie(cookie1);
response.addCookie(cookie2);
response.addCookie(cookie3);
response.addCookie(cookie4);
2、对Cookie进行遍历:
Cookie [] cookies=request.getCookies();//获取Cookie数组
if(cookies!=null){
for (Cookie c:cookies){
String name=c.getName();
String value=c.getValue();
System.out.println(name+" "+value);
}
}
四、Cookie的删除
1、设置一个Cookie,与要删除的Cookie同名,并将有效时间设置为0:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie1=new Cookie("password1","123456");
cookie1.setMaxAge(0);
response.addCookie(cookie1);
}
可以看出响应中该Cookie的存活时间为0。
2、检验Cookie是否已经被删除:
运行程序对Cookie进行遍历:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie [] cookies=request.getCookies();
if(cookies!=null){
for (Cookie c:cookies){
String name=c.getName();
String value=c.getValue();
System.out.println(name+" "+value);
}
}
}
无论是控制台还是抓包结果,都证明Cookie已经被覆盖(删除)。
五、Cookie的应用——三天免登录
1、工程结构:
2、Servlet的运用:
(1)登录界面:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");//设置浏览器编码格式
response.getWriter().write("<html>");
response.getWriter().write("<head>");
response.getWriter().write("<title>");
response.getWriter().write("Login");
response.getWriter().write("</title>");
response.getWriter().write("</head>");
response.getWriter().write("<body bgcolor="aqua">");
response.getWriter().write("<center>");
response.getWriter().write("<h3>");
response.getWriter().write("登录");
response.getWriter().write("</h3>");
response.getWriter().write("<form action="/Servlet_login_war_exploded/login" method="get">");
response.getWriter().write(" 用户名:<input type="text" name="username" size="12"><br>");
response.getWriter().write("密 码 :<input type="password" name="password" size="6" ><br><br>");
response.getWriter().write("<input type="submit" value="登录">");
response.getWriter().write("<input type="reset" value="取消">");
response.getWriter().write("</form>");
response.getWriter().write("</center>");
response.getWriter().write("</body>");
response.getWriter().write("</html>");
}
登录界面采用纯粹的servlet开发,当然,学习过jsp后就可以用jsp代替了。
(2)LogServlet实现数据库和表单数据的连接,如果在数据库中有对应的用户登录信息则登录成功。如果是第一次登录,还需要建立Cookie,以便下次登录的时候能够直接读取Cookie中的信息,不用再手动输入自己的信息:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Connection con=null;
login log= null;
String account=request.getParameter("username");//获得表单数据
String password=request.getParameter("password");
Cookie cookie=new Cookie(account,password);
cookie.setPath("/Servlet_login_war_exploded/cookie");
cookie.setMaxAge(3*24*3600);//三天
response.addCookie(cookie);
try {
con=C3p0Utils.getConnection();
QueryRunner qr = new QueryRunner();
String sql = "Select * from login where account=? and password=?";
Object[] select = {account,password};
log = qr.query(con, sql, new BeanHandler<login>((login.class)), select);
if(log!=null){
response.getWriter().write("nihao"+account);
}
else{
response.getWriter().write("wrong");
}
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
在响应中,存在Cookie信息和Cookie的过期时间。
(3)查询Cookie是否存在,如果存在,再与数据库中的信息进行对比(只有Cookie是不行的,防止用户已经对账户注销,即数据库中已经没有了用户的信息,而使用Cookie进行登录显然是不合理的)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");//设置浏览器编码格式
Cookie[] cookies=request.getCookies();
Connection con=null;
login log= null;
int successNum=0;
try {
con= C3p0Utils.getConnection();
QueryRunner qr = new QueryRunner();
String sql = "Select * from login";
List<login> list = qr.query(con, sql, new BeanListHandler<login>((login.class)));
if(cookies!=null) {//验证数据库中是否有与Cookie对应的用户
for (int i = 0; i < list.size(); i++) {
log= list.get(i);
for (Cookie cookie : cookies) {
if((log.getAccount().equals(cookie.getName()))&&(log.getPassword().equals(cookie.getValue()))){
successNum++;
}
}
}
if(successNum>=1){
response.getWriter().write("Successful login with Cookie!");
}
else{
request.getRequestDispatcher("page").forward(request,response);
}
}
else{
request.getRequestDispatcher("page").forward(request,response);//请求转发
}
}
catch (SQLException e) {
throw new RuntimeException(e);
}
}
(4)过程演示:
第一次访问CookieServlet(因为没有Cookie,或者没有符合要求的Cookie,因此要手动输入实现登录):
点击登录(在这个过程中,已经生成了Cookie):
第二次访问CookieServlet(将Cookie中的信息与数据库中的数据进行比对),下图是已经有Cookie的情况:
显然:第二次访问的时候,没有登录界面,可以直接调用Cookie中的数据。