HttpSession
一.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);
三.HttpSession原理
- request.getSession()方法:
获取Cookie中的SessionId:
如果sessionId不存在,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
如果sessionId存在,通过sessionId查找到了session对象,则不会创建session对象了。
四.HttpSession其他方法
- String getId(); 获取sessionId;
- int getMaxInactiveInterval(); 获取session可以的最大不活动时间,默认为30分钟,当session在30分钟内没有使用,那么tomcat会在session池中移除
- void invalidate(); 让session失效,调用这个方法会使session失效,当session失效后,客户端再次请求,服务器会给客户端一个新的session
- booleam isNew(); 查看session是否为新,但客户端第一次请求时,服务器为客户端创建session,但这时服务器没有响应客户端
五.案例
保存登录信息 + 验证码
各页面和Servlet内容:
login.jsp:提供登录表单,提交表单到LoginServlet
LoginServlet:获取请求你参数,效验用户是否登录成功
失败:保存错误信息到request域,转发到login.jsp显示request域中的错误信息
成功:保存用户到session域中,重定向到success1.jsp
success1.jsp:从session域获取用户信息,如果不存在,显示“没有登录”,存在显示用户信息
success2.jsp:从session域获取用户信息,如果不存在,显示“没有登录”,存在显示用户信息,只能从success1.jsp中进入
只要用户没有关闭浏览器,session就一直存在,那么保存在session中的用户信息也就一直存在,则进入success1.jsp和success2.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>
</head>
<body>
<%--
功能:
1.提交登录用户名密码(并查看是否有cookie);
2.登录失败:显示登录信息,并且没有登录时不会显示,通过request域中保存的信息判断是否输出
--%>
<%
Cookie[] cs = request.getCookies();
String uname = "";
if(cs != null){
for(Cookie ck : cs){
if("uname".equals(ck.getName())){
uname = ck.getValue();
break;
}
}
}
String msg = (String) request.getAttribute("msg");
String message = "";
if(msg != null){
message = msg;
}
%>
<h1>登录</h1>
<h2 style="color:red;"><%=message %></h2>
<form action="/temp/LoginServlet" method="post">
用户名:<input type="text" name="username" value="<%=uname%>"/><br>
密 码:<input type="password" name="password"/><br>
验证码:<input type="text" name="verifycode"/>
<img id="img" src="/temp/VerifyCodeServlet">
<a href="javascript:_change()">换一张</a>
<br>
<input type="submit" value="提交">
</form>
</body>
<script type="text/javascript">
//换一张验证码图片:通过新的请求实现,而且要带着参数请求
function _change(){
var imgfile = document.getElementById("img");
imgfile.src = "/temp/VerifyCodeServlet?a=" + new Date().getTime();
}
</script>
</html>
success1.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>
<%--
功能:
1.判断是否登录过
没有登录:request转发到登录页面进行登录,并且给出提示信息
登录成功:输出欢迎信息
--%>
<%
String username = (String) session.getAttribute("username");
if(username == null){
request.setAttribute("msg","没有登录!");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
%>
<h1>欢迎<%=username %></h1>
<a href="success2.jsp">2.jsp</a>
</body>
</html>
success2.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>
<%--
功能:
1.只能通过success1.jsp中的超链接访问
2.可以根据是否登录给出提示
--%>
<%
String username = (String) session.getAttribute("username");
if(username == null){
request.setAttribute("msg","没有登录!");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
%>
<h1>欢迎<%=username %></h1>
</body>
</html>
LoginServlet
package temp1;
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 final class LoginServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = -8131105561314680017L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
*功能:
*1.得到表单提交的用户名密码,然后判断是否正确
*2.正确->给浏览器设置cookie方便下一次登录,将用户名保存到session域中去,并重定向到success1.jsp,
*3.错误->保存错误信息到request域,通过请求转发到login.jsp
*/
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String vcode = req.getParameter("verifycode");
String tvcode = (String) req.getSession().getAttribute("session_vc");
if(!vcode.equalsIgnoreCase(tvcode)){
req.setAttribute("msg", "验证码错误");
req.getRequestDispatcher("login.jsp").forward(req, resp);
return;
}
if("back".equals(username) && "nick".equals(password)){
Cookie cookie = new Cookie("uname", username);
cookie.setMaxAge(60*60*24);
resp.addCookie(cookie);
HttpSession session = req.getSession();
session.setAttribute("username", username);
resp.sendRedirect("/temp/success1.jsp");
}else{
req.setAttribute("msg", "用户名或密码错误");
RequestDispatcher rd = req.getRequestDispatcher("login.jsp");
rd.forward(req, resp);
}
}
}
随机生成验证码图片 VerifyCode
package temp1;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
public class VerifyCode {
private int w = 80;
private int h = 35;
private Random r = new Random();
private String[] fontNames = {"宋体","华文楷体","黑体","微软雅黑","楷体"};
private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
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);
int size = r.nextInt(5) + 24;
return new Font(fontName,style,size);
}
private char randomChar(){
int index = r.nextInt(codes.length());
return codes.charAt(index);
}
private BufferedImage createImage(){
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 = createImage();
Graphics2D g2 = (Graphics2D) image.getGraphics();
StringBuilder sb = new StringBuilder();
for(int i = 0;i<4;i++){
String s = randomChar() + "";
sb.append(s);
float x = i * 1.0F * w / 4;
g2.setFont(randomFont());
g2.setColor(randomColor());
g2.drawString(s, x, h-5);
}
this.text = sb.toString();
return image;
}
public String getText(){
return text;
}
public static void output(BufferedImage image,OutputStream out)throws IOException{
ImageIO.write(image, "JPEG", out);
}
}
得到验证码图片并输出
package temp1;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.junit.Test;
public class VerifyCodeServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 5717417590080133474L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
VerifyCode vc = new VerifyCode();
BufferedImage image = vc.getImage();
HttpSession session = req.getSession();
session.setAttribute("session_vc", vc.getText());;
VerifyCode.output(image, resp.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}