会话
概述:一次会话中包含多次的响应和请求(浏览器第一次给服务器资源发送请求,会话建立,直到一方断开,会话结束)
功能:在一次的会话范围内多次请求间共享数据,例如:浏览器会自动记录你的搜索历史
方式:客户端会话技术:Cookie,服务器端会话技术:Session
Cookie
步骤:①创建Cookie对象
②发送Cookie对象
③获取Cookie,共享数据
Cookie cookie = new Cookie("name","value");
response.addCookie(cookie);
Cookie[] c = request.getCookies();
//遍历
for(Cookie cookie1 : c){
String name = cookie1.getName();
String value = cookie1.getValue();
System.out.println(name + ":" + value);
}
实现原理:基于响应头 set-cookie和请求头cookie实现
cookie细节:1、可创建多个cookie对象,使用response对象发送
2、默认情况下,浏览器关闭之后,cookie信息销毁;使用setMaxAge(int seconds)可以设置cookie信息存活时间,参数为正,是cookie信息存活时间;参数为负,是默认情况;参数为0,直接删除cookie信息。
Cookie信息共享问题
1、默认情况下,cookie信息不能共享。使用setPath(String path),如果需要共享数据,将path设置为"/"
2、不同tomcat服务器之间的cookie共享:设置一级域名相同,多个服务器之间cookie数据可共享 setDomain(".baidu.com")百度贴吧和百度新闻数据可以共享
Cookie特点:①cookie存储数据在客户端浏览器;②存储大小为4kb,存储数量为20个
Cookie作用:①存储不重要的信息;②在不登录的情况下识别用户
这是一个记录访问时间的Cookie案例
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
//能够记录访问时间
@WebServlet(name = "Cookietest", value = "/Cookietest")
public class Cookietest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获取cookie数据
Cookie[] cookies = request.getCookies();
boolean flag = false;
//遍历数据
if(cookies != null && cookies.length > 0){
for (Cookie cookie : cookies) {
//获取cookie名称
String name = cookie.getName();
//判断是否有lastTime
if("lastTime".equals(name)){
//不是第一次访问
flag = true;
Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
String date1 = sd.format(date);
cookie.setValue(date1);
//设置cookie存活3分钟
cookie.setMaxAge(60*3);
response.addCookie(cookie);
//响应数据
String value = cookie.getValue();
response.getWriter().write("欢迎回来,你上次的访问时间为"+value);
break;
}
}
}
if(cookies == null || cookies.length == 0 || flag == false){
Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
String date1 = sd.format(date);
Cookie cookie = new Cookie("lastTime",date1);
cookie.setValue(date1);
cookie.setMaxAge(60*3);
response.addCookie(cookie);
response.getWriter().write("欢迎你,第一次来"+ cookie.getValue());
}
}
}
Session
服务器端会话技术
HttpSession session = request.getSession();//获取Session
session.setAttribute("name","value");//存储数据
Object session1 = request.getAttribute("name");//获取数据
原理:session的实现依赖于cookie
细节:①客户端关闭,服务端不关闭,两次的session不同,实现相同,使用cookie的getId()方法进行持久化
HttpSession session = request.getSession();
System.out.ptintln(session);
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(int seconds);
response.addCookie(cookie);
②session钝化:服务器正常关闭之前,将session对象系统化到硬盘;session活化:服务器启动后,将session文件转化为内存的session对象
③session销毁
服务器关闭;session对象调用invalidate()
Session特点
1、存储一次会话,多次请求数据,存于服务器端
2、Session可存储任意类型、任意大小的数据
Session与Cookie区别
1、session放在服务器端,cookie放在客户端
2、session数据相对安全
3、session数据存储无限制,cookie则有
Session案例,登录,能够检索验证码
验证码
package Session;
import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet(name = "CheckCode1", value = "/CheckCode1")
public class CheckCode1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建一个对象
int width = 100;
int height = 50;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//填充背景颜色
Graphics g = image.getGraphics();//画笔
g.setColor(Color.cyan);//设置画笔颜色
g.fillRect(0,0,width,height);
//画边框
g.setColor(Color.black);
g.drawRect(0,0,width-1,height-1);
//随机码
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random ran = new Random();
StringBuilder sb = new StringBuilder();
for(int i=1;i<=4;i++){
int index = ran.nextInt(str.length());
char ch = str.charAt(index);
sb.append(ch);
g.drawString(ch+"",width/5*i,height/2);
}
String checkCode_session = sb.toString();
//将验证码存入session
request.getSession().setAttribute("checkCode_session",checkCode_session);
//写验证码
// g.drawString("a",20,25);
// g.drawString("b",40,25);
// g.drawString("c",60,25);
// g.drawString("d",80,25);
//随机划线
g.setColor(Color.BLUE);
for(int i=1;i<10;i++){
int x1 = ran.nextInt(width);
int y1 = ran.nextInt(height);
int x2 = ran.nextInt(width);
int y2 = ran.nextInt(height);
g.drawLine(x1,y1,x2,y2);
}
//图片输出
ImageIO.write(image,"png",response.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
登录后台
package Servlet;
import Bean.User;
import dao.UserDao;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Logon", value = "/Logon")
public class Logon extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkcode = request.getParameter("checkcode");
User user = new User();
user.setUsername(username);
user.setPassword(password);
UserDao userDao = new UserDao();
User user1 = userDao.login(user);
//获取生成的验证码
HttpSession session = request.getSession();
String checkCode_session = (String) session.getAttribute("checkCode_session");
//删除session中的验证码,保证验证码一次有效
session.removeAttribute("checkCode_session");
//判断验证码,忽略大小写
if(checkCode_session != null && checkCode_session.equalsIgnoreCase(checkcode)){
if(user1 != null){
// response.getWriter().append("登陆成功,欢迎你");
session.setAttribute("username",username);
response.sendRedirect(request.getContextPath()+"/success.jsp");
}else{
// response.getWriter().append("登陆失败,用户名或密码错误");
request.setAttribute("login_error","用户名或密码错误");
request.getRequestDispatcher("/Login.jsp").forward(request,response);
}
}else{
request.setAttribute("code_error","验证码错误");
request.getRequestDispatcher("/Login.jsp").forward(request,response);
}
}
}
这里使用数据库中的数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
<script>
onload = function () {
document.getElementById("img").onclick = function () {
this.src = "/CheckCode1?time"+new Date().getTime();
}
}
</script>
</head>
<body>
<table>
<form action="/Logon" method="post">
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>验证码</td>
<td><input type="text" name="checkcode"></td>
</tr>
<tr>
<td colspan="2"><img src="/CheckCode1" id="img"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录"></td>
</tr>
</form>
</table>
<div><%=request.getAttribute("login_error") == null ? "" : request.getAttribute("login_error")%></div>
<div><%=request.getAttribute("code_error") == null ? "" : request.getAttribute("code_error")%></div>
</body>
</html>