Session的特点和作用

概念

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

入门

  • HTTPSession对象
    - Object getAttribute(String name)
    - void setAttribute(String name, Object value)
    - void removeAttribute(String name)
发送:
//使用Session获取数据
        //1 获取session
        HttpSession session = request.getSession();
        //2 存储数据
        session.setAttribute("msg", "hello session");

接收:
//1 获取session
        HttpSession session = request.getSession();
        //2 获取数据
        Object msg = session.getAttribute("msg");
        response.getWriter().write(msg + "");

原理

服务器如何确保会话中多次请求的Session是同一个?

  • 依赖于Cookie的

在这里插入图片描述

问题
  • 当客户端关闭后,服务端不关闭,两次获取Session是同一个?默认情况下:不是,当客户端关闭后,会话结束了,获取时没有对应的cookie头。如果需要相同,可以创建cookie,键为JSESSIONID,设置最大存活时间,让其持久化保存
  • 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?不是同一个,创建session的对象分配的地址值是随机的。但是为了确保数据不丢失,必须 ***session的钝化(序列化),将服务器正常关闭前,将其对象序列化到硬盘 **session的活化:服务器启动后,将session文件转化为内存中的session对象(tomcat自动实现)
  • session的失效时间?** 服务器关闭。***session对象调用invalidate() ** 默认失效的时间为30s【conf/web.xml中可修改配置】
特点
  • session用于存储一次会话的多次请求的数据,存在服务器端
  • session可以存储任意类型,任意大小的数据
  • 与cookie的区别:
    - session没有大小限制,cookie有
    - session服务器端, cookie在客户端
    - session数据安全, cookie相对不安全
代码

需求

  • 访问带有验证码的登录页面login.jsp
  • 用户输入用户名,密码以及验证码
  • 与数据库交互

页面1:登录界面

<%@ 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="/checkcode?time=" + new Date().getTime();
            }
        }
    </script>
    <style>
        div{
            color: red;
        }
    </style>
</head>
<body>
<form action="/loginServletV2" method="post">
    <table>
        <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 id="img" src="/checkcode"> </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>

页面2:登录成功界面

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

web端

import com.pu.dao.UserDao;
import com.pu.domain.User;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
@WebServlet("/loginServletV2")
public class LoginServletV2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1:设置编码
        req.setCharacterEncoding("utf-8");
        //2:获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String checkCode = req.getParameter("checkCode");
        //获取验证码
        HttpSession session = req.getSession();
        String checkCodeString = (String)session.getAttribute("checkCodeString");
        //获取完验证码立即删除
        session.removeAttribute("checkCodeString");
        //判断验证码正确性
        if(checkCodeString != null && checkCodeString.equalsIgnoreCase(checkCode)){
            //判断用户名和密码
            User loginUser = new User();
            loginUser.setUsername(username);
            loginUser.setPassword(password);
            UserDao dao = new UserDao();
            User user = dao.login(loginUser);
            //5:判断User
            if(user == null){
                req.setAttribute("login_error", "用户名或密码错误");
                req.getRequestDispatcher("/login.jsp").forward(req, resp);
            }else{
                //存储
                session.setAttribute("user", username);
                //跳转其他页面,重定向
                resp.sendRedirect(req.getContextPath() + "/success.jsp");
            }
        }else{
            //验证码不正确
            //存储提示信息到request
            req.setAttribute("cc_error", "验证码错误");
            //转发到登录界面
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

验证码


import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
@WebServlet("/checkcode")
public class CheckCode extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width = 100;
        int height = 40;
        //创建一对象,在内存中图片(验证码图片对象)
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //美化图片
        //填充背景色
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.pink);//设置画笔颜色
        g.fillRect(0, 0, width, height);
        //画边框
        g.setColor(Color.BLUE);
        g.drawRect(0, 0, width - 2, height - 2);
        //写验证码
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        //生成随机角标
        Random ran = new Random();
        StringBuffer sb = new StringBuffer();

        int index = 0;
        for(int i = 1; i <= 4 ; i++){
            index = ran.nextInt(str.length());
            char ch = str.charAt(index);
            sb.append(ch);
            String strs = ch + "";
            g.drawString(strs, 20 * i , 25 );
        }
        String checkCodeString = sb.toString();
        request.getSession().setAttribute("checkCodeString", checkCodeString);
        //画干扰线
        g.setColor(Color.GREEN);
        for(int i = 0; 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, "jpg", response.getOutputStream());
    }

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

Dao层


import com.pu.domain.User;
import com.pu.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * description:操作数据库中User表的类
 */
public class UserDao {
    //声明JDBCTemplate对象共用
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    /**
     * 登录方法
     * @param loginUser 只有用户名和密码
     * @return user包含用户的数据
     */
    public User login(User loginUser){
        //1:编写sql语句
        try {
            String sql = "select * from user where username = ? and password = ?";

            //2:调用query方法
            User user = template.queryForObject(sql,
                    new BeanPropertyRowMapper<User>(User.class),
                    loginUser.getUsername(), loginUser.getPassword());
            return user;
        } catch (DataAccessException e) {
            e.printStackTrace();//记录日志
            return null;
        }
    }
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值