状态管理(之cookie、session、filter、listener)

#cookie和session

   -常用的会话跟踪技术是Cookie与Session。

   -会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

   -cookie和session用来跟踪用户的整个会话。

   ##1.以一个业务场景开始

-登陆时要记录账号

-以后访问查询、增加、修改页面时要显示账号

   ##2.前提条件:浏览器和服务器是多对一关系

   ##3.使用如下对象

附件:(可忽略)

-request:登陆、查询是不同的请求,使用不同的request

-config:假设开发项目时采用多个Servlet处理不同的请求 ,

-多个Servlet用不同的config

-它没有读写变量的能力

-context:tomcat内只有一个对象,每个人登陆时传递的账号都是相同的数据

-key都一样,存入context有冲突

     --以上做法在此都不能使用

   ##4.正确的做法:通过 cookiesession 保存这样的数据

   ## cookie、session区别

-cookie:存储在浏览器上,服务器压力小,但数据不安全。Cookie通过在

              客户端记录信息确定用户身份。

-session:存储在服务器上,服务器压力大,但数据安全。Session通过在

                服务器端记录信息确定用户身份。

-- 重要数据存入session,一般数据存入cookie

   ##cookie演示

package web;

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;

/**
 * 登陆检查,判断账号密码是否正确
 * @author menbog
 *
 */
public class LoginServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        //接收参数
        String code = req.getParameter("code");
        //
        //每个cookie对象只能存一条数据,key、value 都是字符串
        Cookie c1 = new Cookie("code", code);
        res.addCookie(c1);//将cookie发送给浏览器,浏览器接收到后会自动保存
        
    }
    
}
package web;

import java.io.IOException;
import java.io.PrintWriter;

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 IndexServlet extends HttpServlet {
    /**
     * 模拟打开主页
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        //向浏览器输出主页内容
        //获取cookie
        Cookie[] cs = req.getCookies();
        if(cs != null) {
            res.setContentType("text/html;charset=utf-8");
            PrintWriter pw = res.getWriter();
            for(Cookie c:cs) {
                pw.println(c.getName()+":"+c.getValue());
//              pw.println(c.getName()+":"
//                  +URLDeoder.decode(c.getValue(),”utf-8”));
            }
            pw.close();
        }
    }

}



<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>jsp4</display-name>
  <servlet>
      <servlet-name>login</servlet-name>
      <servlet-class>web.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>login</servlet-name>
      <url-pattern>/main/login</url-pattern>
  </servlet-mapping>
  
  <servlet>
      <servlet-name>index</servlet-name>
      <servlet-class>web.IndexServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>index</servlet-name>
      <url-pattern>/main/index</url-pattern>
  </servlet-mapping>
</web-app>

-- 首先访问:http://localhost:8080/jsp4/main/login?code=zhangsan 

QQ截图20190226122512

--再访问http://localhost:8080/jsp4/main/index 

QQ截图20190228203552

   ##cookie特点

-cookie保存在浏览器上

-多个请求可以共用一组cookie

-多个Servlet可以共用一组cookie

-每个用户(浏览器)访问服务器,都会获得一组cookie

   ##cookie的生存时间

>>:默认情况下,浏览器会将cookie保存在内存中,只要浏览器不关闭,cookie就一直存在

>>:void  Cookie.setMaxAge(int seconds);   seconds单位时秒

如果希望浏览器关闭后cookie仍在,可以此方法通过设置过期时间

   -- second > 0:代表浏览器关闭后,cookie不会失效,仍然存在。并且会将cookie保存到硬盘中,直到设置时间过期才会被浏览器自动删除,

  -- second <-1:代表浏览器关闭后,也就是会话结束后,cookie就失效了,也就没有了。默认为-1
  -- second =0:删除cookie。
     不管是之前的second =-1还是>0,当设置second =0时,cookie都会被浏览器给删除。

   ##cokie编码:只能保存合法的ASCII字码。如果要保存中文,需要将中文转换成合法的ASCII字符。

//创建一个cookie存中文

//编码:
         Cookie c2 = new Cookie("city", URLEncoder.encode("苏州", "utf-8"));
         res.addCookie(c2);


//解码:

URLDeoder.decode(c.getValue(),”utf-8”)

   

##cookie的路径问题

例子:在/main/login路径下创建的cookie,它只对/main及其下级路径有效

解决办法:

-修改cookie的访问路径

 --setPath("/");//在该服务器下,任何项目,任何位置都能获取到cookie。

 --用途:保证在tomcat下所有的web项目可以共享相同的cookie 

   --例如:tieba , wenku , beike 多个项目共享数据。例如用户名。

 --setPath("/test01/"); //在test01项目下任何位置都能获取到cookie。

 

##session演示

session特点:

--1.浏览器第一次访问服务器时会自动创建一个session,给到request。

--2.响应(response)的时候服务器会自动创建一个cookie,将session id给浏览器。

--3.下次浏览器访问时,会传session id,服务器根据id找到session,将它给到本次请求的request里。

--4.多个请求可以共用同一个session

--5.一个浏览器有一个session

package web;

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 LoginServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        //接收账号
        String adminCode = req.getParameter("adminCode");
        //存入session
        HttpSession session = req.getSession();
        session.setAttribute("adminCode", adminCode);
        //服务器会自动创建一个cookie,将sessionId给浏览器。
        //Cookie c = new Cookie("JSESSIONID", session.getId());
    }

}
package web;

import java.io.IOException;
import java.io.PrintWriter;

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 IndexServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        HttpSession session = req.getSession();
        String adminCode = (String) session.getAttribute("adminCode");
        res.setContentType("text/html;charset=utf-8");
        PrintWriter out = res.getWriter();
        out.println(adminCode);
        out.close();
    }

}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>jsp5</display-name>
  
  <servlet>
      <servlet-name>login</servlet-name>
      <servlet-class>web.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>login</servlet-name>
      <url-pattern>/main/login</url-pattern>
  </servlet-mapping>
  
  <servlet>
      <servlet-name>index</servlet-name>
      <servlet-class>web.IndexServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>index</servlet-name>
      <url-pattern>/main/index</url-pattern>
  </servlet-mapping>
</web-app>

   ##session语句

-- request.getSession();
   //如果没有将创建一个新的,等效getSession(true);
-- request.getSession(boolean);  
   //true:没有将创建,false:没有将返回null
-- session.setAttrubute(key,value);
  session.getAttribute(key);
-- session.invalidate();//将session对象销毁
  session.setMaxInactiveInterval(int interval); 
   //设置有效时间,单位秒

 -- 在web.xml中配置session的有效时间:

 <session-config>
    <session-timeout>30</session-timeout>   单位:分钟
 <session-config>

   ##如果cookie被禁用了,session也不能使用。

       解决办法:session id的URL重写

通过URL将session id 传递给服务器:URL重写

  1)手动方式: url;jsessionid=....

  2)api方式:

   >> response.encodeURL(java.lang.String url) ;

         //进行所有URL重写

      >> response.encodeRedirectURL(java.lang.String url) ;

          //进行重定向 URL重写

#cookie和session的作用

1.通俗来说:这些数据在不同的请求中可以共用,在不同的Servlet之间可以共用,每个浏览器都有一组这样的数据。

2.http协议是无状态协议,服务器无法记住浏览器。cookie和session的作用就是用来管理状态(浏览器曾经访问过服务器的证据<数据>),让服务器记住浏览器。

原文地址:https://www.cnblogs.com/menbozg/p/10449811.html