web应用程序会话管理的基本方式,就是在此次请求中,将下一次请求时服务器应该知道的信息,先响应给浏览器,由浏览器在之后的请求再一并发送给应用程序,这样应用程序就可以"得知"多次请求的相关数据.
Cookie是在浏览器存储信息的一种方式,服务器可以响应浏览器set-cookie标头,浏览器收到这个标头与数值后,会将它以文件的形式存储在计算机上,这个文件就称为Cookie.
Cookie有一个存活期限,保留一些有用的信息在客户端,如果关闭浏览器之后,再次打开浏览器并链接服务器时,这些Cookie仍在有效期限中,浏览器会使用cookie标头自动将Cookie发送给服务器,服务器就可以得知一些先前浏览器请求的相关信息.
Cookie可以设定存活期,所以在客户端存储的信息可以活得更久一些(除非用户主动清除Cookie信息).
Servlet本身提供创建、设置与读取Cookie得API。
session和Cookie的不同之处在于:session会随浏览器的关闭而失效,但Cookie会一直存放在客户端机器上,除非超过Cookie的生命期限。
由于安全性原因,使用Cookie客户端浏览器必须支持Cookie才行。客户端完全可以设置禁用Cookie。
创建Cookie的方式:
Cookie cookie = new Cookie(“Cookie名称”,“Cookie数值”);
如:
Cookie cookie = new Cookie(“user”,“caterpillar”);
设置cookie的存活期限:
cookie.setMaxAge(7*24*60*60);//单位为秒,这里相当于7天
注意:使用Cookie对象必须设置其生存期限,否则Cookie将会随浏览器的关闭而自动消失
在响应中添加Cookie:
response.addCookie(cookie);
访问客户端Cookie使用request对象,request对象提供了getCookie()方法,该方法返回客户端机器上所有Cookie.
Cookie[] cookies = request.getCookies();
寻找我们需要的Cookie,getCookies返回的是一个数组,这时候我们需要遍历该数组每一个元素,根据Cookie的名称找到希望访问的Cookie.
Cookie也存在编码问题:
默认情况下,Cookie值不允许出现中文字符,如果需要值为中文内容的Cookie,则可以借助java.net.URLEncoder先对中文字符进行编码,将编码后的结果设为Cookie值.
读取时,则应该先读取,然后使用java.net.URLDecoder对其进行解码.
同一个Cookie存储多个键值对:
如下:
Cookie cookie = new Cookie("name", "admin");
Cookie cook = new Cookie("pass", "123456");
cook.setMaxAge(24 * 60 * 60);
cookie.setMaxAge(24 * 60 * 60);
response.addCookie(cookie);
response.addCookie(cook);
案例:向客户端写一个username的Cookie,并访问,且设置输入正常的中文字符的Cookie内容.
cookie.jsp(写cookie)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String name = request.getParameter("name");
Cookie c = new Cookie("username",name);
c.setMaxAge(24*60*60);//24小时有效期
response.addCookie(c);
%>
</body>
</html>
如下图:
getCookie.jsp(获取希望访问的Cookie)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Cookie[] cookies = request.getCookies();
for(Cookie c:cookies){
if(c.getName().equals("username")){
out.println(c.getValue());
}
}
%>
</body>
</html>
如下图:
cnCookie.jsp(编码设置和获取)
<%@page import="java.net.URLEncoder"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Cookie c = new Cookie("username",URLEncoder.encode("孙悟空","UTF-8"));
c.setMaxAge(24*60*60);//24小时有效期
response.addCookie(c);
Cookie[] cookies = request.getCookies();
for(Cookie co:cookies){
if(co.getName().equals("username")){
out.println(URLDecoder.decode(co.getValue()));
}
}
%>
</body>
</html>
如下图:
存
入中文之前先用java.net.URLEncoder进行编码,读取时需要对读取的cookie值用java.net.URLDecoder进行解码
Cookie应用案例:实现用户自动登录功能.在用户登录窗体上,经常会看到有个自动登录的选项,登陆时选取该选项,下次登录时就不必重复输入名称密码,就可以直接登录.设计一个登录页面,当点击自动提交的时候,保存name和pass到同一cookie中,登录页面login.jsp,若登录成功通过long.java转发到su.jsp页面.若失败则重定向回long.jsp页面
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function check() {
document.getElementById("check1").value = "auto";
}
</script>
</head>
<body>
<%
Cookie[] cookies = request.getCookies();
String name = "", pass = "";
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("name")) {
name = cookie.getValue();
}
if (cookie.getName().equals("pass")) {
pass = cookie.getValue();
}
}
}
%>
<%=name%>
<%=pass%>
<center>
<form action="Login" method="post">
名称:<input type="text" name="name" value="<%=name%>"><br>
密码:<input type="password" name="pass" value="<%=pass%>"><br>
自动登录:<input type="checkbox" name="login" value="" id="check1"
οnclick="check()"><br> <input type="submit">
</form>
</center>
</body>
</html>
显示如下图:
输入名称:admin 密码:123456,但是不点击自动登录,如下图,
然后点击提交后,如下图:
从该图
可以看出登录成功了,但是没有点击自动登录,cookie的值并没有保存下来.
关闭后再次登录,如下图:
可以发现,没有点击自动登录,再次登录的时候,名称和密码是空的,而且name和pass是没有保存下来的.
接下来对比一下,点击自动登录按钮后的变化.
如下图 ,输入正确名称 和密码,点击自动登录,再点击提交按钮
点击提交按钮后,转发到su.jsp页面
如下图,发现name,和pass都保存到了cookie中:
关闭浏览器,重新打开login.jsp
如下图:发现,cookie已经把名称和密码保存下来了,就省了再次输入.
Login.java:(控制页面实现转发和重向的Servlet:主要为了实现表现层的独立(在Servle里实现表现层代码不好写)
package Servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.User;
/**
* Servlet implementation class Login
*/
@WebServlet("/Login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Login() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String pass = request.getParameter("pass");
if ("admin".equalsIgnoreCase(name) && "123456".equals(pass)) {
String login = request.getParameter("login");
System.out.println(login);
if ("auto".equals(login)) {
Cookie cookie = new Cookie("name", "admin");
Cookie cook = new Cookie("pass", "123456");
//cookie期限必写,否则浏览器关闭了,cookie就消失了.
cook.setMaxAge(24 * 60 * 60);
cookie.setMaxAge(24 * 60 * 60);
response.addCookie(cookie);
response.addCookie(cook);
}
request.setAttribute("name", name);
request.getRequestDispatcher("su.jsp").forward(request, response);
} else {
response.sendRedirect("login.jsp");
}
}
}
当用户名密码正确时请求转发到su.jsp页面
su.jsp(用户名密码正确时才转发到该页面)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=request.getParameter("name")%>登录成功!
</body>
</html>
如下图:
否则重定向到login.jsp登录页面
如下图:
输入xiaoqiao,页面没有改变,实际上已经提交请求,但是密码用户名错误,然后重定向回到了登录页面
cookie的验证,需要设置自己的浏览器cookies配合运行,才能看到效果.