Cookie
将会话相关的数据保存到浏览器中,并且在每次访问服务器时都带过去。
Cookie最多可以存放300个 一个浏览器最多可以保存20个cookie,每个cookie存放大小不得超过4KB
Cookie分类
会话级别Cookie 如果将一个值存到cookie中,并未设置MaxAge,那么这个Cookie就是会话级别的Cookie,当浏览器关闭后或服务器关闭时,该会话的Cookie会被清空
持久保存Cookie:设置过MaxAge的Cookie为持久Cookie,保存的时候会以秒为单位,此Cookie浏览器关闭打再次打开,Cookie值不会消失
Cookie常用的方法
‘ setMaxAge()设置Cookie数据存储时间,秒为单位
setPath()- 用来设置浏览器在访问哪个路径及其自路径时带着当前的cookie信息过来,如果一个cookie不设置maxage,则默认的path为当前发送cookie的servlet在的路径 setDomain与getDomain方法 -- 设置当访问哪个域名时带着当前cookie,只要设置过这个方法,浏览器拒绝接受
response.addCookie(cookie);向response缓存区存入一个cookie,服务器将这个cookie刷入浏览器
request.getCookies();从浏览器取得一个cookie列表
如何删除一个cookie
浏览器根据cookie的名字+cookie的path+cookie的domain来判断两个cookie是否是同一个,如果是同一个则新发送会覆盖旧的
所以想要删除一个cookie,只要发送一个同名、同path的cookie并且设置这个cookie的MaxAge为0,浏览器接到这个cookie覆盖旧地,立即超时删除,就可以删除一个cookie了
cookie存储中文
如果一个cookie要存储一个中文,那么需要先将该中文由URL重写技术将中文编为URL,存储到Cookie,如果需要使用的时候,出来使用URL解码
存储
String username = "王秀强";
username = URLEncoder.encode(username,"gb2312");
读取
URLDecoder.decode(username,"gb2312")
Session
session是一个域对象,用户存储数据
作用范围:整个会话范围
生命周期:在第一次明确调用request.getSession()方法时创建session。如果session超过30分钟(可以在web.xml中进行配置)没有人使用,则服务器认为session已经失效,销毁session。也可以明确的调用session.invalidate方法,立即销毁session。如果服务器非正常关闭则session随着服务器关闭而销毁。
当服务器正常关闭时,还没有超时的ssession会以文件的形式保存在tomcat/work下,这个过程叫做session的钝化。下次服务器正常启动时,钝化着的session会被恢复到内存中,这个过程叫做session的活化。
配置设置一个Session有效时间
在web.xml中:
<session-config>
<session-timeout>1000</session-timeout>
</session-config>
session的原理、利用session的原理,在多个浏览器中共用session
session的原理:基于一个特殊的cookie JSESSIONID 工作,在生成session时服务器以JSESSIONID为名字发送session的id值到浏览器保存,以后浏览器在访问服务器时都带着这个id找对应的session服务。
如何使同一台计算机内的多个浏览器公用session:只要手动的发送一个JSESSIONID cookie,其中path设为web应用名称,设置maxage时浏览器将此cookie以文件形式保存在浏览器缓存区中,从而实现多个浏览器公用一个JSESSIONID cookie,从而公用session
3.禁用cookie的情况下如何使用session -- url重写
request.getSession() 检查cookie中有没有一个叫JSESSIONID 的cookie,如果有,则拿它的值作为session的id找到对应的session返回。如果没有这个cookie则检查请求的URL后是否跟了JSESSIONID属性,如果有则拿它的值作为session id找对应的session返回。如果两个都找不到,则创建一个新的session出来,返回,并且设置JSESSIONID cookie 发送给浏览器
response.encodeURL() 可以实现URL重写操作,但是要注意,在进行重写之前,一定要先创建出session。如果浏览器带来了任何cookie,服务器就认为当前浏览器没有仅用过cookie,URL重写的操作将不会进行。
4、Session常用的方法
session1.setAttribute("", "");//设置一个session属性
session1.getAttribute("");//取得一个session属性
session1.getAttributeNames();//取得所以的session的名字
session1.removeAttribute("");//删除一个Session属性
session1.setMaxInactiveInterval();//设置session保存时间
小例子:
防止表单重复提交
(1)js验证,只可以提交一次
缺点:无法对非正常登录用户进行限制
var flag=false;
function validata(){
if(flag){
return true;
}
else{
flag=true;
return false;}
}
(2)----在jsp页面(Servlet)生成一个随机数,并存储到session中,
----同时在jsp页面将这个随机数的值存储到一个隐藏域中,并发送到servlet中
----在Servlet中验证session中与jsp页面传过来的隐藏域中的值是否相等,如果相等可以执行下面的操作,并把session赋值为空。
jsp如果提交过一次,并且已在处理,这时再次点击登录,session值已被处理完为空,域中值为随机数,到Servlet再次验证提示登录重复,不再让其下一步操作
《JSP》
<h1>
欢迎登录
</h1>
<br />
<form action="<%=request.getContextPath()%>/servlet/LoginServlet"
method="POST">
用户名:
<input type="text" name="username" id="username" />
<br />
密码:
<input type="password" name="password" id="password" />
<br />
<input type="submit" value="登录">
<%
Random random = new Random();
int randomNum = random.nextInt(1000 - 900) + 900;
request.getSession().setAttribute("randomNum", randomNum + "");
%>
<input type="hidden" name="randomNum" value="<%=randomNum%>">
</form>
《Servlet》
public boolean loginInitVali(HttpServletRequest request) {
Object randomNumObj = request.getSession().getAttribute("randomNum");
if (randomNumObj != null) {
int sessionRandomNum = Integer.parseInt(randomNumObj + "");
String randomNumStr = request.getParameter("randomNum");
if (randomNumStr != null
&& sessionRandomNum == Integer.parseInt(randomNumStr)) {
return true;
}
}
return false;
}
实现一次性验证码<图片验证码>
《JSP》 指导用户输入图片验证码
<h1>
欢迎登录
</h1>
<br />
<form action="<%=request.getContextPath()%>/servlet/LoginServlet"
method="POST">
用户名:
<input type="text" name="username" id="username" />
<br />
密码:
<input type="password" name="password" id="password" />
<br />
请输入下图验证码:
<input type="text" name="valiStr" id="valiStr" />
<br />
<img src="/Servlet_Cooki_Session/servlet/ImageServlet"
style="cursor: pointer;" οnclick="imgVali()" id="valiImg"
name="valiImg" />
<input type="submit" value="登录">
</form>
《Servlet》LoginServlet 接收session中的验证码图片的验证码和JSP传过来的用户输入的验证码进行验证
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 验证图片验证
HttpSession sessionImg = request.getSession();
Object valiImgObj = sessionImg.getAttribute("valiStr");
String randomStr = null;
if (valiImgObj != null) {
randomStr = valiImgObj.toString();
}
String subStr = request.getParameter("valiStr");
if (subStr != null && !"".equals(subStr) && randomStr != null
&& randomStr.equals(subStr)) {
System.out.println("现在成功了 验证码是" + subStr);
} else {
return;
}
《Servlet》ImageServlet 生成一个验证码图片并存到session里面
package com.itheima.valiimg;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ImageServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 使用java图形界面技术绘制一张图片
int charNum = 4;
int width = 30 * 4;
int height = 30;
// 1. 创建一张内存图片
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 2.获得绘图对象
Graphics graphics = bufferedImage.getGraphics();
// 3、绘制背景颜色
graphics.setColor(Color.YELLOW);
graphics.fillRect(0, 0, width, height);
// 4、绘制图片边框
graphics.setColor(Color.BLUE);
graphics.drawRect(0, 0, width - 1, height - 1);
// 5、输出验证码内容
graphics.setColor(Color.RED);
graphics.setFont(new Font("宋体", Font.BOLD, 20));
// 随机输出4个字母
Graphics2D graphics2d = (Graphics2D) graphics;
String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random random = new Random();
int x = 5;
// 建立一个缓存区 存储验证码
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
int index = random.nextInt(26);
String content = String.valueOf(s.charAt(index));
sb.append(content);
double theta = random.nextInt(45) * Math.PI / 180;
graphics2d.rotate(theta, x, 18);
graphics2d.drawString(content, x, 18);
graphics2d.rotate(-theta, x, 18);
x += 30;
}
request.getSession().setAttribute("valiStr", sb.toString());
// 6、绘制干扰线
graphics.setColor(Color.GRAY);
for (int i = 0; i < 30; i++) {
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
graphics.drawLine(x1, y1, x2, y2);
}
// 释放资源
graphics.dispose();
// 图书输出 ImageIO
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
}
}