session和cookie

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

会话技术

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

  • Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端 可以清除cookie
  • Session:将数据存储到服务器端,安全性相对好,增加服务器的压力

cookie技术

  • 服务器向客户端发送一个cookie
  1. 创建cookie 使用new关键字就可以创建
  2. 设置cookie持久化时间
  3. 设置cookie携带路径
  4. 向客户端发送cookie
  5. 删除cookie
  • 服务器怎么接收客户端携带的数据
request.getCookies(); 返回 数组类型
  • cookie案例
    一个简单的案例,我们先写一个文件来给创建一个cookie,然后把它发送到客户端。
package CookieDemo;

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

/**
 * Servlet implementation class CookieDemo
 */
@WebServlet("/CookieDemo")
public class CookieDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//服务器向客户端发送一个cookie
		//第一步 创建cookie
		Cookie cookie = new Cookie("name", "Tom");
		//第二步 设置一个cookie的持久化时间
		//如果不设置,cookie默认在浏览器内存中,浏览器关闭cookie随即销毁
		//如果设置,存储到客户端的电脑中
		//设置了10分钟
		cookie.setMaxAge(10*60);
		//第三步 设置携带路径
		//注意事项:如果不设置携带路径,
		//    	   那么该cookie信息访问产生该cookie的web资源的所有路径都会有cookie信息
		System.out.println( request.getContextPath());
		cookie.setPath( request.getContextPath() );
		//第四步 向客户端发送这个cookie
		response.addCookie(cookie);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

}

随后我们在写一个程序获得来自客户端的cookie信息:

package CookieDemo;

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

/**
 * Servlet implementation class GetCookeieDemo
 */
@WebServlet("/GetCookeieDemo")
public class GetCookeieDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Cookie[] cookies = request.getCookies();
		for(Cookie c:cookies ) {
			if( c.getName().equals("name")  ) {
				System.out.println( "对应的值:"+ c.getValue() );
			}
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

}

这样我们就实现了在客户端存储信息的功能(比如我们可以存储一些账户信息,因为http协议是无状态的)

session技术

一般结合cookie使用,用session对象在服务器中对客户端进行识别
session对象有一个标识id标识,这个标识代表唯一的客户端id(服务器创建session对象后会把session的id ,以cookie的形式回显给客户端)

  1. 获取session对象
request.getSession()
  1. session中存取数据(session也是一个域对象)范围:一次会话(比较小)
//第一步 得到session对象
HttpSession session = request.getSession();
//第二步 往session对象中放置数据  所有域对象 方法名都相同 就是调用的对象名不同
session.setAttribute("sex", "男");
//第三步  session取数据
String sex=(String) session.getAttribute("sex");
System.out.println("域对象中的数据"+sex);
//移除域对象中数据
session.removeAttribute("sex");

一个小例子:

package CookieDemo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class SessionParaDemo
 */
@WebServlet("/SessionParaDemo")
public class SessionParaDemo extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        HttpSession session = request.getSession();
        session.setAttribute("name", "Jeason");
        Object attribute = session.getAttribute("name");
        System.out.println( (String)attribute );
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

}
  1. 每次回话只能生成一个session,并且其ID是唯一的,我们可以通过下面的程序看出来
package CookieDemo;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class SessionDemo
 */
@WebServlet("/SessionDemo")
public class SessionDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		String idString = session.getId();
		System.out.println("Session ID:"+ idString);
		if(session.isNew()) {
			System.out.println("this is new session!");
		}else {
			System.out.println("this is old session!");
		}
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}
}

当我们在页面多次访问该程序的时候,,输出如下;

Session ID:1CD44853C3D2B3D759A3C8F9BBBFC2CD
this is new session!
Session ID:1CD44853C3D2B3D759A3C8F9BBBFC2CD
this is old session!
Session ID:1CD44853C3D2B3D759A3C8F9BBBFC2CD
this is old session!

Session对象的生命周期

创建:第一次执行request.getSession()时创建
销毁:
1)服务器(非正常)关闭时
2)session过期/失效(默认30分钟)
问题:时间的起算点 从何时开始计算30分钟?
从不操作服务器端的资源开始计时
可以在工程的web.xml中进行配置

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

3)手动销毁session
session.invalidate(); 作用范围:默认在一次会话中,也就是说在,一次会话中任何资源公用一个session对象
面试题:浏览器关闭,session就销毁了? 不对

过滤器filter

第一步 书写一个类 实现filter接口 重写里面方法
第二步 在dofilter这个方法中根据自己需求进行 放行和不放行的设置

下面的例子,我门假设的前提是,如果登录成功了,就把登录成功后的用户名字存到session里面,然后设置过滤器过滤主页,如果session里面没有用户的名字信息,那么不可以访问主页。

package Project;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


/**
 * Servlet Filter implementation class FilterDemo1
 */
@WebFilter("/index.html")
public class FilterDemo1 implements Filter {

    /**
     * Default constructor. 
     */
    public FilterDemo1() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
	
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		HttpServletResponse httpServletResponse = (HttpServletResponse)response;
		HttpSession session = httpServletRequest.getSession();
		String name = (String)session.getAttribute( "name" );
		
		
		
		if(name!=null) {
			System.out.println("已验证登录状态,过滤器放行!");
			chain.doFilter(request, response);
			
		}else {
			
			System.out.println("请登录访问");
			httpServletResponse.sendRedirect("login.html");
		}
		
		// 放行
		
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

监听器

监听器就是监听某个对象的的状态变化的组件
监听器的相关概念:
事件源:被监听的对象 ----- 三个域对象 request session servletContext
监听器:监听事件源对象 事件源对象的状态的变化都会触发监听器