zoukankan      html  css  js  c++  java
  • 开启 J2EE(五)— Servlet之状态管理

    HTTP无状态协议


    首先我们要知道:

    HTTP协议是无状态协议。

    我们知道HTTP协议就是server通过Request从浏览器接收和Response向浏览器输出的这么一个过程(浏览器和server的交互过程)。

    所谓无状态也就是完毕一个过程后(client和server 就断开了),下一个过程假设须要前面的信息,它还须要又一次进行一次,server不能记住上次的请求。

    这样可能就是在频繁进行同样的请求传送时,数据量增大,效率减少。所以,假设在server不须要先前信息时它的应答就较快。

    那么,怎样让server知道不同的请求是否来自同一个client。就状态管理问题出现了CookieSession。


    Cookie


    Cookie保存在client,有两种实现方式。


    方式一

     将Cookie保存到浏览器内存中

     1 保存Cookie

    写到client(addCookie()

     

    public class SetCookie extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		Cookie c1 = new Cookie("password","123");
    		response.addCookie(c1);
    	}
    }
    
     Cookie以键值对的形式进行保存。


     2 读取Cookie(通过Http协议传过去的)

     

    public class ShowCookie extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		Cookie[] Cookies = request.getCookies();
    		for(int i=0; i<Cookies[i];i++){
    			Cookie c = Cookies[i];
    			reponse.getWriter().Println(c.getName() + "," + c.getValue());
    		}
    	}
    }

    此方式,Cookie仅仅能在当前浏览器窗体和子窗体中有效。重开浏览器无效。所以有一定的限制。

     

    方式二

     将Cookie保存到文本文件

     文件怎样生成的,通过限制Cookie的生命期。然后在写到client,就能够生成文本文件了。

     例如以下例。拿到clientIP的样例:

     1 保存Cookie。写到client文本文件

    public class SetCookie extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
                    
    <span style="font-family:SimSun;">                //<span lang="zh-CN" style="font-family:SimSun;">获取</span><span lang="en-US" style="font-family:Calibri;">IP</span><span lang="zh-CN" style="font-family:SimSun;">地址</span></span>
    		Cookie c2 = new Cookie("client_ip",request.getRemoteAddr());
    		
    		//设置Cookie的生命周期为1小时,单位秒
     		c2.setMaxAge(60*60);
     		response.addCookie(c2);
    		
    		response.getWriter().println("SetCookie OK");
    	}
    }

       2 读取Cookie。同方式一,略。


    Cookie说明:

    上面两种方式都是通过Servlet创建一个 Cookie对象,存储键-值对。

    1、通过 response的 addCookie方法将该 Cookie信息加入到对应信息中。

    2、再通过request.getCookies()方法获取到Cookie信息。

    3、总的来说cookie机制採用的是在client保持状态的方案。

    它是在client的会话状态的存储机制,他须要用户打开client的cookie支持。

    4、不足:因为Cookie是保存在client的,相对存在较大的安全隐患。且一般浏览器对 Cookie的数目及数据大小有严格的限制。所以对一些小数量,安全性的信息,普通情况下通过Session存储。


    Session


    Session保存在服务端。

    因为Session的是将会话保存在服务端。关闭浏览器(或新开)就没了。可是这么多的用户Session,怎样区分?这就须要一个SessionID。每个SessionID都指向了唯一的一个用户会话。

    可是client怎样知道SessionID呢,方式有两种。

    方式一

    在Cookie中保存SessionID



    public void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException { 
    
        //获得 HttpSession对象 
        HttpSession session = request.getSession(); 
        //设置 Session对象的最长不活动间隔 
        session.setMaxInactiveInterval(30); 
    
        //获取 Session中的数据 
        List list = (List)session.getAttribute("list"); 
        if (list == null) { 
            list = new ArrayList(); 
            list.add("hey"); 
            //向 Session中加入数据 
            session.setAttribute("list", list); 
        } 
    } 
    
    


    方式二

    假设禁用了Cookie?通过URL重写,SessionId能够保存在URL后面

    URL重写:

    public class UrlRewriterSession extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		HttpSession session = request.getSession(true);
    		response.getWriter().println("<a href= '" + response.encodeURL(request.getRequestURL().toString()) + "'>UrlRewrite</a>");
    	}
    }
    不论client是否禁用Cookie。

    假设想安全使用Session。仅仅能使用URL重写,但对应的会添加编程负担,所以有时站点要求client打开Cookie。



    总结

      

      相比Cookie,Session事实上在之前ASP.net中已经用的非常多了。当时真是认为真好用。把值放到Session中。什么时候用直接取,不用再查数据库了,太方便了,以至于快到了滥用的趋势。然而过度使用session将会导致代码不可读并且不好维护,并且Session的默认失效期是30分钟。假设在Session中放入了大的对象,server的压力可想而知。

    所以Session的使用也须要有度。


  • 相关阅读:
    ubuntu上部署ceph集群
    Ceph介绍及原理架构分享
    搭建家庭 NAS 服务器
    Android让屏幕保持常亮,不熄屏的三种方法
    IP流 TS流 PS流之间的关系及区别
    【WPF】Command 自定义命令
    WPF的路由事件、冒泡事件、隧道事件(预览事件)
    WPF之路路由事件
    c# string按指时间格式转化成datetim
    WPF样式(Style)入门
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7109461.html
Copyright © 2011-2022 走看看