zoukankan      html  css  js  c++  java
  • Cookie和Session

    存储客户端的状态:

         由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪   里?因为Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并不知道该客户端是谁,所以需要会话技术识别客户端的状态。会话技术是帮助服务器记住客户端状态(区分客户端)。

    会话技术:

        从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,成为一次会话。会   话技术就是记录这次会话中客户端态的状与数据的。

        会话技术分为Cookie和Session:

        Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端   可以清除cookie

        Session:将数据存储到服务器端,安全性相对好,增加服务器的压力

    Cookie技术:

        Cookie技术是将用户的数据存储到客户端的技术,我们分为两方面学习:

        1:服务器端怎样将一个Cookie发送到客户端

            Cookie cookie = new Cookie(String cookieName,String cookieValue);

            Cookie中不能存储中文

            设置Cookie在客户端的持久化时间:

              cookie.setMaxAge(int seconds); ---时间秒

              注意:如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭 cookie信息销毁(会话级别的cookie),如果设置持久化时间,cookie信息会   被持久化到浏览器的磁盘文件里。       

             设置Cookie的携带路径:

              cookie.setPath(String path);

            注意:如果不设置携带路径,那么该cookie信息会在访问产生该cookie的   web资源所在的路径都携带cookie信息

            

    public class SendCookiesServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //创建cookie对象
            Cookie cookie=new Cookie("goods","iphone12");
            //持久化cookie信息
            cookie.setMaxAge(2*60);
            //设置cooie携带路径
            //cookie.setPath("/WEB05/SendCookiesServlet");
            //cookie.setPath("/WEB05");
            //cookie.setPath("/");
            //向客户端发送cookie
            response.addCookie(cookie);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

            向客户端发送cookie:

              response.addCookie(Cookie cookie);

              

    package com.oracle.demo01;

    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    public class GetCookieServlet extends HttpServlet {

        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //从请求中获取所有cookie所在的数组
            Cookie cookies[]=request.getCookies();
            for(Cookie c:cookies){
                //获取key位goods的cookie对象并获取相应的值
                if(c.getName().equals("goods")){
                    System.out.println(c.getValue());
                }
            }
        }

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

            删除客户端的cookie:

            如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时   间为0的cookie进行覆盖即可

            

    public class DeleteServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //创建Cookie对象
            Cookie cookie=new Cookie("goods","iphone");
            cookie.setPath("/WEB05");
            cookie.setMaxAge(0);
            //发送cookie
            response.addCookie(cookie);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

         2:服务器端怎样接受客户端携带的Cookie

            cookie信息是以请求头的方式发送到服务器端的。

            1)通过request获得所有的Cookie:

            Cookie[] cookies = request.getCookies();

            2)遍历Cookie数组,通过Cookie的名称获得我们想要的Cookie

            for(Cookie cookie : cookies){

            if(cookie.getName().equal(cookieName)){

            String cookieValue = cookie.getValue();

            }

            }

    public class GetCookieServlet extends HttpServlet {

        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //从请求中获取所有cookie所在的数组
            Cookie cookies[]=request.getCookies();
            for(Cookie c:cookies){
                //获取key位goods的cookie对象并获取相应的值
                if(c.getName().equals("goods")){
                    System.out.println(c.getValue());
                }
            }
        }

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

    设置访问时间:

          

    public class LastAccessServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //设置当前系统时间
            Date date=new Date();
            //创建日期时间转换类
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //将日期对象转为字符串
            String newdate=sdf.format(date);
            //创建cookie对象,
            Cookie cookie=new Cookie("lastTime",newdate);
            cookie.setMaxAge(5*60);
            //发送Cookie
            response.addCookie(cookie);
            //获取客户端携带的cookie数组
            String lastTime=null;
            Cookie[] cookies=request.getCookies();
            if(cookies!=null){
                for(Cookie c:cookies){
                    //获取上次访问时间
                    if(c.getName().equals("lastTime")){
                        lastTime=c.getValue();
                    }
                }
            }
            //解决响应乱码
            response.setContentType("text/html;charset=utf-8");
            if(lastTime==null){
                response.getWriter().write("你是第一次访问");
            }else{
                response.getWriter().write("你上次访问时间为:"+lastTime);
            }
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

     Session:

        Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间   存储客户的数据,但客户端需要每次都携带一个标识ID去服务器中寻找属于自己的内 存空间。所以说Session的实现是基于Cookie,Session需要借助于Cookie存储客 户的唯一性标识JSESSIONID.

        

    获得Session对象:

        HttpSession session = request.getSession();

        此方法会获得专属于当前会话的Session对象,如果服务器端没有该会话的Session    对象会创建一个新的Session返回,如果已经有了属于该会话的Session直接将已有    的Session返回(实质就是根据JSESSIONID判断该客户端是否在服务器上已经存在     session了)

    向Session中存数据:

        Session也是存储数据的区域对象,所以session对象也具有如下三个方法:

        session.setAttribute(String name,Object obj);

        session.getAttribute(String name);

        session.removeAttribute(String name);

    Session对象的生命周期:

        创建:第一次执行request.getSession()时创建

        销毁:1:服务器(非正常)关闭时      2:session过期/失效(默认30分钟)

         问题:时间的起算点 从何时开始计算30分钟?从不操作服务器端的资源开始计时

         可以在工程的web.xml中进行配置

          <session-config>

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

          </session-config>

        3)手动销毁session

          session.invalidate();

        作用范围:

          默认在一次会话中,也就是说在,一次会话中任何资源公用一个session对象。

          

    package com.oracle.demo01;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    public class Servlet01 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取Session对象
            //如果是第一次获取,那么就创建Session对象
            HttpSession session=request.getSession();
            //向域中存数据
            session.setAttribute("goods","酸奶");
            //获取JSESSIONID
            String id=session.getId();
            //创建Cookie对象
            Cookie cookie=new Cookie("JSESSIONID",id);
            cookie.setPath("/WEB06");
            cookie.setMaxAge(3*60);
            //发送Cookie
            response.addCookie(cookie);
            response.getWriter().write("JSESSIONID:"+id);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }
    package com.oracle.demo01;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    public class Servlet02 extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //从域中取值
            HttpSession session=request.getSession();
            String name=(String)session.getAttribute("goods");
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write(name);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

     利用Session进行验证码验证以及登录功能:

    package com.oracle.web.user;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 验证码生成程序
     * 
     * 
     * 
     */
    public class CheckImgServlet extends HttpServlet {
    
        // 集合中保存所有成语
        private List<String> words = new ArrayList<String>();
    
        @Override
        public void init() throws ServletException {
            // 初始化阶段,读取new_words.txt
            // web工程中读取 文件,必须使用绝对磁盘路径
            String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
            try {
                BufferedReader reader = new BufferedReader(new FileReader(path));
                String line;
                while ((line = reader.readLine()) != null) {
                    words.add(line);
                }
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 禁止缓存
            // response.setHeader("Cache-Control", "no-cache");
            // response.setHeader("Pragma", "no-cache");
            // response.setDateHeader("Expires", -1);
    
            int width = 120;
            int height = 30;
    
            // 步骤一 绘制一张内存中图片
            BufferedImage bufferedImage = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
    
            // 步骤二 图片绘制背景颜色 ---通过绘图对象
            Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
            // 绘制任何图形之前 都必须指定一个颜色
            graphics.setColor(getRandColor(200, 250));
            graphics.fillRect(0, 0, width, height);
    
            // 步骤三 绘制边框
            graphics.setColor(Color.WHITE);
            graphics.drawRect(0, 0, width - 1, height - 1);
    
            // 步骤四 四个随机数字
            Graphics2D graphics2d = (Graphics2D) graphics;
            // 设置输出字体
            graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
    
            Random random = new Random();// 生成随机数
            int index = random.nextInt(words.size());
            String word = words.get(index);// 获得成语
    
            // 定义x坐标
            int x = 10;
            for (int i = 0; i < word.length(); i++) {
                // 随机颜色
                graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
                        .nextInt(110), 20 + random.nextInt(110)));
                // 旋转 -30 --- 30度
                int jiaodu = random.nextInt(60) - 30;
                // 换算弧度
                double theta = jiaodu * Math.PI / 180;
    
                // 获得字母数字
                char c = word.charAt(i);
    
                // 将c 输出到图片
                graphics2d.rotate(theta, x, 20);
                graphics2d.drawString(String.valueOf(c), x, 20);
                graphics2d.rotate(-theta, x, 20);
                x += 30;
            }
    
            // 将验证码内容保存session
            request.getSession().setAttribute("checkcode_session", word);
    
            // 步骤五 绘制干扰线
            graphics.setColor(getRandColor(160, 200));
            int x1;
            int x2;
            int y1;
            int y2;
            for (int i = 0; i < 30; i++) {
                x1 = random.nextInt(width);
                x2 = random.nextInt(12);
                y1 = random.nextInt(height);
                y2 = random.nextInt(12);
                graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
            }
    
            // 将上面图片输出到浏览器 ImageIO
            graphics.dispose();// 释放资源
            
            //将图片写到response.getOutputStream()中
            ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
        /**
         * 取其某一范围的color
         * 
         * @param fc
         *            int 范围参数1
         * @param bc
         *            int 范围参数2
         * @return Color
         */
        private Color getRandColor(int fc, int bc) {
            // 取其随机颜色
            Random random = new Random();
            if (fc > 255) {
                fc = 255;
            }
            if (bc > 255) {
                bc = 255;
            }
            int r = fc + random.nextInt(bc - fc);
            int g = fc + random.nextInt(bc - fc);
            int b = fc + random.nextInt(bc - fc);
            return new Color(r, g, b);
        }
    
    }
    package com.oracle.web.user;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import com.oracle.domain.Users;
    import com.oracle.service.UserService;
    
    public class LoginServlet extends HttpServlet {
    private UserService userService=new UserService();
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //解决请求乱码
            request.setCharacterEncoding("UTF-8");
            //获取用户输入的验证码
            String code=request.getParameter("code");
            //获取Session对象
            HttpSession session=request.getSession();
            //获取生成的正确验证码
            String checkcode=(String)session.getAttribute("checkcode_session");
            //验证
            //如果验证码不正确
            if(!code.equals(checkcode)){
                request.setAttribute("mes","验证码不正确");
                //请求转发
                request.getRequestDispatcher("/login.jsp").forward(request, response);
                return;
            }
            //登录验证
            String username=request.getParameter("username");
            String password=request.getParameter("password");
            Users user=userService.login(username, password);
            if(user!=null){
                //登录成功
                session.setAttribute("user",user);
                //跳转到商城首页
                response.sendRedirect(request.getContextPath()+"/index.jsp");
            }else{
                request.setAttribute("mes","用户名或密码不正确");
                request.getRequestDispatcher("/login.jsp").forward(request, response);
            }
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }
    package com.oracle.dao;
    
    import java.sql.Connection;
    import java.sql.Date;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import com.oracle.domain.Users;
    import com.oracle.tools.JDBCUtils;
    
    public class UserDao {
    //注册
        public int resgister(Users user) throws SQLException{
            Connection conn=JDBCUtils.getConn();
            String sql="insert into users values(?,?,?,?,?,?,?,?,?,?)";
            PreparedStatement pst=conn.prepareStatement(sql);
            pst.setString(1,user.getUid());
            pst.setString(2,user.getUsername());
            pst.setString(3,user.getPassword());
            pst.setString(4,user.getName());
            pst.setString(5,user.getEmail());
            pst.setString(6,user.getTelephone());
            pst.setDate(7,new Date(user.getBirthday().getTime()));
            pst.setString(8,user.getSex());
            pst.setInt(9,user.getState());
            pst.setString(10,user.getCode());
            int row=pst.executeUpdate();
            JDBCUtils.close(conn, pst);
            return row;
        }
        //登录
        public Users login(String username,String password) throws SQLException{
            Connection conn=JDBCUtils.getConn();
            String sql="select * from users where username=? and password=?";
            PreparedStatement pst=conn.prepareStatement(sql);
            pst.setString(1,username);
            pst.setString(2,password);
            ResultSet rs=pst.executeQuery();
            Users user=null;
            while(rs.next()){
                user=new Users();
                user.setUid(rs.getString("uid"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setName(rs.getString("name"));
                user.setEmail(rs.getString("email"));
                user.setTelephone(rs.getString("telephone"));
                user.setBirthday(rs.getDate("birthday"));
                user.setSex(rs.getString("sex"));
                user.setState(rs.getInt("state"));
                user.setCode(rs.getString("code"));
            }
            JDBCUtils.close(conn, pst, rs);
            return user;
        }
    }
    package com.oracle.service;
    
    import java.sql.SQLException;
    
    import com.oracle.dao.UserDao;
    import com.oracle.domain.Users;
    
    public class UserService {
    private UserDao userDao=new UserDao();
    public int resgister(Users user){
        int row=0;
        try {
            row=userDao.resgister(user);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return row;
    }
    //登录
    public Users login(String username,String password){
        Users user=null;
        try {
            user=userDao.login(username, password);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return user;
    }
    }
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>会员登录</title>
    <link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
    <script src="js/jquery-1.11.3.min.js" type="text/javascript"></script>
    <script src="js/bootstrap.min.js" type="text/javascript"></script>
    <!-- 引入自定义css文件 style.css -->
    <link rel="stylesheet" href="css/style.css" type="text/css" />
    
    <style>
    body {
        margin-top: 20px;
        margin: 0 auto;
    }
    
    .carousel-inner .item img {
         100%;
        height: 300px;
    }
    
    .container .row div {
        /* position:relative;
                     float:left; */
        
    }
    
    font {
        color: #666;
        font-size: 22px;
        font-weight: normal;
        padding-right: 17px;
    }
    </style>
    </head>
    <body>
    
        <!-- 引入header.jsp -->
        <jsp:include page="/header.jsp"></jsp:include>
    
    
        <div class="container"
            style=" 100%; height: 460px; background: #FF2C4C url('images/loginbg.jpg') no-repeat;">
            <div class="row">
                <div class="col-md-7">
                    <!--<img src="./image/login.jpg" width="500" height="330" alt="会员登录" title="会员登录">-->
                </div>
    
                <div class="col-md-5">
                    <div
                        style=" 440px; border: 1px solid #E7E7E7; padding: 20px 0 20px 30px; border-radius: 5px; margin-top: 60px; background: #fff;">
                        <font>会员登录</font>USER LOGIN
                        <div style="color:red"><%=request.getAttribute("mes")==null?"":request.getAttribute("mes") %>
                        
                        </div>
                        <form class="form-horizontal" action="/Market02/LoginServlet" method="post">
                            <div class="form-group">
                                <label for="username" class="col-sm-2 control-label">用户名</label>
                                <div class="col-sm-6">
                                    <input type="text" class="form-control" id="username"
                                        placeholder="请输入用户名" name="username">
                                </div>
                            </div>
                            <div class="form-group">
                                <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
                                <div class="col-sm-6">
                                    <input type="password" class="form-control" id="inputPassword3"
                                        placeholder="请输入密码" name="password">
                                </div>
                            </div>
                            <div class="form-group">
                                <label for="inputPassword3" class="col-sm-2 control-label">验证码</label>
                                <div class="col-sm-3">
                                    <input type="text" class="form-control" id="inputPassword3"
                                        placeholder="请输入验证码" name="code">
                                </div>
                                <div class="col-sm-3">
                                    <img src="/Market02/CheckImgServlet" onclick="code(this)">
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="col-sm-offset-2 col-sm-10">
                                    <div class="checkbox">
                                        <label> <input type="checkbox"> 自动登录
                                        </label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <label> <input
                                            type="checkbox"> 记住用户名
                                        </label>
                                    </div>
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="col-sm-offset-2 col-sm-10">
                                    <input type="submit" width="100" value="登录" name="submit"
                                        style="background: url('./images/login.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0); height: 35px;  100px; color: white;">
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    
        <!-- 引入footer.jsp -->
        <jsp:include page="/footer.jsp"></jsp:include>
    <script type="text/javascript">
    function code(obj){
        obj.src="/Market02/CheckImgServlet?time="+new Date().getTime();
    }
    
    </script>
    </body>
    </html>
  • 相关阅读:
    ubuntu下怎么配置/查看串口-minicom工具
    jpg与pgm(P5)的互相转换(Python)
    hyper-v安装ubuntu18的全过程+踩过的坑(win10家庭版)
    zerotier的下载、安装、配置与使用(win10、ubuntu)
    github page+jekyll构建博客的解决方案
    opencv2.4.13.7的resize函数使用(c++)
    c++中的const和volatile知识自我总结
    各种优化算法详解
    P与NP问题
    vs2017配置pthread.h的方法
  • 原文地址:https://www.cnblogs.com/maxuefeng/p/13985815.html
Copyright © 2011-2022 走看看