Session和Cookie
Session和Cookie
1. 会话技术
- 会话:一次会话中包含多个请求和响应;从浏览器给服务器发送请求开始,直到某一方断开连接为止
- 功能:在一次会话中的多次请求之间共享数据
- 方式:
- 客户端会话技术:Cookie
- 服务端会话技术:Session
2. Cookie
-
功能:将数据保存在客户端
-
入门:
-
创建Cookie对象,绑定数据
new Cookie(String name, String value)
Cookie cookie=new Cookie("msg","helloworld"); -
发送Cookie对象
response.addCookie(Cookie cookie)
response.addCookie(cookie); -
获取Cookie,拿到绑定的数据
request.getCookies()
Cookie[] cookies = request.getCookies(); if (cookies!=null){ for (Cookie cookie : cookies) { String cookieName = cookie.getName(); String cookieValue = cookie.getValue(); System.out.println(cookieName+""+cookieValue); } }
-
-
流程分析
- 第一次请求时服务器给响应头set-cookie: key-value
- 第二次请求时请求头带有cookies
-
细节处理
-
一次发送多个cookie:需要多少个就add多少个
-
cookie在浏览器保存多久:
-
默认浏览器关闭后被销毁
-
持久化:
setMaxAge(int seconds)
seconds>0 表示持久化,写到文件中;同时表示cookie的保存时间(秒)
seconds<0 表示默认值
seconds=0 表示删除cookie
-
-
cookie能否存放中文字符:
tomcat8前不支持,特殊字符和中文也需要将中文URL编码
-
cookie获取范围:
-
多个webapp能否共享?
默认不能共享;如果需要则要设置path为根路径cookie.setPath("/")
-
不同tomcat服务器的cookie能共享吗?
cookie.setDomain(String domain)设置一级域名相同,则可以共享
-
-
cookie特点
- 数据存储在客户机
- 浏览器对于单个cookie大小有限制(max 4kb)以及同一域名下cookie个数有限制(20)
- 一般用于不登录身份鉴别
-
-
Cookie案例
-
需求:访问Servlet,第一次访问提示:你好,欢迎使用
以后访问显示上一次访问时间
-
分析:
访问时判断是否有Cookie数据,没有就是第一次,提示你好欢迎使用,写入Cookie数据;有就取出Cookie数据,并更新当前的访问时间
-
3. JSP
-
概念:Java Server Pages:java服务器端页面,用于简化书写
-
JSP的原理:本质就是Servlet
-
JSP脚本:JSP定义Java代码的方式
- <% java code %>:定义的Java代码在service方法中,可以定义
- <%! java code %>:定义成员变量和成员方法
- <%= java code%>:定义Java代码,输出语句中可以使用
-
JSP的九大内置对象:不需要获取和创建,可以直接使用的对象
-
request
-
response
-
out:
和writer有细微区别,writer永远会比out先输出,与缓冲区有关
-
4. Session
-
概念:在一次会话的多次请求间共享数据
-
入门:
-
获取session:HttpSession session = request.getSession()
-
使用session对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
-
-
原理:session依赖于cookie,会有jsessionid来区分
-
细节:
session什么时候被销毁:服务器关闭;session.invalidate();默认失效时间是30分钟
session钝化:连接关闭之前,将session对象序列化到硬盘session.ser
session活化:连接启动前,将硬盘中的数据给序列化
-
特点:
- Session用于存储一次会话的多次请求的数据
- 可以存储任意类型,任意大小的数据,存储在服务器端
-
案例:
-
需求:
访问登录页面,输入username, userpwd, verifycode;如果用户名或密码错误就提示用户名或密码错误,验证码错误提示验证码错误;输入正确就直接跳转到success.jsp显示xxx,欢迎使用
-
代码:
其中的验证码生成代码来自:https://www.cnblogs.com/Alice-Thinker/p/8400318.html
效果图:

<%-- login.jsp --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <script> window.onload=function () { document.getElementById("verifycode").onclick=function () { this.src="/verifyCode?"+new Date().getTime(); } } </script> <title>用户登录</title> </head> <body> <form action="/login" method="post"> <table> <tr> <td>用户名</td> <td><input type="text" name="username" ></td> </tr> <tr> <td>密码</td> <td><input type="password" name="userpwd" ></td> </tr> <tr> <td>验证码</td> <td><input type="text" name="verifyCode" placeholder="请输入验证码"></td> </tr> <tr> <td colspan="2"><img src="/verifyCode" alt="verifyCode" id="verifycode"></td> </tr> <tr> <td colspan="2"><input type="submit" value="登录"></td> </tr> </table> <div style="color: red;"><%=request.getAttribute("error0")==null?"":request.getAttribute("error0")%></div> <div style="color: red;"><%=request.getAttribute("error1")==null?"":request.getAttribute("error0")%></div> </form> </body> </html><%-- success.jsp --%> <%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>欢迎使用</title> </head> <body> <h3><%=request.getSession().getAttribute("user")%> 欢迎使用本系统!</h3> </body> </html>//verifyCode.java import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.util.Random; @javax.servlet.annotation.WebServlet(name = "verifyCode", urlPatterns = "/verifyCode") public class verifyCode extends javax.servlet.http.HttpServlet { private static final int WIDTH = 100;//设置验证码图片宽度 private static final int HEIGHT = 30;//设置验证码图片高度 private static final int LENGTH = 4;//设置验证码长度 public static final int LINECOUNT = 20;//干扰线的数目 //验证码的字符库 private static final String str = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; //通过随机数取字符库中的字符组合成4位验证码 private static Random random = new Random(); protected void doPost(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws javax.servlet.ServletException, java.io.IOException { req.setCharacterEncoding("utf-8"); resp.setContentType("image/jpeg"); //设置不进行缓存 resp.setHeader("pragma", "no-cache"); resp.setHeader("cache-control", "no-cache"); resp.setHeader("expires", "0"); BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_3BYTE_BGR); Graphics g = image.getGraphics(); //设置背景颜色并绘制矩形背景 g.setColor(Color.WHITE); g.fillRect(0, 0, WIDTH, HEIGHT); //验证码的绘制 String code = drawChar(g); System.out.println("验证码:" + code); //随机线的绘制 for (int i = 0; i < LINECOUNT; i++) { drawLine(g); } //在session中存入当前的code码,便于验证 req.getSession().setAttribute("code", code); //绘制图片 g.dispose(); //将图片输出到response中 ImageIO.write(image, "JPEG", resp.getOutputStream()); } public Color getColor() { return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)); } //获取字体样式 public Font getFont() { return new Font("Fixedsys", Font.CENTER_BASELINE, 20); } //绘制字符 public String drawChar(Graphics g) { String code = ""; g.setFont(getFont()); for (int i = 0; i < LENGTH; i++) { char c = str.charAt(random.nextInt(str.length())); g.setColor(getColor()); g.drawString(c + "", 20 * i + 10, 20); code = code + c; } return code; } //绘制随机线 public void drawLine(Graphics g) { int x = random.nextInt(WIDTH); int y = random.nextInt(HEIGHT); int xl = random.nextInt(13); int yl = random.nextInt(15); g.setColor(getColor()); g.drawLine(x, y, x + xl, y + yl); } protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { request.setCharacterEncoding("utf-8"); this.doPost(request, response); } }//login.java import javax.servlet.http.HttpSession; @javax.servlet.annotation.WebServlet(name = "login", urlPatterns = "/login") public class login extends javax.servlet.http.HttpServlet { protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String username = request.getParameter("username"); String userpwd = request.getParameter("userpwd"); String verifyCode = request.getParameter("verifyCode"); HttpSession session=request.getSession(); String realVerifyCode = (String) session.getAttribute("code"); if(realVerifyCode.equalsIgnoreCase(verifyCode)){ if ("username".equals(username)&&"userpwd".equals(userpwd)){ session.setAttribute("user",username); response.sendRedirect(request.getContextPath()+"/success.jsp"); } else { request.setAttribute("error1","用户名或密码输入错误!"); request.getRequestDispatcher("/login.jsp").forward(request,response); } } else { request.setAttribute("error0","验证码输入错误,请重新输入!"); request.getRequestDispatcher("/login.jsp").forward(request,response); } } protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { request.setCharacterEncoding("utf-8"); this.doPost(request, response); } }
-

浙公网安备 33010602011771号