zoukankan      html  css  js  c++  java
  • javaWeb核心技术第八篇之Cookie和Session

    会话技术:
    会话是什么?
    浏览器和服务器交互,浏览器打开网页访问服务器,会话开始,正常交互.
    浏览器关闭,会话结束.
    会话能干什么?
    会话可以共享数据.
    Cookie和session将数据保存在不同的位置 进行数据共享

    Cookie入门案例

    1.创建一个cookie对象
    a. Cookie cookie = new Cookie(String name,String value);
    2.响应给浏览器
    a.Response.addCookie(cookie)
    3.再次请求时需要获得cookie
    a.Request.getCookies() 获得的是数组(包含所有的cookie,如果没有cookie,返回值为null)
    4.Cookie.getName() 获得名称 cookie.getValue() 获得值

    Cookie原理--会话级别cookie
    Http中头信息进行数据传输
    Cookie默认是会话级别的cookie,浏览器打开访问服务器 ,交互的时候数据共享,当前浏览器关闭的时候数据失效.

    Cookie细节--持久化级别的cookie

    以后开发需要设置时间(cookie的存活时间)
    Cookie.setMaxAge(秒)
    以后开发需要设置路径(访问路径)(作用:cookie 作用域 如果请求地址栏跟cookie文件里cookie路径一致 自动携带)
    Cookie.setPath("/") (作用:表示该服务器下所有的项目允许共享cookie)

    6)如果不设置cookie的有效存活时间,默认cookie只在内存中有效,当程序结束后,内存中的cookie销毁,不会写入浏览器的缓存中,因此,
    需要为cookie设置一个有效的时间,当程序运行完毕后,会将该cookie写入浏览器的缓存中,即硬盘中保留。如果cookie的存活时间为0,
    就相当于浏览器将删除cookie删除或无效.
    7)在默认情况下,day08web应用的cookie只能被day08web应用的动态资源访问,如果要让其它的web资源访问,得设置cookie.setPath("/day08-2"),默认cookie的path为当前web应用。
    8)cookie是以文本文件的方式存于浏览器缓存中,而且里面的内容明码.

    cookie细节:(面试)
    1.cookie的value不可以为中文(因为在响应头,响应头在数据传输时,使用是http协议,而协议使用的是iso-8859-1 不支持中文)
    2.cookie的设置 遵循4 2 3规则.
    2.1:4 表示4kb :设置value的是长度是有限的(精准)
    2.2:2 表示20个 : 表示一个网站(站点)最多支持20个cookie(不精准)
    2.3:3 表示300个 : 一个浏览器最大存放cookie是300个(不精准)

    案例:记录本次登录时间,显示上次访问时间

    //编码
    response.setHeader("content-type","text/html;charset=utf-8");

    //2.第二次访问
    //2.1获得请求中携带的cookie数据
    Cookie[] cookies = request.getCookies();
    //2.2判断数据是否为空
    if(cookies != null) {
    for(Cookie cookie : cookies) {
    //判断是最后一次访问的cookie
    if("lasttime".equals(cookie.getName())) {
    response.getWriter().print("您上次访问时间是" + cookie.getValue());
    //重新赋值
    //1.第一次访问
    //1.1创建一个cookie
    Cookie cookie1 = new Cookie("lasttime",new Date().toLocaleString());

    //1.1.1 设置最大存活时间
    cookie1.setMaxAge(60*60);
    //1.1.2设置路径
    cookie1.setPath("/");

    //1.2将cookie响应给浏览器
    response.addCookie(cookie1);
    }
    }
    }else {
    //1.3打印第一访问
    response.getWriter().print("您是第一次访问服务器");
    //1.第一次访问
    //1.1创建一个cookie
    Cookie cookie = new Cookie("lasttime",new Date().toLocalString());

    //1.1.1设置最大存活时间
    cookie.setMaxAge(60*60);
    //1.1.2设置路径
    cookie.setPath("/");

    //1.2将cookie响应给浏览器
    response.addCookie(cookie);
    }

    Session的底层基于cookie,cookie只用于保存id,服务器根据id去找session对象
    过程:
    1.服务器第一次调用getSession()将创建一个Session对象,并且会给这个session对象赋值唯一的id属性sessionld = 1234.
    2.session的底层创建一个cookie对象,目的sessionid传给浏览器 new Cookie(jsessionid,1234),浏览器端会自动保存jsessionid
    3.下一次再次请求时,自动携带jsession=1234,服务器第二次调用getSession()根据session获得唯一的session对象.
    总结:session的底层基于cookie

    Session生命周期:

    问题:如果浏览器端禁用cookie session能否使用?
    session生命周期
    session的底层基于cookie,使用的是会话级的cookie,浏览器关闭cookie,但session还是存在服务器,只是因为cookie丢了,所以session找不回来了.

    创建:
    1.第一次调用request.getSerssion()时创建.
    销毁:
    2.1:超时30分钟自动销毁,tomcat配置可以修改(路径在:tomcat -- conf -- web.xml)
    例如:
    <session-config>
    <session-timeout>30</session-timeout>
    </session-config>
    2.2 手动调用 session.invalidate()销毁.或者setMaxInactiveInterval(int interval)(不常用)
    2.3 服务器非正常关闭.
    开启服务器后,点击了Console的红色按钮.

    session如何持久化?
    将sessionid保存到数据库或者可以在浏览器端将cookie持久化.

    作用域对象总结:

    数据共享:Servlet中的域对象.
    类型ServletRequest HttpSession ServletContext
    对象request session ServletContext

    api:
    setAttribute(String name,Object value) :
    getAttribute(String name) 返回值Ojbect :
    removeAttribute() :

    域对象:在一定范围内共享数据.
    request:一个请求内多个资源可以共享数据(使用的技术 请求转发)
    session:一个会话内共享数据,可以有多个请求.
    servletContext : 一个项目内多个会话,多个请求共享同一份数据(全局变量时使用)

    以后作用域如何选择?
    1.能小不大原则.
    2.需求优先原则.

    Cookie也可以进行数据共享,但不是域对象,因为指的是服务器端技术.
    Cookie和Session关系?如何选择?
    Session的底层基于cookie.
    如何选择?主要看数据的重要程度.

    如果想使用Servlet必须要有tomcat , web中一共13套规范(接口) tomcat支持servlet和jsp

    一次性验证码

    @WebServlet(urlPatterns={"/BDVerifyCodeServlet"})//等效web.xml配置
    public class BDVerifyCodeServlet extends HttpServlet{

    // 图片高度
    private static final int IMG_HEIGHT = 100;
    // 图片宽度
    private static final int IMG_WIDTH = 30;
    // 验证码长度
    private static final int CODE_LEN = 4;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 用于绘制图片,设置图片的长宽和图片类型(RGB)
    BufferedImage bi = new BufferedImage(IMG_HEIGHT, IMG_WIDTH, BufferedImage.TYPE_INT_RGB);
    // 获取绘图工具
    Graphics graphics = bi.getGraphics();
    graphics.setColor(new Color(100, 230, 200)); // 使用RGB设置背景颜色
    graphics.fillRect(0, 0, 100, 30); // 填充矩形区域

    // 验证码中所使用到的字符
    char[] codeChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456".toCharArray();
    String captcha = ""; // 存放生成的验证码
    Random random = new Random();


    graphics.setFont(new Font("楷体", Font.BOLD, 20));
    for(int i = 0; i < CODE_LEN; i++) { // 循环将每个验证码字符绘制到图片上
    int index = random.nextInt(codeChar.length);
    // 随机生成验证码颜色
    graphics.setColor(new Color(random.nextInt(150), random.nextInt(200), random.nextInt(255)));
    // 将一个字符绘制到图片上,并制定位置(设置x,y坐标)
    graphics.drawString(codeChar[index] + "", (i * 20) + 15, 20);
    captcha += codeChar[index];
    }
    // 将生成的验证码code放入sessoin中
    req.getSession().setAttribute("code", captcha);
    // 通过ImageIO将图片输出
    ImageIO.write(bi, "JPG", resp.getOutputStream());
    }
    }

    //效验
    try{
    //编码--
    request.setCharacterEncoding("utf-8");
    response.setHeader("content-type","text/html;charset=utf-8");

    //1.获得
    //1.1用户输入的验证码 -- 表单的组件需要有name属性
    String verifyCode = request.getParameter("verifyCode");
    //1.2获得图片生成的验证码
    Object code = request.getSession().getAttribute("code");
    //1.3情况session中验证码
    request.getSession().removeAttribute("code");
    if(code == null) {
    //3.1存放错误记录
    request.setAttribute("msg","验证码失效");
    //3.2请求转发给当前页面form.html
    request.getRequestDispatcher("/form.jsp").forward(request,response);
    return ;//等效else
    }

    //2.处理 //equalsIgnoreCase 不区分大小写
    if(verifyCode.equalsIgnoreCase(code.toString())) {
    //3.响应成功
    response.getWriter.prinltn("success");
    }else {
    //3.失败 请求转发
    //3.1存放错误记录
    request.setAttribute("msg","验证码错误");
    //3.2请求转发给当前页面form.jsp
    request.getRequestDispatcher("/form.jsp").forward(request,response);//刷新页面

    }

    }catch(Exception e) {

    }


    debug : 里面在Progress窗口下报building和sleeping,那就是编译不过去了.
    如果能编译过去,在Project窗口下点击Clean(可以重新编译一个,或者多个),出现Building workspace有绿色条,说明没问题,如果没有
    那就是Eclipse挂掉了.解决的办法就是重新启动.

    案例:
    public class Parent {
    public void demo1() {
    System.out.println("1");
    this.demo2();
    //在编译时,this的确表示parent
    //但在运行时,表示是son
    }
    //不可以删,如果删了,编译不过去
    public void demo2() {
    System.out.println("2");
    }
    }

    public class Son extends Parent {
    public void demo1() {
    super.demo1();
    System.out.println("3");
    this.demo2();
    }

    public void demo2() {
    System.out.println("4");
    }
    public static void main(String[] args) {
    Son son = new Son();//new 是谁 this代表谁.
    son.demo1();
    }

    答案:1434
    }

    更改项目的jdk版本:项目右键 -- Project Facets -- java -- 1.7(改这里) 和 Java Compiler -- JDK -- 1.7(改这里)

    JS : 函数问题
    //1.函数的声明问题 跟参数没有关系 只要函数名称一样 产生覆盖的效果
    //2.函数的调用问题 跟参数没有关系
    //3.函数当中有arguments 用来接收所有的数据

    function demo2() {
    alert(1);
    }
    function demo2() {
    alert(arguments.length);//arguments 表示一个数组,用数组来接收传过来的所有参数值
    //arguments.length : 获取的是这个数组的长度
    alert(a);

    }
    demo2("1","2","3");

    //$(对象).css("参数") ; 获得 (底层是这么判断的,如果arguments是1表示就一个参数,这样就是表示获得,如果不止一个参数,那就是设置)
    //$(对象).css("参数","参数"); 设置

    js中遍历;
    var arr = new Array("三金","三金","丝巾");
    //普通遍历
    for(var i = 0;i < arr.length ; i++) {
    alert(arr[i]);
    }
    //增强遍历(forin) foreach(Object obj : 数组) :(var相当于Object;variables相当于索引(或者说是key或者是下标); :相当于in ; 数组相当于arr)
    for(var variables in arr) {
    alert(arr[variables]);
    }
    arr["abc"] = "1234";//数组可以使用字符串当下标(数组的属性)
    alert(arr["abc"]);
    </srcipt>
    </head>
    <body>
    <input id="usernameId" type="text" name="username" value="二斤rose" />

    <script>
    var userNameObj = document.getElementById("usernameId");
    //增强for 可以遍历对象的属性
    //现在的userNameObj相当于是一个数组
    for(var temp in userNameObj) {
    alert(temp);//temp表示属性的key值(例如:type,name,value等等很多)
    if(temp == "value") {
    //数组名[temp]
    alert(userNameObj[temp]);
    }
    }
    </script>
    </body>

  • 相关阅读:
    1014 Waiting in Line (30)(30 point(s))
    1013 Battle Over Cities (25)(25 point(s))
    1012 The Best Rank (25)(25 point(s))
    1011 World Cup Betting (20)(20 point(s))
    1010 Radix (25)(25 point(s))
    1009 Product of Polynomials (25)(25 point(s))
    1008 Elevator (20)(20 point(s))
    1007 Maximum Subsequence Sum (25)(25 point(s))
    1006 Sign In and Sign Out (25)(25 point(s))
    1005 Spell It Right (20)(20 point(s))
  • 原文地址:https://www.cnblogs.com/haizai/p/11406171.html
Copyright © 2011-2022 走看看