JavaWeb开发之Cookie&Session

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb开发之Cookie&Session相关的知识,希望对你有一定的参考价值。

会话简单理解为:用户打开一个浏览器,点击多个超链接访问服务器的web资源,然后关闭浏览器,整个过程称为是一次会话。每个用户与服务器进行交互过程中,产生一些各自的数据,程序想要把这些数据进行保存,就需要使用会话技术。会话技术主要分为Cookie技术和Session技术两种,具体如下:Cookie是客户端技术,程序把每个用户的数据以cookie的形式保存到各自浏览器中。当用户使用浏览器再次访问服务器中的web资源的时候,就会带着各自的数据过去。这样,web资源处理的就是用户各自的数据了。Session是服务器端技术,利用这个技术,服务器在运行时为每一个用户的浏览器创建一个独享的session对象。由于session为用户浏览器独享,所有用户在访问服务器的时候,可以把各自的数据放在各自的session中,当用户再次访问服务器中的web资源的时候,其他web资源再从用户各自的session中取出数据为用户服务。

目录

1、使用cookie技术记录用户上次访问时间

2、cookie的分类及常用API

3、 session对象概述

4、cookie&session案例实现


1、使用cookie技术记录用户上次访问时间

实现原理如下:第一次访问,没有cookie信息,显示初次访问,并记录当前时间到cookie对象,后面再次访问将cookie数据显示,并再此记录当前时间到cookie中,并将cookie回写到浏览器。

获得从浏览器带过来的cookie:

向浏览器回写cookie:

cookie的构造方法:

 下面是实现记录用户上次访问时间的代码:

首先需要编写一个查找指定名称的cookie工具类:


import javax.servlet.http.Cookie;

/**
 * 查找指定名称Cookie的工具类
 */
public class CookieUtils 
	public static Cookie findCookie(Cookie[] cookies,String name)
		if(cookies == null)
			// 浏览器没有携带任何的Cookie
			return null;
		else
			for (Cookie cookie : cookies) 
				// 判断数组中的每个cookie的名称与给定名称是否一致
				if(name.equals(cookie.getName()))
					// 直接返回:
					return cookie;
				
			
			// 浏览器带有Cookie过来了,但是没有指定名称的那个Cookie
			return null;
		
	

编写Servlet,判断指定名称的cookie对象是否为null,如果是null,则初次访问,如果不是null,则获取cookie对象的值显示在页面,无论是第几次访问,都要讲当前时间写入cookie对象,并将cookie对象回写到浏览器。


import utils.CookieUtils;

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;
import java.io.IOException;
import java.util.Date;

@WebServlet(name = "VisitServlet")
public class VisitServlet extends HttpServlet 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
        /**
         * 用户访问Servlet
         * 	* 如果是第一次访问
         * 		* 显示 您好,欢迎来到本网站
         * 		* 记录当前访问时间,存入到Cookie,回写到浏览器
         *  * 如果不是第一次访问
         *  	* 从cookie中获得上次时间,显示到页面
         *  	* 记录当前访问时间,存入到Cookie,回写到浏览器
         */
        // 判断是否是第一次访问:从指定的Cookie的数组中获取指定名称的Cookie。
        // 获得从浏览器带过来的所有的Cookie:
        Cookie[] cookies = request.getCookies();
        // 从数组中找到指定名称的Cookie:
        Cookie cookie = CookieUtils.findCookie(cookies, "lastVisit");
        // 判断是否是第一次访问:
        if(cookie == null)
            // 是第一次访问
            // 显示到页面上一段内容:
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println("<h1>您好,欢迎来到本网站!</h1>");
        else
            // 不是第一次访问
            // 获得cookie中的上次访问时间,显示到页面
            String value = cookie.getValue();
            // 显示到页面上一段内容:
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println("<h1>您好,您的上次访问时间为:"+value+"</h1>");
        
        // 记录当前系统时间存入到Cookie,回写到浏览器
        Date d = new Date();
        // 存入到Cookie:
        Cookie c = new Cookie("lastVisit",d.toLocaleString());
//        // 给Cookie设置有效路径
//        c.setPath("/web03");
//        // 给Cookie设置有效时长
//        c.setMaxAge(60 * 60); // 设置有效时长为1小时
        // 回写到浏览器:
        response.addCookie(c);
    
    

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

最后还需要再web.xml文件中配置servlet对象,具体如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>VisitServlet</servlet-name>
        <servlet-class>servlet.VisitServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>VisitServlet</servlet-name>
        <url-pattern>/VisitServlet</url-pattern>
    </servlet-mapping>
</web-app>

2、cookie的分类及常用API

  1. 默认级别的Cookie

指的是没有设置有效时间的Cookie,默认的情况下只要关闭了浏览器,Cookie也会被销毁。(Cookie存在于浏览器的内存中,当关闭了浏览器Cookie就销毁了)。

2.持久级别的Cookie

指的是有有效时间的Cookie,这种Cookie的内容不是保存在浏览器的内存中,将Cookie的内容保存(持久化)到硬盘上。这个时候,关闭浏览器,再次打开浏览器会加载硬盘上的文件,从而Cookie中的数据就不会丢失。

常用的API如下:

3、 session对象概述

Session称为是一次会话,Cookie将用户产生的私有的数据保存到浏览器端,Session将用户产生的私有的数据保存到服务器端。注意:一个浏览器独占一个session对象。因此,在需要保存用户数据时候,服务器程序可以将用户数据写到session对象中,当用户使用浏览器访问其他程序时,其他程序可以从用户的session中取出该用户的数据,为用户服务。

  1. Cookie局限性:
    1. Cookie保存的数据是有个数和大小的限制的。
    2. 数据是保存客户端浏览器上(相对不是很安全)。
  2. Session
    1. Session没有个数和大小限制。
    2. 数据是保存在服务器上(相对比较安全)。

4、cookie&session案例实现

先看一下案例的需求,首先写一个登录页面,要求对验证码和用户名及密码进行验证,验证错误回都登录页面,登录成功则跳转到登录成功页面,如果勾选了己住用户名,利用cookie对象记录用户的用户名,下次直接回写到浏览器,需要讲登录成功的用户信息保存到session中。

 首先,数据准备,创建数据库和表,并向其中插入一条记录,具体如下:
 

create database if not exists web02_login ;
use web02_login ;
create table if not exists user(
uid int primary key auto_increment,
username varchar(20),
password varchar(20),
nickname varchar(30)
) ;

insert into user values(1,'wang','123','nicks')

案例所需三个jar包,分别是连接数据库的,c3p0连接池的以及DBUtils的。

创建登录页面和登录成功页面,该部分属于视图层。登录页面是一个表单信息,提交表单信息到登录的servlet,验证码图片是使用验证码类生成的,调用js更新图片。点击记住用户名会讲cookie的用户名值回写到页面。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	function changeImg()
		document.getElementById("img1").src="$pageContext.request.contextPath/CheckImgServlet?time="+new Date().getTime();
	
</script>
</head>
<body>

<h1>登录页面</h1>
<h3><font color="red">$msg</font></h3>
<form action="$pageContext.request.contextPath/LoginServlet" method="post">
	<table border="1" width="500">
		<tr>
			<td>用户名</td>
			<td><input type="text" name="username" value="$ cookie.remember.value "/></td>
		</tr>
		<tr>
			<td>密码</td>
			<td><input type="password" name="password"/></td>
		</tr>
		<tr>
			<td>验证码</td>
			<td><input type="text" name="checkcode" size="6"/>
			<img id="img1" src="$pageContext.request.contextPath/CheckImgServlet"/>
			<a href="#" onclick="changeImg()">看不清,换一张</a>
			</td>
		</tr>
		<tr>
			<td><input type="checkbox" name="remember" value="true"/></td>
			<td>记住用户名</td>
		</tr>
		<tr>
			<td colspan="2"><input type="submit" value="登录"/></td>
		</tr>
	</table>
</form>
</body>
</html>

登录成功页面获得session对象,判断是否登录,未登录跳转到登录页面,否则跳转到登录成功页面。

<%@ page import="servlet.domain.User" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	if(request.getSession().getAttribute("existUser") == null)
%>		
	<h1>您还没有登录!请先去<a href="$pageContext.request.contextPath/login.jsp">登录</a>!</h1>
<%	
	else
%>
	<h1>用户登录成功!</h1>
<%
	User existUser = (User) request.getSession().getAttribute("existUser");
%>
	<h3>您好:<%= existUser.getUsername()  %> <a href="$pageContext.request.contextPath/LogoutServlet">退出</a></h3>
<%			
	
%>

</body>
</html>

使用了三个Servlet,该部分属于控制层。需要再web.xml文件中配置,具体如下:
 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>CheckImgServlet</servlet-name>
        <servlet-class>servlet.controller.CheckImgServlet</servlet-class>
        </servlet>
    <servlet-mapping>
        <servlet-name>CheckImgServlet</servlet-name>
        <url-pattern>/CheckImgServlet</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>servlet.controller.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/LoginServlet</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>servlet.controller.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/LogoutServlet</url-pattern>
    </servlet-mapping>
</web-app>

使用c3p0连接池获得连接,所以需要在c3p0-config.xml文件中配置mysql参数,如下:

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///web02_login</property>
		<property name="user">root</property>
		<property name="password">123456</property>
		
		<property name="initialPoolSize">5</property>
		<property name="minPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</default-config> 
</c3p0-config>

生成验证图片的Servlet如下:主要是将获得到的字符串验证码存入session对象。

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

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

/**
 * 生成验证码图片
 * 
 * 
 */
public class CheckImgServlet extends HttpServlet 

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException 
		// 禁止缓存
		// response.setHeader("Cache-Control", "no-cache");
		// response.setHeader("Pragma", "no-cache");
		// response.setDateHeader("Expires", -1);

		int width = 120;
		int height = 30;

		// 步骤一 绘制一张内存中图片
		BufferedImage bufferedImage = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);

		// 步骤二 图片绘制背景颜色 ---通过绘图对象
		Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
		// 绘制任何图形之前 都必须指定一个颜色
		graphics.setColor(getRandColor(200, 250));
		graphics.fillRect(0, 0, width, height);

		// 步骤三 绘制边框
		graphics.setColor(Color.WHITE);
		graphics.drawRect(0, 0, width - 1, height - 1);

		// 步骤四 四个随机数字
		Graphics2D graphics2d = (Graphics2D) graphics;
		// 设置输出字体
		graphics2d.setFont(new Font("宋体", Font.BOLD, 18));

		String words =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
		//String words = "\\u7684\\u4e00\\u4e86\\u662f\\u6211\\u4e0d\\u5728\\u4eba\\u4eec\\u6709\\u6765\\u4ed6\\u8fd9\\u4e0a\\u7740\\u4e2a\\u5730\\u5230\\u5927\\u91cc\\u8bf4\\u5c31\\u53bb\\u5b50\\u5f97\\u4e5f\\u548c\\u90a3\\u8981\\u4e0b\\u770b\\u5929\\u65f6\\u8fc7\\u51fa\\u5c0f\\u4e48\\u8d77\\u4f60\\u90fd\\u628a\\u597d\\u8fd8\\u591a\\u6ca1\\u4e3a\\u53c8\\u53ef\\u5bb6\\u5b66\\u53ea\\u4ee5\\u4e3b\\u4f1a\\u6837\\u5e74\\u60f3\\u751f\\u540c\\u8001\\u4e2d\\u5341\\u4ece\\u81ea\\u9762\\u524d\\u5934\\u9053\\u5b83\\u540e\\u7136\\u8d70\\u5f88\\u50cf\\u89c1\\u4e24\\u7528\\u5979\\u56fd\\u52a8\\u8fdb\\u6210\\u56de\\u4ec0\\u8fb9\\u4f5c\\u5bf9\\u5f00\\u800c\\u5df1\\u4e9b\\u73b0\\u5c71\\u6c11\\u5019\\u7ecf\\u53d1\\u5de5\\u5411\\u4e8b\\u547d\\u7ed9\\u957f\\u6c34\\u51e0\\u4e49\\u4e09\\u58f0\\u4e8e\\u9ad8\\u624b\\u77e5\\u7406\\u773c\\u5fd7\\u70b9\\u5fc3\\u6218\\u4e8c\\u95ee\\u4f46\\u8eab\\u65b9\\u5b9e\\u5403\\u505a\\u53eb\\u5f53\\u4f4f\\u542c\\u9769\\u6253\\u5462\\u771f\\u5168\\u624d\\u56db\\u5df2\\u6240\\u654c\\u4e4b\\u6700\\u5149\\u4ea7\\u60c5\\u8def\\u5206\\u603b\\u6761\\u767d\\u8bdd\\u4e1c\\u5e2d\\u6b21\\u4eb2\\u5982\\u88ab\\u82b1\\u53e3\\u653e\\u513f\\u5e38\\u6c14\\u4e94\\u7b2c\\u4f7f\\u5199\\u519b\\u5427\\u6587\\u8fd0\\u518d\\u679c\\u600e\\u5b9a\\u8bb8\\u5feb\\u660e\\u884c\\u56e0\\u522b\\u98de\\u5916\\u6811\\u7269\\u6d3b\\u90e8\\u95e8\\u65e0\\u5f80\\u8239\\u671b\\u65b0\\u5e26\\u961f\\u5148\\u529b\\u5b8c\\u5374\\u7ad9\\u4ee3\\u5458\\u673a\\u66f4\\u4e5d\\u60a8\\u6bcf\\u98ce\\u7ea7\\u8ddf\\u7b11\\u554a\\u5b69\\u4e07\\u5c11\\u76f4\\u610f\\u591c\\u6bd4\\u9636\\u8fde\\u8f66\\u91cd\\u4fbf\\u6597\\u9a6c\\u54ea\\u5316\\u592a\\u6307\\u53d8\\u793e\\u4f3c\\u58eb\\u8005\\u5e72\\u77f3\\u6ee1\\u65e5\\u51b3\\u767e\\u539f\\u62ff\\u7fa4\\u7a76\\u5404\\u516d\\u672c\\u601d\\u89e3\\u7acb\\u6cb3\\u6751\\u516b\\u96be\\u65e9\\u8bba\\u5417\\u6839\\u5171\\u8ba9\\u76f8\\u7814\\u4eca\\u5176\\u4e66\\u5750\\u63a5\\u5e94\\u5173\\u4fe1\\u89c9\\u6b65\\u53cd\\u5904\\u8bb0\\u5c06\\u5343\\u627e\\u4e89\\u9886\\u6216\\u5e08\\u7ed3\\u5757\\u8dd1\\u8c01\\u8349\\u8d8a\\u5b57\\u52a0\\u811a\\u7d27\\u7231\\u7b49\\u4e60\\u9635\\u6015\\u6708\\u9752\\u534a\\u706b\\u6cd5\\u9898\\u5efa\\u8d76\\u4f4d\\u5531\\u6d77\\u4e03\\u5973\\u4efb\\u4ef6\\u611f\\u51c6\\u5f20\\u56e2\\u5c4b\\u79bb\\u8272\\u8138\\u7247\\u79d1\\u5012\\u775b\\u5229\\u4e16\\u521a\\u4e14\\u7531\\u9001\\u5207\\u661f\\u5bfc\\u665a\\u8868\\u591f\\u6574\\u8ba4\\u54cd\\u96ea\\u6d41\\u672a\\u573a\\u8be5\\u5e76\\u5e95\\u6df1\\u523b\\u5e73\\u4f1f\\u5fd9\\u63d0\\u786e\\u8fd1\\u4eae\\u8f7b\\u8bb2\\u519c\\u53e4\\u9ed1\\u544a\\u754c\\u62c9\\u540d\\u5440\\u571f\\u6e05\\u9633\\u7167\\u529e\\u53f2\\u6539\\u5386\\u8f6c\\u753b\\u9020\\u5634\\u6b64\\u6cbb\\u5317\\u5fc5\\u670d\\u96e8\\u7a7f\\u5185\\u8bc6\\u9a8c\\u4f20\\u4e1a\\u83dc\\u722c\\u7761\\u5174\\u5f62\\u91cf\\u54b1\\u89c2\\u82e6\\u4f53\\u4f17\\u901a\\u51b2\\u5408\\u7834\\u53cb\\u5ea6\\u672f\\u996d\\u516c\\u65c1\\u623f\\u6781\\u5357\\u67aa\\u8bfb\\u6c99\\u5c81\\u7ebf\\u91ce\\u575a\\u7a7a\\u6536\\u7b97\\u81f3\\u653f\\u57ce\\u52b3\\u843d\\u94b1\\u7279\\u56f4\\u5f1f\\u80dc\\u6559\\u70ed\\u5c55\\u5305\\u6b4c\\u7c7b\\u6e10\\u5f3a\\u6570\\u4e61\\u547c\\u6027\\u97f3\\u7b54\\u54e5\\u9645\\u65e7\\u795e\\u5ea7\\u7ae0\\u5e2e\\u5566\\u53d7\\u7cfb\\u4ee4\\u8df3\\u975e\\u4f55\\u725b\\u53d6\\u5165\\u5cb8\\u6562\\u6389\\u5ffd\\u79cd\\u88c5\\u9876\\u6025\\u6797\\u505c\\u606f\\u53e5\\u533a\\u8863\\u822c\\u62a5\\u53f6\\u538b\\u6162\\u53d4\\u80cc\\u7ec6";
		Random random = new Random();// 生成随机数

		// 定义一个StringBuffer
		StringBuffer buffer = new StringBuffer();
		// 定义x坐标
		int x = 10;
		for (int i = 0; i < 4; i++) 
			// 随机颜色
			graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
					.nextInt(110), 20 + random.nextInt(110)));
			// 旋转 -30 --- 30度
			int jiaodu = random.nextInt(60) - 30;
			// 换算弧度
			double theta = jiaodu * Math.PI / 180;

			// 生成一个随机数字
			int index = random.nextInt(words.length()); // 生成随机数 0 到 length - 1
			// 获得字母数字
			char c = words.charAt(index);
			
			// 将随机产生的字符存入到字符串中:
			buffer.append(c);
			
			// 将c 输出到图片
			graphics2d.rotate(theta, x, 20);
			graphics2d.drawString(String.valueOf(c), x, 20);
			graphics2d.rotate(-theta, x, 20);
			x += 30;
		
		
		// 将buffer转成字符串对象:
		String checkcode = buffer.toString();
		// 将其存入到session中
		request.getSession().setAttribute("checkcode", checkcode);
		// 步骤五 绘制干扰线
		graphics.setColor(getRandColor(160, 200));
		int x1;
		int x2;
		int y1;
		int y2;
		for (int i = 0; i < 30; i++) 
			x1 = random.nextInt(width);
			x2 = random.nextInt(12);
			y1 = random.nextInt(height);
			y2 = random.nextInt(12);
			graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
		

		// 将上面图片输出到浏览器 ImageIO
		graphics.dispose();// 释放资源
		ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

	


	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException 
		doGet(request, response);
	

	/**
	 * 取其某一范围的color
	 * 
	 * @param fc
	 *            int 范围参数1
	 * @param bc
	 *            int 范围参数2
	 * @return Color
	 */
	private Color getRandColor(int fc, int bc) 
		// 取其随机颜色
		Random random = new Random();
		if (fc > 255) 
			fc = 255;
		
		if (bc > 255) 
			bc = 255;
		
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	


处理登录的Servlet代码:从页面获得用户输入的用户名,密码和验证码。检验用户输入的验证码和session中保存的是否一致,然后校验用户名和密码是否与数据库中的一致,一致,则将用户信息保存到session中,并重定向到登录成功页面。

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;

import servlet.domain.User;
import servlet.model.UserModel;

/**
 * 登录的Servlet的编写
 */
public class LoginServlet extends HttpServlet 

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		try
			// 1.接收数据
			// 处理中文乱码
			request.setCharacterEncoding("UTF-8");
			String username = request.getParameter("username");
			String password = request.getParameter("password");
			// 一次性验证码的校验
			// 接收验证码
			String checkcode1 = request.getParameter("checkcode");
			// 从session中获取一次性验证码的值:
			String checkcode2 = (String) request.getSession().getAttribute("checkcode");
			// 为了保证验证码使用一次:应该将session中的验证码值清空
			request.getSession().removeAttribute("checkcode");
			// 校验一次性验证码:
			if(!checkcode1.equalsIgnoreCase(checkcode2))
				request.setAttribute("msg", "验证码输入错误!");
				request.getRequestDispatcher("/login.jsp").forward(request, response);
				return;
			
			
			// 2.封装数据
			User user = new User();
			user.setUsername(username);
			user.setPassword(password);
			// 3.处理数据
			UserModel userModel = new UserModel();
			User existUser = userModel.login(user);
			// 4.页面跳转
			if(existUser == null)
				// 登录失败
				// 向request域中保存一个错误信息:
				request.setAttribute("msg", "用户名或密码错误!");
				// 使用请求转发进行页面跳转
				request.getRequestDispatcher("/login.jsp").forward(request, response);
			else
				// 登录成功
				// 保存用户的信息:保存到会话当中。
				HttpSession session = request.getSession();
				// 保存数据:
				session.setAttribute("existUser", existUser);
				// 记住用户名:
				// 判断复选框是否已经勾选了:
				String remember = request.getParameter("remember");
				if("true".equals(remember))
					// 已经勾选了:
					Cookie cookie = new Cookie("remember",existUser.getUsername());
					// 设置有效路径:
					cookie.setPath("/servlet_war_exploded");
					// 设置有效时长:
					cookie.setMaxAge(60*60*24);
					// 将Cookie回写到浏览器
					response.addCookie(cookie);
				
				// 重定向到成功页面
				response.sendRedirect("/servlet_war_exploded/success.jsp");
			
		catch(Exception e)
			e.printStackTrace();
			throw new RuntimeException();
		
	

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


退出的servlet,销毁session,重定向到登录成功页面,不过在页面处理显示尚未登录,因为session对象为空,没有用户信息。

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

/**
 * 系统退出的Servlet
 */
public class LogoutServlet extends HttpServlet 

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
		// 销毁session:
		request.getSession().invalidate();
		// 页面跳转
		response.sendRedirect("/servlet_war_exploded/success.jsp");
	

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


用于封装数据的javaBean,属于模型层,如下:

/**
 * 用于封装数据的JavaBean
 *
 */
public class User 
	private Integer uid;
	private String username;
	private String password;
	private String nickname;
	public Integer getUid() 
		return uid;
	
	public void setUid(Integer uid) 
		this.uid = uid;
	
	public String getUsername() 
		return username;
	
	public void setUsername(String username) 
		this.username = username;
	
	public String getPassword() 
		return password;
	
	public void setPassword(String password) 
		this.password = password;
	
	public String getNickname() 
		return nickname;
	
	public void setNickname(String nickname) 
		this.nickname = nickname;
	
	

对用户数据进行处理,查询输入的用户名和密码在数据库中是否村早,属于属于模型层。


import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import servlet.domain.User;
import servlet.utils.JDBCUtils;

public class UserModel 
	
	public User login(User user) throws SQLException 
		// 连接数据库:通过传入的用户名和密码去数据库中进行查询
		QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
		User existUser = queryRunner.query("select * from user where username = ? and password = ?",
				new BeanHandler<User>(User.class), user.getUsername(), user.getPassword());
		return existUser;
	


对于连接数据库进行查询的时候,获得连接池,使用了工具类,具体如下:


import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCUtils 
	// 创建一个连接池:但是这个连接池只需要创建一次即可。
	private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
	
	/**
	 * 获得连接的方法
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws SQLException
		return dataSource.getConnection();
	
	
	/**
	 * 获得连接池:
	 */
	public static DataSource getDataSource()
		return dataSource;
	
	

以上是关于JavaWeb开发之Cookie&Session的主要内容,如果未能解决你的问题,请参考以下文章

03-JavaWeb开发最详细的Cookie&Session分析

2Python全栈之路系列之Tornado的Cookie与Sess

javaweb-cookie&session(未处理)

JAVAWEB开发之JSPEL及会话技术(Cookie和Session)的使用详解

JavaWeb从零到一会话技术Cookie&Session&JSP

Cookie&Session