会话技术

  • 会话:一次会话中包含多次请求和响应。

  • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止

  • 功能:在一次会话的范围内的多次请求间,共享数据

  • 方式:
    1.客户端会话技术:Cookie
    2.服务器端会话技术: session

  • Cookie:

    1. 概念∶客户端会话技术,将数据保存到客户端

    2. 使用步骤︰
      1.创建cookie对象,绑定数据
      new Cookie(string name, string value)
      2.发送cookie对象
      response.addcookie(cookie cookie)
      3.获取cookie,拿到数据
      cookier[] request.getcookies()

    3. 实现原理
      基于响应头set-cookie和请求头cookie实现

    4. cookie的细节:

      1. 一次可不可以发送多个cookie?
        可以创建多个cookie对象,使用response调用多次addcookie方法发送cookie即可。

      2. cookie在浏览器中保存多长时间?
        1.默认情况下,当浏览器关闭后,cookie数据被销毁
        2.持久化存储:

        setMaxAge(int seconds)
        1.正数∶将cookie数据写到硬盘的文件中。持久化存储。cookie存活时间。
        2.负数︰默认值
        3.零:删除cookie信息

      3. cookie能不能存中文?
        在tomcat 8 之前cookie中不能直接存储中文数据。【需要将中文数据转码---—般采用URL编码(%E3)】
        在tomcat 8 之后,cookie支持中文数据。

      4. cookie共享问题?
        1.假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
        *默认情况下cookie不能共享
        setPath(string path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
        *如果要共享,则可以将path设置为"/”
        2.不同的tomcat服务器间cookie共享问题?
        setDomain(string path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
        setDomain(".baidu.com") ,那么tieba.baidu.com和news.baidu.com中cookie可以共享

  1. cookie的特点和作用
    1.cookie存储数据在客户端浏览器
    2.浏览器对于单个cookie的大小有限制(4kb)以及对同一个域名下的总cookie数量也有限制(20个)
    *作用∶
    1.cookie—般用于存出少量的不太敏感的数据
    2.在不登录的情况下,完成服务器对客户端的身份识别
  2. 例子
     response.setContentType("text/html;charset=utf-8");
        //获取cookie
        Cookie[] cookies = request.getCookies();//获取cookies
        Boolean flag=false; //是否第一次访问

        /**不是第一次访问**/
        if(cookies!=null&&cookies.length>0){ //如果cookie存在
            for (Cookie cookie:cookies) {  //循环cookie
                if("lastTime".equals(cookie.getName())){ //如果cookie的名字是lastTime说明cookie存在
                    flag=true; //不是第一次访问
                    Date date = new Date(); //创建系统时间
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//格式化时间对象
                    String str_date = dateFormat.format(date); //格式化时间
                    //编码
                    str_date=URLEncoder.encode(str_date,"utf-8");  //特殊字符空格会报错,用URL编码
                    cookie.setValue(str_date); //设置lastTime的值是系统时间
                    cookie.setMaxAge(30*24*60*60);//保存一个月
                    response.addCookie(cookie); //保存cookie
                    String value = cookie.getValue();//获取cookie的值
                    //解码
                    value=URLDecoder.decode(value,"utf-8");  //输出的时候要解码
                    response.getWriter().write("<h1>欢迎回来你上次访问的时间是"+value+"</h1>");
                    break;
                }


            }
        }
        /**第一次访问**/
        if(cookies==null||cookies.length==0||flag==false){
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String str_date = dateFormat.format(date);
            //编码
            str_date=URLEncoder.encode(str_date,"utf-8");
            Cookie cookie=new Cookie("lastTime",str_date);
            cookie.setMaxAge(30*24*60*60);
            response.addCookie(cookie);
            response.getWriter().write("<h1>欢迎你首次访问</h1>");
        }
  • Session :
    1. 概念∶服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。Httpsession
      1.获取Httpsession对象:
      Httpsession session = request.getsession();
      2.使用Httpsession对象︰
      object getAttribute(string name)
      void setAttribute(string name,object value)
      void removeAttribute(string name)

    2. 原理:

    3. 细节:

      1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
        默认情况下。不是。
        如果需要相同,则可以创建cookie,键为"SESSIONID,设置最大存活时间,让cookie持久化保存。
        cookie c = new Cookie("JSESSIONID",session.getId());
        c.setMaxAge(60*60);
        response.addcookie(c);
      2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
        不是同一个,但是要确保数据不丢失
        session的钝化:在服务器正常关闭之前,将session对象系列化到硬盘上
        session的活化:在服务器启动后,将session文件转化为内存中的session对象即可。
      3. session什么时候被销毁?|
        1.服务器关闭
        2.session对象调用invalidate() 。
        3.session默认失效时间30分钟
        选择性配置修改:web.xml
        <session-config>
        <session-timeout>30</session-timeout>
        </session-config>
    4. session的特点

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

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

案例,验证码
jdbc工具类:

public class Druid {
    private static DataSource ds;

    static {

        try {
            Properties pro=new Properties();
            //查找数据库连接的配置文件
            InputStream  is= Druid.class.getClassLoader().getResourceAsStream("jdbc.properties");
            pro.load(is);
            ds= DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取数据库连接池
    public static DataSource getDataSource(){
        return ds;
    }
    //获取数据库连接对象
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}

dao提供的login方法

public class UserDao {
    private JdbcTemplate template=new JdbcTemplate(Druid.getDataSource());

    public User login(User user) {
        try {
            String sql="select * from user where username=? and password=?";
            User BeanUser = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), user.getUsername(), user.getPassword());
            return BeanUser;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
}

sessionLogin.jsp

<form action="/newServlet/SessionLoginServlet">
    <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="checkCodeImg" src="/newServlet/CheckCodeServlet" alt=""></td></tr>
        <tr><td colspan="2"><input type="submit" value="提交"></td></tr>
    </table>
</form>
<div><%= request.getAttribute("error_login")==null?"":request.getAttribute("error_login") %></div>
<div><%= request.getAttribute("error_code")==null?"":request.getAttribute("error_code") %></div>
<script>
    document.getElementById("checkCodeImg").onclick=function(){
        this.src="/newServlet/CheckCodeServlet?"+new Date().getTime();
    }
</script>

验证码图片

package com.xjbt.session;

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("/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.美化图片
        Graphics graphics = image.getGraphics();//画笔对象
        //填充粉红色
        graphics.setColor(Color.pink);//设置画笔颜色
        graphics.fillRect(0,0,width,height);//填充

        //蓝色边框
        graphics.setColor(Color.blue);
        graphics.drawRect(0,0,width-1,height-1);

        //写数字
        String str="ABCDEFGHIJKLMNOPQISCUVWSYZabcdefghijklmnopqiscuvwsyz0123456789";
        //生成随机角标
        Random rand = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <=4 ; i++) {
            int index = rand.nextInt(str.length());
            //获取随机字符
            char c = str.charAt(index);//随机字符
            sb.append(c);
            graphics.drawString(c+"",width/5*i,height/2);
        }
        String checkCode_session = sb.toString();
        request.getSession().setAttribute("checkCode_session",checkCode_session);//将验证码存入session
        //4画干扰线
        graphics.setColor(Color.green);
        for (int i = 1; i <=10; i++) {
            int x1=rand.nextInt(width);
            int y1=rand.nextInt(height);
            int x2=rand.nextInt(width);
            int y2=rand.nextInt(height);
            graphics.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);
    }
}

success.jsp

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

sessionLoginServlet.java

@WebServlet("/SessionLoginServlet")
public class SessionLoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码
        request.setCharacterEncoding("utf-8");
        /*
        //获取输入框的内容
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String checkCode = request.getParameter("checkCode");
        */

        /**
         * 获取用户信息(包含了用户id,username,password)
         */

        Map<String, String[]> map = request.getParameterMap();
        User loginUser=new User();//登录对象(包含了所有的用户信息)
        try {
            //使用beanutils
            BeanUtils.populate(loginUser,map);//将传入的参数(输入框的内容),作为loginUser对象的成员变量的值
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        /**
         *判断验证码是否添加正确
         */

        //获取传入参数的验证码
        String checkCode = request.getParameter("checkCode");
        //获取session
        HttpSession session = request.getSession();
        //创建dao
        UserDao userDao = new UserDao();
        //获取存入session的checkCode_session【验证码】的值
        String checkCode_session = (String) session.getAttribute("checkCode_session");
        //删除验证码
        session.removeAttribute("checkCode_session");//解决登陆成功后点击返回验证码还是原来的
        if(checkCode_session!=null&&checkCode_session.equalsIgnoreCase(checkCode)){//忽略大小写(如果传入的验证码等于存入session的验证码)
            //验证用户名密码
            User user = userDao.login(loginUser);
            if(user!=null){
                //存用户信息
                session.setAttribute("user",user.getUsername());
                //重定向到登录成功页面
                response.sendRedirect(request.getContextPath()+"/success.jsp");
            }else{
                //登录失败
                //存入提示信息
                request.setAttribute("error_login","用户名或密码错误");
                request.getRequestDispatcher("/sessionLogin.jsp").forward(request,response);
            }

        }else{
            //存入提示信息
            request.setAttribute("error_code","验证码输入错误");
            request.getRequestDispatcher("/sessionLogin.jsp").forward(request,response);
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容

  • 会话技术 会话:一次会话中包含多次请求和响应 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开...
    魔笛使者阅读 171评论 0 0
  • 会话技术 会话 浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止,一次会话中包含多次请求和响应。 功...
    某翁阅读 317评论 0 1
  • 会话技术 1.会话:一次会话中包含多个请求和响应一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方被...
    程序猿峰岑阅读 314评论 0 0
  • 会话技术 1. Cookie 概念:客户端会话技术,将数据保存到客户端 具体操作:创建Cookie对象,绑定数据n...
    青丶空阅读 306评论 0 0
  • 会话技术 概念会话是一次会话中包含多次请求和响应。一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方...
    画画的baby_7f69阅读 126评论 0 0