Session

服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession

快速入门

获取HttpSession对象:request.getSession(); 使用HttpSession对象:

  • Object getAttribute(String name)
  • void setAttribute(String name,Object value)
  • void removeAttribute(String name)

原理

Session的实现是依赖于Cookie的,在第一次获取Session时,没有Cookie,会在内容中创建一个新的Session对象,该对象会有一个id,响应头会通过set-cookie:JSESSIONID=xxxxxxxx传给服务器端,下一次请求中,则请求头则会有一个cookie:JSESSIONID=xxxxxxxx,来对比Session对象。

细节

1.当客户端关闭后,服务器不关闭,两次获取session是否为同一个吗

默认情况下不是。
如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让Cookie持久性保存

Cookie c=new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);

2.客户端不关闭后,服务器关闭后,两次获取session是否为同一个吗

不是同一个 ,但是要确保数据不丢失

  • session的钝化:在服务器正常关闭之前,将session对象系列化到硬盘上
  • session的活化:在服务器启动后,将session文件转化内存中的session对象即可

3.session什么时候被销毁

  • 服务器关闭
  • session对象调用invalidate()方法
  • session有一个默认失效时间30分钟

选择性的配置修改

<session-config>
	<session-timeout>30</session-timeout>
</session-config>

特点

  • session用于存储一次会话的多次请求的数据,存在服务器端
  • session可以存储任意类型、任意大小的数据

session与cookie的区别

  • session存储数据在服务器端,Cookie在客户端
  • session没有数据大小限制,Cookie有
  • session数据安全,Cookie相对不安全

案例

带有验证码的登录案例(并未引数据库)

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
    <script>
        window.onload=function (){
            document.getElementById("img").onclick=function (){

                this.src="/test/checkCodeServlet?"+new Date().getTime();
            }
        }
    </script>
    <style>
        div{
            color: red;
        }
    </style>
</head>
<body>
    <form action="/test/loginServlet" method="post">
        <table>
            <tr>
                <td>用户名</td>
                <td><input type="text" name="username" placeholder="请输入用户名"></td>
            </tr>
            <tr>
                <td>密码</td>
                <td><input type="password" name="password" placeholder="请输入密码"></td>
            </tr>
            <tr>
                <td>验证码</td>
                <td><input type="text" name="checkCode"></td>
            </tr>
            <tr>
                <td colspan="2"><img id="img" src="/test/checkCodeServlet" ></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="登录"></td>
            </tr>
        </table>
    </form>
    <div>
        <%=request.getAttribute("cc_error")==null?"":request.getAttribute("cc_error")%>
    </div>
    <div>
        <%=request.getAttribute("login_error")==null?"":request.getAttribute("login_error")%>
    </div>
    
</body>
</html>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
    <h1><%=request.getSession().getAttribute("user")%>,欢迎你</h1>
</body>
</html>

LoginServlet

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置request编码
        request.setCharacterEncoding("utf-8");
        //获取参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String checkCode = request.getParameter("checkCode");
        //获取生成的验证码
        HttpSession session = request.getSession();
        String checkCode_session = (String) session.getAttribute("checkCode_session");
        //删除session中存储的验证码
        session.removeAttribute("checkCode_session");
        //先判断验证码是否正确
        if (checkCode_session!=null&&checkCode.equalsIgnoreCase(checkCode_session)){
            //验证码正确
            if ("zhangsan".equals(username)&&"123".equals(password)){
                //登录成功
                //存储信息用户信息
                    session.setAttribute("user",username);
                //重定向到success.jsp
                response.sendRedirect(request.getContextPath()+"/success.jsp");
            }else{
                //登录失败
                //存储提示信息到request
                request.setAttribute("login_error","用户名或密码错误");
                //转发到登录页面
                request.getRequestDispatcher("/login.jsp").forward(request,response);
            }
        }else {
            //验证码不一致
            //存储提示信息到request
            request.setAttribute("cc_error","验证码错误");
            //转发到登录页面
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

CheckCodeServlet

@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width=100;
        int height=50;
        //1.创建一个对象,在内存中画图(验证码图片对象)
        BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);

        //2.美化图片
        //填充背景色
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.PINK);//设置画笔颜色
        g.fillRect(0,0,width,height);
        //画边框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,width-1,height-1);
        //写验证码
        String str="ABCDEFGHIJKLMNOPQRSTOVWSYZabcdefghijklmnopqrstuvwsyz0123456789";
        Random random=new Random();
        StringBuilder sb=new StringBuilder();
        for (int i=1;i<=4;i++){
            int index=random.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
        HttpSession session = request.getSession();
        session.setAttribute("checkCode_session",checkCode_session);

        //画干扰线
        g.setColor(Color.GREEN);
        for (int i=0;i<10;i++){
            int x1 = random.nextInt(width);
            int x2 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int y2 = random.nextInt(height);
            g.drawLine(x1,x2,y1,y2);
        }

        //3.将图片输出到页面展示
        ImageIO.write(image,"jpg",response.getOutputStream());

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}