后台技术学习4--会话技术
会话
概述:一次会话中包含多次的响应和请求(浏览器第一次给服务器资源发送请求,会话建立,直到一方断开,会话结束)
功能:在一次的会话范围内多次请求间共享数据,例如:浏览器会自动记录你的搜索历史
方式:客户端会话技术: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>