首页 > 代码库 > Cookie&&Session会话技术之再体验

Cookie&&Session会话技术之再体验

1、转发与重定向【****】
    * 重定向:重新确定请求方向
        * 发送者:服务器 --> 响应(response)浏览器
        * 执行者:浏览器 --> 重新请求
        * 跳转
        * response.sendRedirect("/day04/1.html");
        * //完全等价,隐藏了HTTP协议的具体要求
        * response.setStatus(302);
        * response.setHeader("location", "http://localhost/day04/1.html");
    * 转发:当前请求未完成,服务器调用另一个程序继续完成整个请求
        * 服务器:当前程序需要获得请求调度器 RequestDispatcher
        * forward:当调度器,协调多个servlet时,此方法返回最后一个servlet的页面输出内容。

   * 如果是include:包含所有servlet或者jsp的页面输出内容
    * 对比
        * 何时使用
            * 重定向:可以指定当前web项目的URL,也可以指定其他web资源(路径一般是绝对路径)
            * 转发:只能指定当前的web项目URL
        * 确定使用
            * 重定向:在第一次请求中设置值,在重定向后不能获取。两次请求,tomcat创建了两个request
                * 完成跳转功能,选重定向
            * 转发:设置的值可以在其他servlet或资源中使用。
                * 多个servlet需要传递数据时,现在转发。
        * 总结:
            * 请求次数
                * 重定向:请求2次,tomcat创建了两个request对象
                * 转发:请求1次,tomcat创建了2个request对象
                    * request --> org.apache.catalina.connector.RequestFacade  -- HttpServletRequest --ServletRequest
                    * request --> org.apache.catalina.core.ApplicationHttpRequest
                                    * class ApplicationHttpRequest extends HttpServletRequestWrapper {
                                    * public class HttpServletRequestWrapper implements HttpServletRequest {
                                    * ApplicationHttpRequest -- HttpServletRequestWrapper -- HttpServletRequest
                    * 将第一个request中的内容,拷贝给第二个request。值相同
            * 浏览器地址栏是否修改
                * 重定向:修改,看到跳转后页面的内容
                * 转发:没有修改,看到的转发后最后一个servlet响应的内容
            * request设置的值,是否共享
                * 重定向:数据不共享
                * 转发:数据共享
        
        * 如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头
        * 它是相对于整个WEB站点的根目录;
        * 如果创建RequestDispatcher对象时指定的相对URL以“/”开头,
        * 它是相对于当前WEB应用程序的根目录。         
        * 一般前台页面访问、写绝对路径/项目名/xxxx       
            * String path = request.getContextPath();
            * System.out.println(path+"获得网站根目录名称");例如:/day04/
2、会话:当访问web资源之后,通过连接继续请求当前站点的资源,然后关闭浏览器的整个过程。
    * 会话技术:cookie、session
    * cookie:将服务器的数据保存到浏览器端的技术
        * 要求保存数据:服务器
        * 保存的是文本信息、不能使对象
        * 保存数据:浏览器
            * IE;将cookie保存到指定目录中,以文件的形式存储
            * 火狐或谷歌:将cookie保存到指定的文件中
            *IE中保存Cookie的位置、工具-->Internet选项--->常规--设置---->查看文件
            *火狐保存Cookie的位置、工具--->页面信息--->安全--->查看cookie
        * 使用HTTP协议进行通信
        * 会话级cookie:当整个会话结束后,cookie信息将被删除(cookie在内存中)
        * 持久化cookie:将cookie保存到硬盘中
            * setMaxAge
                * 单位:秒
                * 如果设置的值为零,则进行删除操作。
        * request.getCookies();获得当前web项目的所有的cookie信息
            * 获得当前浏览器中的cookie
            * 获得当前servlet所在目录,以及之上的所有目录下的cookie信息
            * 通过setPath可以设置cookie的访问路径
        * 在cookie中存放中文
            * 编码:String returnData  = URLEncoder.encode(data, "UTF-8");
            * 解码:String value = http://www.mamicode.com/URLDecoder.decode(c.getValue(),"UTF-8");
            
        * cookie的value可以设置多少个字符:4kb
        *遍历所有cookie
        //读取cookie
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //读取
        Cookie[] cookies = request.getCookies();
        if(cookies!=null){
            for(Cookie cookie : cookies){
                //解码
                if("username".equals(cookie.getName())){
                    String value = http://www.mamicode.com/URLDecoder.decode(cookie.getValue(),"UTF-8");
                    System.out.println(value);
                }
            }
        }else{
            System.out.println("has not cookie");
        }
        
        
        
        String str = "曹健强";
        //编码
        String data = http://www.mamicode.com/URLEncoder.encode(str,"UTF-8");
        Cookie cookie = new Cookie("username",data);
        cookie.setMaxAge(60*60*24);
        //这个时候写入中文到cookie会报错、所以必须先编码再添加到cookie
        response.addCookie(cookie);
    }
    * session:服务器在服务器端创建一个内存区域,用来存放当前用户的所有信息,通过cookie关联。
        * 前提:必须使用cookie
        * 保存的内容可以是文本也可以是对象
        * session:
            //默认是会话级别的、创建在服务器端、tomcat服务器设置默认时间30分钟
            //当浏览器关闭的时候session销毁
            //然后在打开浏览器、又创建session、在内存里面又要30分钟才会销毁
            //如果说关闭浏览器之后、再打开用原来的30分钟、这样的话就需要持久化session
            //写入cookie        
            //Tomcat默认设置的cookie JSESSIONID=3DFC14F2BE91077CB8A336CD7CA3D4E4; Path=/day04/; HttpOnly
            HttpSession session = request.getSession();//如果有就返回、没有就创建
            System.out.println(session.isNew());
        
            //持久化session
            Cookie cookie = new Cookie("JSESSIONID",session.getId());
            cookie.setMaxAge(60*30);
            response.addCookie(cookie);
        * URL重写
            * 假设浏览器禁止了cookie那么每一次刷新session都不一样、
            * 这个时候需要重写session保证一致
            * 获得session
            * 一般情况选择encodeURL
            * 两个方法区别在于,如果参数为空字符串,返回结果不同。
                public String encodeURL(String url) {
            
                    String absolute = toAbsolute(url);
                    if (isEncodeable(absolute)) {
                        // W3c spec clearly said
                        if (url.equalsIgnoreCase("")){  //****
                            url = absolute;
                        }
                        return (toEncoded(url, request.getSessionInternal().getIdInternal()));
                    } else {
                        return (url);
                    }

                }
                
                 public String encodeRedirectURL(String url) {

                    if (isEncodeable(toAbsolute(url))) {
                        return (toEncoded(url, request.getSessionInternal().getIdInternal()));
                    } else {
                        return (url);
                    }

                }
            * 注意:参数url必须有效,否则返回没有改变的URL
                * 当使用"/"开头,相对于web站点
                    * response.encodeURL("/day04/urlSessionServlet2")
                    * /day04/urlSessionServlet2;jsessionid=F85DB5EFDDB9A6B170AF2B4959EFC4FC
                * 获得Web的绝对路径
                    String absolute = toAbsolute(url);
                    * http://localhost/day04/
            * 总结:
                * 需要考虑用户的Cookie是否禁用了
                * 将所有的链接全部进行URL重写(过滤器)
    
            一次性验证码
                //获得一张图片        
                // 创建图片 -- 在内存中
                int width = 90;
                int height = 35;
                BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                
                //创建图层,获得画板
                Graphics g = image.getGraphics();
                //确定画笔颜色
                g.setColor(Color.BLACK);
                //填充一个矩形
                g.fillRect(0, 0, width, height);
                //只需要一个边框
                //设置颜色
                g.setColor(Color.WHITE);
                //填充一个矩形
                g.fillRect(1, 1, width -2, height -2);
                
                //填充字符
                String data = "http://www.mamicode.com/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
                //设置字体
                g.setFont(new Font("宋体",Font.BOLD,30));
                
                //缓存随机生成的字符
                StringBuffer buf = new StringBuffer();
                
                //随机获得4个字符
                Random random = new Random();
                for(int i = 0 ; i < 4 ; i++){
                    //设置随机颜色
                    g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
                    //获得一个随机字符
                    int index = random.nextInt(62);
                    //截取字符串
                    String str = data.substring(index, index + 1);  //[)
                    //需要将随机的字符,写到图片中
                    g.drawString(str, 20 * i, 30);
                    //缓存
                    buf.append(str);
                }
                
                //将获得随机字符串,保存到session
                // * 获得session
                HttpSession session = request.getSession();
                // * 保存值
                session.setAttribute("number", buf.toString());
                
                //干扰线
                for(int i = 0 ; i < 10 ; i ++){
                    //设置随机颜色
                    g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
                    //随机画直线
                    g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
                    
                }
                                
                /**
                 * <extension>jpg</extension>
                        *  <mime-type>image/jpeg</mime-type>
                 */
                //通知浏览器发送的数据时一张图片
                response.setContentType("image/jpeg");
                //将图片发送给浏览器
                ImageIO.write(image, "jpg", response.getOutputStream());


    
                //获得用户提交的数据 imageNumber
                String imageNumber = request.getParameter("imageNumber");
                //需要判断  从session获得保存的验证码的信息
                // * 获得session
                HttpSession session = request.getSession();
                // * 获得保存的值number
                String number = (String)session.getAttribute("number");
        
                PrintWriter out = response.getWriter();
                
                //匹配 用户提交的数据与程序保存的数据
                if(number != null){ //程序保存
                    if(number.equalsIgnoreCase(imageNumber)){
                        //输入正确
                        out.print("验证通过");
                    } else {
                        //验证码错误
                        out.print("验证码错误");
                    }
                    //无论情况,程序存储的数据,只能使用一次
                    session.removeAttribute("number");(注销Session)
                } else {

                out.print("验证码失效");

            }
    
    
    
    
    
    
    
    
    
    
   

Cookie&&Session会话技术之再体验