HttpSession概述
- HTTPSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端。
- HTTPSession是Servlet三大域对象之一,所以它也有setAttribute()、getAttribute()、removeAttribute()方法。
- HTTPSession底层依赖Cookie,或是URL重写。
HTTPSession的作用
- 会话范围:会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束
会话:一个用户对服务器的多次连贯性请求。所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器。 - 服务器会为每个客户端创建一个session对象,session就好比客户在服务器端的账户,它们被服务器保存到一个Map中,这个Map被称之为session缓存。
Servlet中得到session对象:HttpSession session=request.getSession();
Jsp中得到session对象:session是jsp内置对象之,不用创建就可以直接使用。 - session域相关方法:
- void setAttribute(String name,Object value)
- Object getAttribute(String name)
- void removeAttribute(String name)
案例:演示session中会话的多次请求中共享数据
<body>
<h1>向session域保存数据</h1>
<%
session.setAttribute("aaa","AAA"); //jsp内置对象,直接使用
%>
</body>
<body>
<h1>获取session中的数据</h1>
<%
String s=(String)session.getAttribute("aaa");
%>
<%=s %>
</body>
案例:演示保存用户登录信息(重要)
login.jsp:
<body>
<%--本页面提供登录表单,还有显示错误信息 --%>
<h1>登录</h1>
<%
//读取名为uname的cookie
//如果为空:显示""
//如果不为空:显示Cookie的值
String uname="";
Cookie[] cs=request.getCookies(); //获取请求中所有的Cookie
if(cs!=null){ //如果存在cookie
for(Cookie c:cs){ //循环遍历所有的cookie
if("uname".equals(c.getName())){ //查找名为uname的cookie
uname=c.getValue(); //获取这个cookie的值赋给uname
}
}
}
%>
<%
String message="";
String msg=(String)request.getAttribute("msg"); //获取request域中名为msg的属性
if(msg!=null){
message=msg;
}
%>
<font color="red"><b><%=message %></b></font>
<form action="/day11_3/LoginServlet" method="post">
用户名:<input type="text" name="username" value="<%=uname %>" /><br/>
密 码:<input type="password" name="password" /><br/>
<input type="submit" value="登录" />
</form>
</body>
LoginServlet.java
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 1、获取表单数据
*/
//处理中文问题
request.setCharacterEncoding("utf-8");
//获取
String username=request.getParameter("username");
String password=request.getParameter("password");
/*
* 2、校验用户名和密码是否正确
*/
if(!"itcast".equalsIgnoreCase(username)){ //登录成功
/*
* 附加项:把用户名保存到cookie中,发送给客户端浏览器
* 当再次打开login.jsp时,login.jsp中会读取request中的cookie,把它显示到用户名文本框中
*/
Cookie cookie=new Cookie("uname",username); //创建cookie
cookie.setMaxAge(60*60*24); //设置cookie命长为1天
response.addCookie(cookie); //保存cookie
/*
* 3、如果成功
* --保存用户信息到session中
* --重定向到succ1.jsp
*/
HttpSession session=request.getSession(); //获取session
session.setAttribute("username", username); //向session域中保存用户名
response.sendRedirect("/day11_3/session2/succ1.jsp");
}else{ //登录失败
/*
* 4、如果失败
* --保存错误信息到request域中
* --转发到login.jsp
*/
request.setAttribute("msg", "用户名或密码错误!");
RequestDispatcher rd=request.getRequestDispatcher("/session2/login.jsp"); //得到转发器
rd.forward(request, response); //转发
}
}
succ1.jsp
<body>
<h1>succ1</h1>
<%
String username=(String)session.getAttribute("username");
if(username==null){
//向request域中保存错误信息,转发到login.jsp
request.setAttribute("msg","您还没有登录!");
request.getRequestDispatcher("/session2/login.jsp").forward(request, response); //转发
return;
}
%>
欢迎<%=username %>
</body>
获取session的ID号
每一个session都有一个32位长的id号
package cn.xiaoma.uuid;
import java.util.UUID;
import org.junit.Test;
import cn.xiaoma.commons.CommonUtils;
public class UUIDTest {
@Test
public void fun1(){
UUID uuid=UUID.randomUUID();
String string=uuid.toString();
string=string.replace("-", "");
string=string.toUpperCase(); //转成大写字母
// System.out.println(string);
System.out.println(CommonUtils.uuid());
}
}
package cn.xiaoma.commons;
import java.util.UUID;
public class CommonUtils {
public static String uuid(){
return UUID.randomUUID().toString().replace("-","").toUpperCase();
}
}
HttpSession其它方法
String getId()
:获取session的id
int getMaxInactiveInterval()
:获取session的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除该session
void invalidate()
:让session失效。当session失效后,客户端再次请求,服务器会给客户端创建一个新的session。
boolean isNew()
:查看session是否为新,客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把session的id响应给客户端,这时session的状态为新。
web.xml中配置session的最大不活动时间
<session-config>
<session-timeout>30</session-timeout>
</session-config>
生成验证码图片(VerifyCode类)
VerifyCode.java
package cn.xiaoma.image;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
public class VerifyCode {
private int w=70;
private int h=35;
private Random r=new Random();
private String[] fontNames={"宋体","华文楷体","黑体","微软雅黑","楷体_GB2312"};
private String codes="23456789abcdefghijklmnpqrstuvwxyz"; //可选字符
private Color bgColor=new Color(255,255,255); //背景色
private String text; //验证码上的文本
//生成随机的颜色
private Color randomColor(){
int red=r.nextInt(150);
int green=r.nextInt(150);
int blue=r.nextInt(150);
return new Color(red,green,blue);
}
//生成随机的字体
private Font randomFont(){
int index=r.nextInt(fontNames.length);
String fontName=fontNames[index]; //生成随机的字体名称
int style=r.nextInt(4); //生成随机样式,0(无样式),1(粗体),2(斜体),3(粗体+斜体)
int size=r.nextInt(5)+24; //生成随机字号,24~28
return new Font(fontName,style,size);
}
//画干扰线
private void drawLine(BufferedImage image){
int num=3; //一共画3条
Graphics2D g2=(Graphics2D)image.getGraphics();
for(int i=0;i<num;i++){ //生成两个点的坐标,即4个值
int x1=r.nextInt(w);
int y1=r.nextInt(h);
int x2=r.nextInt(w);
int y2=r.nextInt(h);
g2.setStroke(new BasicStroke(1.5F));
g2.setColor(Color.BLUE); //干扰线是蓝色
g2.drawLine(x1,y1,x2,y2); //画线
}
}
//随机生成一个字符
private char randomChar(){
int index=r.nextInt(codes.length());
return codes.charAt(index);
}
//创建BuffredImage
private BufferedImage creatImage(){
BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
Graphics2D g2=(Graphics2D)image.getGraphics();
g2.setColor(this.bgColor);
g2.fillRect(0, 0, w, h);
return image;
}
//调用这个方法得到验证码
public BufferedImage getImage(){
BufferedImage image=creatImage(); //创建图片缓冲区
Graphics2D g2=(Graphics2D)image.getGraphics(); //得到绘制环境
StringBuilder sb=new StringBuilder(); //用来装载生成的验证码文本
//向图片中画4个字符
for(int i=0;i<4;i++){ //循环4次,每次生成一个字符
String s=randomChar()+""; //随机生成一个字母
sb.append(s); //把字母添加到sb中
float x=i*1.0F*w/4; //设置当前字符的x轴坐标
g2.setFont(randomFont()); //设置随机字体
g2.setColor(randomColor()); //设置随机颜色
g2.drawString(s,x,h-5); //画图
}
this.text=sb.toString(); //把生成的字符串赋给this.text
drawLine(image); //添加干扰线
return image;
}
//返回验证码图片上的文本
public String getText(){
return text;
}
//保存图片到指定的输出流
public static void output(BufferedImage image,OutputStream out)throws IOException{
ImageIO.write(image, "JPEG", out);
}
}
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'login.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript">
function _change(){
/*
1. 得到img元素
2. 修改其src元素为/day11_3/VerifyCodeServlet 还是这个地址,但会新生成图片
*/
var imgEle=document.getElementById("img");
imgEle.src="/day11_3/VerifyCodeServlet?a="+new Date().getTime(); //加个参数,不让浏览器缓存验证码
}
</script>
</head>
<body>
<%--本页面提供登录表单,还有显示错误信息 --%>
<h1>登录</h1>
<%
//读取名为uname的cookie
//如果为空:显示""
//如果不为空:显示Cookie的值
String uname="";
Cookie[] cs=request.getCookies(); //获取请求中所有的Cookie
if(cs!=null){ //如果存在cookie
for(Cookie c:cs){ //循环遍历所有的cookie
if("uname".equals(c.getName())){ //查找名为uname的cookie
uname=c.getValue(); //获取这个cookie的值赋给uname
}
}
}
%>
<%
String message="";
String msg=(String)request.getAttribute("msg"); //获取request域中名为msg的属性
if(msg!=null){
message=msg;
}
%>
<font color="red"><b><%=message %></b></font>
<form action="/day11_3/LoginServlet" method="post">
用户名:<input type="text" name="username" value="<%=uname %>" /><br/>
密 码:<input type="password" name="password" /><br/>
验证码:<input type="text" name="verifyCode" size="3"/>
<img id="img" src="/day11_3/VerifyCodeServlet"/>
<a href="javascript:_change()">换一张</a>
<br>
<input type="submit" value="登录" />
</form>
</body>
</html>
LoginServlet.java
package cn.xiaoma.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 校验验证码
* 1. 从session中获取正确的验证码
* 2. 从表单中获取用户填写的验证码
* 3. 进行比较
* 4. 如果相同,向下运行,否则保存错误信息到request域,转发到login.jsp
*/
String sessionCode=(String)request.getSession().getAttribute("session_vcode");
String paramCode=request.getParameter("verifyCode");
if(!paramCode.equalsIgnoreCase(sessionCode)){
request.setAttribute("msg", "验证码错误");
request.getRequestDispatcher("/session2/login.jsp").forward(request, response);
return;
}
/*
* 1、获取表单数据
*/
//处理中文问题
request.setCharacterEncoding("utf-8");
//获取
String username=request.getParameter("username");
String password=request.getParameter("password");
/*
* 2、校验用户名和密码是否正确
*/
if(!"itcast".equalsIgnoreCase(username)){ //登录成功
/*
* 附加项:把用户名保存到cookie中,发送给客户端浏览器
* 当再次打开login.jsp时,login.jsp中会读取request中的cookie,把它显示到用户名文本框中
*/
Cookie cookie=new Cookie("uname",username); //创建cookie
cookie.setMaxAge(60*60*24); //设置cookie命长为1天
response.addCookie(cookie); //保存cookie
/*
* 3、如果成功
* --保存用户信息到session中
* --重定向到succ1.jsp
*/
HttpSession session=request.getSession(); //获取session
session.setAttribute("username", username); //向session域中保存用户名
response.sendRedirect("/day11_3/session2/succ1.jsp");
}else{ //登录失败
/*
* 4、如果失败
* --保存错误信息到request域中
* --转发到login.jsp
*/
request.setAttribute("msg", "用户名或密码错误!");
RequestDispatcher rd=request.getRequestDispatcher("/session2/login.jsp"); //得到转发器
rd.forward(request, response); //转发
}
}
}
VerifyCodeServlet.java
package cn.xiaoma.servlet;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.xiaoma.image.VerifyCode;
public class VerifyCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 1. 生成图片
* 2. 保存图片上的文本到session域中
* 3. 把图片响应给客户端
*/
VerifyCode vc=new VerifyCode();
BufferedImage image=vc.getImage();
request.getSession().setAttribute("session_vcode",vc.getText()); //保存图片上的文本到session域
VerifyCode.output(image, response.getOutputStream());
}
}