JavaWeb学习心得之session

一、session简介

       Session是服务端技术,服务器在运行时可以为每个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问浏览器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他web资源时,其他web资源再从用户各自的session中取出数据为用户服务。


二、session实现原理

       服务器创建session后,会把session的id号,以cookie的形式回写给客户端,只要客户端的浏览器不管,再去访问服务器时都会带着session的Id,服务器发现哭护短带着session id过来,就会使用内存中与之对应的session为之服务。

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

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("utf-8");
		response.setHeader("content-type", "text/html;charset=utf-8");
		PrintWriter pw = response.getWriter();
		HttpSession session = request.getSession();
		session.setAttribute("data", "韩信");
		String sessionId = session.getId();
		if(session.isNew()){
			pw.print("session创建成功,sessionId是:"+sessionId);
		}else{
			pw.print("服务器已经存在该session,sessionID是:"+session);
		}
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
	
}


第一次访问时,服务器会创建一个新的sesion,并且把session的Id以cookie的形式发送给客户端浏览器。
JavaWeb学习心得之session_第1张图片

点击刷新按钮,再次请求服务器,此时就可以看到浏览器再请求服务器时,会把存储到cookie中的session的Id一起传递到服务器端了。JavaWeb学习心得之session_第2张图片


三、Session对象的创建和销毁时机

1.创建

在程序中第一次调用request.getSession()方法时就会创建一个新的Session,可以用isNew()方法来判断Session是不是新创建的。

//使用request对象的getSession()获取session,如果session不存在则创建一个
HttpSession session = request.getSession();
//获取session的Id
String sessionId = session.getId();
//判断session是不是新创建的
if (session.isNew()) {
    response.getWriter().print("session创建成功,session的id是:"+sessionId);
}else {
    response.getWriter().print("服务器已经存在session,session的id是:"+sessionId);
}

2.销毁

session对象默认30分钟没有使用,则服务器会自动销毁session,在web.xml文件中可以手工配置session的失效时间。



  
  
  
    index.jsp
  

  
    
        15
    

当需要在程序中手动设置Session失效时,可以手工调用session.invalidate方法,摧毁session。

1 HttpSession session = request.getSession();
2 //手工调用session.invalidate方法,摧毁session
3 session.invalidate();

四、利用session防止表单重复提交

       具体的做法:在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token。然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端,然后在服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。

Token生成类

import java.security.MessageDigest;
import java.util.Random;

import sun.misc.BASE64Encoder;
/**
 * Token工具类,单例模式(保证内存中只有一个实例对象)
 * 
 * @author hanxin
 *
 */
public class TokenUtil {
	private static TokenUtil instance;
	
	private TokenUtil(){
		
	}
	/*
	 * 返回实例对象,如果没有对象就新建一个对象
	 */
	public static TokenUtil getInstance(){
		if(instance==null){
			instance = new TokenUtil();
		}
		return instance;
	}
	/*
	 * 生成token
	 */
	public String getToken(){
		String token =String.valueOf(System.currentTimeMillis()+new Random().nextInt(999999999));
		//数据指纹   128位长   16个字节  md5
		try{
			MessageDigest md = MessageDigest.getInstance("md5");
			byte[] md5 = md.digest(token.getBytes());
			//base64编码--任意二进制编码明文字符
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(md5);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
}
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SessionDemo02 extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String token = TokenUtil.getInstance().getToken();//创建令牌
		request.getSession().setAttribute("token", token);//保存到session中
		request.getRequestDispatcher("/form.jsp").forward(request, response);//跳转到form.jsp中
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
	
}

表单

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>



form表单



    
<%--使用隐藏域存储生成的token--%> <%-- "> --%> <%--使用EL表达式取出存储在session中的token--%> 用户名:

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SessionDemo03 extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String token_client = request.getParameter("token");
		//1、如果用户提交的表单数据中没有token,则用户是重复提交了表单
		if(token_client==null){
			return;
		}
		String token_server = (String)request.getSession().getAttribute("token");
		//2、如果当前用户的Session中不存在Token(令牌),则用户是重复提交了表单
		if(token_server==null){
			return;
		}
		//3、存储在Session中的Token(令牌)与表单提交的Token(令牌)不同,则用户是重复提交了表单
		if(!token_client.equals(token_server)){
			return;
		}
		request.getSession().removeAttribute("token");//移除session中的token
		System.out.println("处理用户提交请求!!");
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
	
}



你可能感兴趣的:(Java学习笔记)