Session 2021-02-07

## Session

    1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
    2. 快速入门:
        1. 获取HttpSession对象:
            HttpSession session = request.getSession();
        2. 使用HttpSession对象:
            Object getAttribute(String name)  
            void setAttribute(String name, Object value)
            void removeAttribute(String name)  
    
    3. 原理
        * Session的实现是依赖于Cookie的。

    
    4. 细节:
        1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
            * 默认情况下。不是。
            * 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
                 Cookie c = new Cookie("JSESSIONID",session.getId());
                 c.setMaxAge(60*60);
                 response.addCookie(c);

        2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
            * 不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作
                * session的钝化:
                    * 在服务器正常关闭之前,将session对象系列化到硬盘上
                * session的活化:
                    * 在服务器启动后,将session文件转化为内存中的session对象即可。
                
        3. session什么时候被销毁?
            1. 服务器关闭
            2. session对象调用invalidate() 。
            3. session默认失效时间 30分钟
                选择性配置修改    
                <session-config>
                    <session-timeout>30</session-timeout>
                </session-config>

     5. session的特点
         1. session用于存储一次会话的多次请求的数据,存在服务器端
         2. session可以存储任意类型,任意大小的数据

        * session与Cookie的区别:
            1. session存储数据在服务器端,Cookie在客户端
            2. session没有数据大小限制,Cookie有
            3. session数据安全,Cookie相对于不安全


## 案例:验证码
    1. 案例需求:
        1. 访问带有验证码的登录页面login.jsp
        2. 用户输入用户名,密码以及验证码。
            * 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
            * 如果验证码输入有误,跳转登录页面,提示:验证码错误
            * 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您

代码:

domain.User.java

package domain;

public class User {
    private String username;
    private  String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

util.JDBCUtils.java

package util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类 使用Durid连接池
 */
public class JDBCUtils {

    private static DataSource ds ;

    static {

        try {
            //1.加载配置文件
            Properties pro = new Properties();
            //使用ClassLoader加载配置文件,获取字节输入流
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);

            //2.初始化连接池对象
            ds = DruidDataSourceFactory.createDataSource(pro);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接池对象
     */
    public static DataSource getDataSource(){
        return ds;
    }


    /**
     * 获取连接Connection对象
     */
    public static Connection getConnection() throws SQLException {
        return  ds.getConnection();
    }
}

dao.UserDao.java

package dao;

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

public class UserDao {
 private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
 //  loginUser.getUsername(), loginUser.getPassword());对应问号
    //根据用户输入的值查询数据库中是否有这个数据,返回User
 public User login(User loginUser){

     try {
         //编写sql
         String sql="select *from user where username=? and password=?";
         //封装成user
         User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),
                 loginUser.getUsername(), loginUser.getPassword());
         return user;
     } catch (DataAccessException e) {
         e.printStackTrace();
     }
     return null;
 }
}

servlet.CheckCodeServlet.java

package servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@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_RGB);


        //2.美化图片
        //2.1 填充背景色
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.PINK);//设置画笔颜色
        g.fillRect(0,0,width,height);

        //2.2画边框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,width - 1,height - 1);

        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
        //生成随机角标
        Random ran = new Random();
        //定义一个StringBuilder
         StringBuilder sb=new StringBuilder();
        for (int i = 1; i <= 4; i++) {
            int index = ran.nextInt(str.length());
            //获取字符
            char ch = str.charAt(index);//随机字符
            //把字符存到StringBuider中
            sb.append(ch);
            //2.3写验证码
            g.drawString(ch+"",width/5*i,height/2);
        }
        //把StringBuider替换为String
        String checkcode = sb.toString();
        HttpSession session = request.getSession();
        //把验证码存到session中
        session.setAttribute("checkcode",checkcode);
        //2.4画干扰线
        g.setColor(Color.GREEN);

        //随机生成坐标点

        for (int i = 0; i < 10; i++) {
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);

            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1,y1,x2,y2);
        }


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


    }

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

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script>
        window.onload = function () {
            var img = document.getElementById("img");
            img.onclick = function () {
                //加时间戳
                var date = new Date().getTime();
                img.src = "/login/checkCodeServlet?" + date;
            }
        }
    </script>
    <style>
        .c{color: deeppink;

        }
    </style>
</head>
<body>
<form action="/login/loginServlet" method="post">
    <table>
    <tr><td>用户名:<input type="text" name="username"></td></tr>
    <tr><td>密码:<input type="password" name="password"></td></tr>
        <tr><td>验证码:<input type="text" name="checkcode"></td></tr>
    <tr><td rowspan="2"><img id="img" src="/login/checkCodeServlet"></td></tr>
    <tr><td><input type="submit" value="登录"></td></tr>
    </table>
</form>
<%--在域中仅仅封装的数据不用强制转换--%>
<%!
    String blanknull(String s)
    {
        return (s == null) ? "" : s;
    }
%>
<%String usererorr = (String)request.getAttribute("usererror");%>
<p class="c"><%=blanknull(usererorr)%></p>
<% String codeerror = (String)request.getAttribute("codeerror");%>
<p class="c"><%=blanknull(codeerror)%></p>
</body>
</html>

servlet.LoginServlet.java

package servlet;

import dao.UserDao;
import 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("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置接受的的数据编码
        request.setCharacterEncoding("utf-8");
        //把数据封装为map对象
        Map<String, String[]> map = request.getParameterMap();
        //设置一个空的User对象
        User loginUser = new User();
        try {
            //封装map数据到loginUser中
            BeanUtils.populate(loginUser, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //因为验证码是单独生成的,所以单独获取用户输入的验证码,
        String checkcode = request.getParameter("checkcode");
        HttpSession session = request.getSession();
        //获取CheckCode生成的验证码并把验证码强行转换为String格式
        String checkcode1 = (String) session.getAttribute("checkcode");
        //防止登录成功后退验证码依然能有效
        session.removeAttribute("checkcode");
        //验证码正确
        //IgnoreCase(String)是比较字符不区分大小写的方法
        if (checkcode != null && checkcode.equalsIgnoreCase(checkcode1)) {
            //如果一样的话
            UserDao dao = new UserDao();
            //调用login方法,参数为封装的loginUser对象
            User user = dao.login(loginUser);
            //用户输入的值正确
            //如果用户不为空证明查找到用户的值
            if (user != null) {
                //把返回的user存入session中
                session.setAttribute("user", user);
                //重定向到success界面
                response.sendRedirect(request.getContextPath()+"/success.jsp");
            } else {
                //账号或密码不正确
                request.setAttribute("usererror", "账号或密码输入错误");
                request.getRequestDispatcher("/login.jsp").forward(request, response);
            }
        } else {
            //验证码输入不正确
            request.setAttribute("codeerror", "验证码输入错误");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }

    }

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

success.jsp

<%@ page import="domain.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    HttpSession session1 = request.getSession();
//一定得强制转换,因为知道user是User类型
    User user = (User) session1.getAttribute("user");
%>
<h1><%=user.getUsername()%>欢迎登陆成功</h1>
</body>
</html>

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值