Session、Cookie 学习笔记
在开始今天的博文之前首先为自己庆祝一下自己有了三个粉丝,也有了同僚的评论,说实话因为这个开心了好久!哈哈,好了在开始今天的正题之前,首先大家需要了解以下几点:
a. HTTP 协议是无状态的协议,WEB 服务器本身不能识别出哪些请求是同一个浏览器发出的,浏览器的每一次请求都是孤立的;
b. 作为服务器必须能够采用一种机制来唯一标识一个用户,同时记录该用户的状态;
c. WEB 应用中的会话是指一个客户端浏览器与 WEB 服务器之间连续发生的一系列请求和响应过程;
d. WEB 应用的会话状态是指 WEB 服务器与浏览器会话过程中产生的状态信息,借助会话状态 WEB 服务器能够把属于同一会话中的一系列的请求和响应过程关联起来;
e. Cookie 机制采用的是在客户端保持 HTTP 状态信息的方案,在浏览器访问 WEB 服务器的某个资源时,由 WEB 服务器在 HTTP 响应消息头中附带传送给浏览器的一个小文本文件,一旦WEB 浏览器保存了某个 Cookie,那么他在以 后每次访问该 WEB 服务器时,都会在 HTTP 请求头中将这个 Cookie 回传给 WEB 服务器
1. Cookie
1). 实现原理:WEB 服务器通过在 HTTP 响应头消息中增加 Set-Cookie 响应头字段将 Cookie 消息发送给浏览器,浏览器则通过在 HTTP 请求消息中增加 Cookie 请求头字段将 Cookie 回传给 WEB 服务器
2). 第一次访问浏览器不存在 Cookie,服务器给浏览器响应时给其加上 Cookie,第二次请求的时候便会自动加上 Cookie,服务器便会根据此 cookie 信息辨别用户状态,以弥补 HTTP 协议的无状态缺点
1.1 Cookie 应用实例之用户的自动登录
a. 用户登录后会跳转到一个欢迎页面,一段时间之内我们再次访问欢迎页面时可以不用登录,但是过了 Cookie 的保质期我们访问欢迎页面的时候就需要去登录
b. 首先我们写一个登录页面,然后提交请求到 servlet,在 servlet 中判断 cookie 中是否有值,若没有值可能是 cookie 失效,可能是第一次访问,然后将用户登录信息保存到 cookie 中;若有值则去判断该 cookie 中是否有匹配的 cookie,若有则显示欢迎页面,否则回到登录页面(登录页面中只有用户名,没有密码,在实际中我们对密码需要进行加密处理),演示如下:

e. 代码如下(我们在 JSP 中模仿 Servlet,没有单独去新建 Servlet):
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="welcom.jsp" method="post">
UserName: <input type="text" name="name"><br>
<button type="submit">Submit</button>
</form>
</body>
</html>
welcom.jsp
<%--
Created by IntelliJ IDEA.
User: yin‘zhao
Date: 2017/11/15
Time: 9:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Welcom</title>
</head>
<body>
<h3>
<%
/*
* 获取用户名和cookie,如果用户名不为空(从登录页面而来)则打印欢迎消息
* 如果用户名为空但cookie 不为空,且cookie 的name 为所要求的同样打印欢迎消息
* 如果都为空则重定向到登录页面
* */ String userName = request.getParameter("name");
if (userName != null) {
Cookie cookie1 = new Cookie("name", userName);
cookie1.setMaxAge(30);
response.addCookie(cookie1);
} else {
// 获取所有的 Cookie
Cookie[] cookies2 = request.getCookies();
if (cookies2 != null && cookies2.length > 0) {
for (Cookie cookie : cookies2) {
// 寻找相匹配的 Cookie
if (cookie.getName().equals("name")) {
// 使得 userName 为所匹配的 Cookie 的值
userName = cookie.getValue();
}
}
}
} if (userName != "" && userName != null) {
// 打印欢迎消息
out.print("Hello" + userName);
} else {
// 如果用户名为空则重定向到登录页面
response.sendRedirect("login.jsp");
}
%>
</h3>
</body>
</html>
1.2 显示最近浏览记录(只显示 5 条)
a. 在显示页面显示出商品清单,点击商品后转到详情页面,然后再次返回到页面此商品将会显示到历史记录中
b. 如果所浏览的是以前所浏览过的那么就需要将此商品更新到最新的记录中,即最后一个,演示如下

代码如下(依旧使用 jsp 模仿 servlet)
<%--
Created by IntelliJ IDEA.
User: yin‘zhao
Date: 2017/11/15
Time: 8:59
To change this template use File | Settings | File Templates.
--%>
<%--
从 Cookie 中获取书的信息并显示,如果 Cookie 的 name 是以 book 开始的就将其显示到页面
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Cookie</title>
</head>
<body>
<a href="book.jsp?book=javaWeb">JavaWeb</a><br>
<a href="book.jsp?book=Java">Java</a><br>
<a href="book.jsp?book=Oracle">Oracle</a><br>
<a href="book.jsp?book=Mysql">Mysql</a><br>
<a href="book.jsp?book=JDBC">JDBC</a><br>
<a href="book.jsp?book=C">C</a><br>
<a href="book.jsp?book=R">R</a><br>
<a href="book.jsp?book=Hibernate">Hibernate</a><br>
<a href="book.jsp?book=Ajax">Ajax</a><br>
<a href="book.jsp?book=Spring">Spring</a><br> <h2>
<%
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().startsWith("book")) {
out.print(cookie.getValue() + "<br>");
}
}
%>
</h2>
</body>
</html>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%--
把书的信息以 Cookie 传回浏览器,如果以 book 开头的 cookie name 属性大于 5, 那么删除一个,如果新来的book
已经存在,那么将其放到最后,如果不存在则删除第一个
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Book</title>
</head>
<body>
<h3>
<%
String bookName = request.getParameter("book");
// 存储相同的 Cookie
Cookie tempCookie = null;
// 获得所有的 Cookie
Cookie[] cookies = request.getCookies();
// 存储Cookie 的 name 属性以 book 开头的并存储在 List 中
List<Cookie> cookieList = new ArrayList<Cookie>(); // 遍历所有的 Cookie,将所有以 book 开头的存储在 List 中,并为 tempCookie 赋值
for (Cookie cookie1 : cookies) {
if (cookie1.getName().startsWith("book")) {
cookieList.add(cookie1);
if (cookie1.getValue().equals(bookName)) {
tempCookie = cookie1;
}
}
} System.out.println(tempCookie); // 如果 List 的 size 大于等于 5,且不存在相同的 Cookie 那么就删除第一个
// 要知道加入新的一个要么全部不相同且大于 5 删除第一个,要么存在相同的删除相同的
// 心得: 最后就是总删除一个,所以我们可以把删除的那个单独为其赋值
if (cookieList.size() > 5 && tempCookie == null) {
tempCookie = cookieList.get(0);
}
if (tempCookie != null) {
tempCookie.setMaxAge(0);
// 另一个不足为提的错误是没有将设置过的Cookie加入到Response中,因为服务器端设置了Cookie,客户端,
// 也就是浏览器是不知道的,所以对Cookie的所有修改都需要调用Response的addCookie方法给客户端响应,“存”回浏览器,这样,浏览器才会更改Cookie 集合
response.addCookie(tempCookie);
} // 获取调用 Servlet 的 Path, 但 JSP 底层就是一个 Servlet,所以会打印文件名
// out.print(request.getServletPath());
// 将新传入的 cookie 返回
Cookie cookie = new Cookie("book" + bookName, bookName);
response.addCookie(cookie);
%>
</h3>
<h3><%=bookName%>
</h3>
<a href="index.jsp">Return...</a>
</body>
</html>
以上便是我所对 cookie 的理解和自己练习的小应用,接下来我们开始讲解 session
2. session
1). Session 在 WEB 开发环境下的语义是指一类用来在客户端与服务器端之间保持状态的解决方法,有时候 Session 也用来指这中解决方案的存储结构
2). 如果浏览器发一个 session 并没有带任何标识,服务器便会新建一个 session 对象,服务器返回响应的时候会以 cookie的方式返回标识头(JSessionId),下一次请求 cookie 会把这个标识 id 带回去,就会找到指定的 session,只要浏览器不关就会一直在 cookie存取数据
3). Session 通过 sessionId 来区分不同的客户,session以cookie 或 URL 重写为基
4). 础在程序中可以设置 cookie(JSESSIONID)的持久化,保证重启浏览器的不会重新发送
5). HttpSession 的生命周期之创建 Session
a. 浏览器访问服务端的任何一个 JSP,服务器不一定会立即创建一个 HttpSession 对象
b. 若当前 JSP 是浏览器访问当前 WEB 资源的第一个资源且 JSP 的 page 指令的 session 设为 false,那么服务器就不会为 JSP 创建一个 HttpSession 对象(Page 指令的 session 属性为 false 是指 JSP 页面的隐含变量不可用,但可以通过显示的方法去创建。)
c. 若当前 JSP 不是客户端访问的第一个,且其他页面已经创建了一个 HttpSession’ 对象,则服务器也不会为当前 JSP 页面创建一个 HttpSession 对象, 而会把和当前页面会话关联的那个 HttpSession 对象返回
d. 对于 Servlet 若是第一个访问的资源,则只有调用了 request.getSession 或 request。getSession(true) 才会创建一个对象
6). HttpSession 的生命周期之销毁 session
a. 超出 HttpSession 的过期时间,调用 session.setMaxInactiveInterval(5) 设置失效时间,单位为秒
b. 服务器调用 sesion.invalidate() 方法,
c. 服务器卸载了当前 WEB 应用
7). Servlet 中如何获取 HttpSession 对象
a. request.getsession(boolean) boolean 为false ,表示若没有和当前JSP 页面关联的 HttpSession则返回 null,若有则返回对象;为 true 表示一定返回,若没有关联页面则服务器创建一个,此时的 true 可省略
8). Session 应用案例之购物车
a. 用户选择所要购买的商品,并填写订单信息后在购买页面显示用户所要购买的物品信息和用户信息(由于是多个请求跨页面,所以我们不能将信息存到 request 中)
b. 代码如下(以下是我自己所写的代码,有点烦琐,代码注释中有自己写代码过程中所犯的错误和更好的解决方案,我这里就不贴出留给有兴趣的自己去实践):
index.jsp(由于此案例并不是一个请求所以我们再次利用反射使得所有请求利用一个 Servlet 和之前所用到的一样)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>FirstPage</title>
</head>
<body>
<h3>请选择你要购买的书籍</h3>
<table cellpadding="10">
<form action="books.do" method="post">
<tr>
<th>书名</th>
<th>购买</th>
</tr>
<tr>
<td>Oracle</td>
<td><input type="checkbox" name="book" value="Oracle"></td>
</tr>
<tr>
<td>Spring</td>
<td><input type="checkbox" name="book" value="Spring"></td>
</tr>
<tr>
<td>Mysql</td>
<td><input type="checkbox" name="book" value="Mysql"></td>
</tr>
<tr>
<td>SqlServer</td>
<td><input type="checkbox" name="book" value="SqlServer"></td>
</tr>
<tr><td>
<button type="submit">Submit</button>
</td></tr>
</form>
</table>
</body>
</html>
books 方法
protected void books(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String[] values = request.getParameterValues("book");
for (String value : values) {
session.setAttribute("book" + value, value);
}
response.sendRedirect("buyBook.jsp");
}
buyBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>BuyBooks</title>
</head>
<body>
<h3>请输入您的基本信息</h3>
<table cellpadding="10">
<form action="buyBook.do" method="post">
<tr>
<td>基本信息</td>
</tr>
<tr>
<td>UserName: </td>
<td><input type="text" name="userName"></td>
</tr>
<tr>
<td>Address: </td>
<td><input type="text" name="address"></td>
</tr>
<tr>
<td>CardNum: </td>
<td><input type="text" name="cardNum"></td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</form>
</table>
</body>
</html>
buyBook 方法
protected void buyBook(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Enumeration<String> enumeration = request.getParameterNames();
while(enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
session.setAttribute("buy" + name, request.getParameter(name));
}
response.sendRedirect("SubmitOrder.jsp");
}
SubmitOrder.jsp
<%@ page import="java.util.Enumeration" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: yin‘zhao
Date: 2017/11/16
Time: 18:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SubmitOrder</title>
</head>
<body>
<h3>订单信息确认</h3>
<h4><%
Enumeration<String> enumeration = session.getAttributeNames();
List<String> bookList = new ArrayList<String>();
String userName = null;
String address = null;
String cardNum = null; while (enumeration.hasMoreElements()) {
String atrName = enumeration.nextElement();
if (atrName.startsWith("book")) {
String atrVal = (String) session.getAttribute(atrName);
bookList.add(atrVal);
} if (atrName.startsWith("buyuser")) {
String atrVal = (String) session.getAttribute(atrName);
userName = atrVal;
}
if (atrName.startsWith("buyadd")) {
String atrVal = (String) session.getAttribute(atrName);
address = atrVal;
}
if (atrName.startsWith("buycard")) {
String atrVal = (String) session.getAttribute(atrName);
cardNum = atrVal;
}
}
%></h4>
<table cellpadding="10" border="1" cellspacing="0">
<tr>
<td>UserName</td>
<td><%= userName%>
</td>
</tr>
<tr>
<td>Address</td>
<td><%= address%>
</td>
</tr>
<tr>
<td>CardNum</td>
<td><%= cardNum%>
</td>
</tr>
<tr>
<td>购买项目</td>
<td>
<%
for (String bookName : bookList) {
%>
<%= bookName %>
<%= "<br><br>"%>
<%
}
%>
</td>
</tr>
</table>
</body>
</html>
完整 servlet 代码以及自己的错误和不足
package com.java.session.cart.servlet; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List; /**
* 小结:
* 1. 首先对于多选框他们的 name 属性应该一致,获取其值的时候直接 getParameterValues(name) 返回一个数组
* 将获得的值直接加入 session 中,不用分开加;
* 2. 对于第二个页面的多个属性应该考虑到将其封装为一个类,比如 Customer,然后为 session 赋值的时候
* 直接用 getParameter(name) 获取到,将他们初始化为 customer 对象,将 customer 对象加入 session
* 属性
* 3. 第三个页面获取 session 属性的时候就可以直接获取 customer 对象和第一步的数组,并将其写到页面
*
* 我的错误:
* 对于多选框的没有将其 name 属性设置为一样的;
* 使用 getParameterNames() 方法,误导自己后面只知道使用 getParameterNames() 方法,很不好;
* 没有很好的用到面向对象的编程思想;
*/
public class CartServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String servletPath = request.getServletPath();
String methodName = servletPath.substring(1).substring(0, servletPath.length() - 4); try {
Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this, request, response);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void books(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String[] values = request.getParameterValues("book"); for (String value : values) {
session.setAttribute("book" + value, value);
}
response.sendRedirect("buyBook.jsp");
} protected void buyBook(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Enumeration<String> enumeration = request.getParameterNames(); while(enumeration.hasMoreElements()) {
String name = enumeration.nextElement();
session.setAttribute("buy" + name, request.getParameter(name));
} response.sendRedirect("SubmitOrder.jsp");
}
}
9). session 典型案例之解决重复提交问题
a. 什么是重复提交
1). 在表单提交到一个 servlet,而 servlet 又通过请求转发的方式响应一个 jsp 页面,此时地址栏里面还保留着 servlet 的路径。在响应页面点击 “刷新”
2). 在响应页面没有到达时重复点击 “提交按钮”
3). 点击返回再点击提交,也算是重复提交
b. 如何避免重复提交
1). 在表单中做一个标记,提交到 Servlet 时,检查标记是否存在且是否和预定义的一致,若一致则受理,并销毁,若不一致或没有标记则响应消息重复提交
代码如下:
index.jsp
<%@ page import="java.util.Date" %><%--
Created by IntelliJ IDEA.
User: yin‘zhao
Date: 2017/11/20
Time: 14:51
To change this template use File | Settings | File Templates.
--%>
<%--
在此页面将 token 值存储在隐藏域和 session 属性中,提交到 servlet 并在 servlet 中校验,且校验成功,然后
成功页面返回再提交,由于有缓存,java 代码将不会执行,所以 session 属性域中就不会有值,所以就会出错
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>LoginPage</title>
</head>
<body>
<h4><%
/*随表单一块提交的标识*/
String tokenValue = String.valueOf(new Date().getTime());
/*将此标识存入 session 中*/
session.setAttribute("token", tokenValue);
%></h4>
<form action="<%=request.getContextPath()%>/tokenServlet" method="post">
<%--将标识放入隐藏表单中,随表单一块提交到 servlet,在 servlet 中和 session 域中的标识进行比较 --%>
<input type="hidden" name="token" value=<%=tokenValue%>>
name: <input type="text" name="name"><br><br>
<button type="submit">Submit</button>
</form>
</body>
</html>
TokenServet.java
package com.java.token.servlet; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; /*
* 从登录页面到这里提交,校验是否为重复提交,若是则给出错误页面,若不是则给出正确的响应页面。
* */
public class TokenServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String tokenValue = request.getParameter("token");
String attribute = String.valueOf(session.getAttribute("token")); if (tokenValue != null && tokenValue.equals(attribute)) {
// 如果标识一直将其移除,并转发到成功页面
session.removeAttribute("token");
} else {
// 若不一致或不存在结束当前方法并重定向到错误页面
response.sendRedirect(request.getContextPath() + "/token.jsp");
return;
} request.getRequestDispatcher("/success.jsp").forward(request, response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
success.jsp
<%--
Created by IntelliJ IDEA.
User: yin‘zhao
Date: 2017/11/20
Time: 16:35
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Success</title>
</head>
<body> <h3>Hello <%= request.getParameter("name")%></h3>
</body>
</html>
10). 利用 session 完成验证码功能
a. 在原表单页面,生成一个验证码图片,生成图片的同时将其字符放入到 session 中;
b. 在原表单页面,定义一个文本域,用于输入验证码
c. 在目标 servlet 中,获取 session 和表单域中的验证码值
d. 比较两个值是否一致,若一致则受理请求,并井session 属性清除
e. 若不一致,则直接通过重定向的方式返回原表单页面,并提示用户“验证码错误”
1). 演示如下

2). 代码如下
ValidateColorServlet.java(用于生成验证码,该 Servlet 算是难点吧,其余代码逻辑和前面的案例差不多)
package com.java.token.servlet; import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random; /**
* 产生随机验证码
*/
public class ValidateColorServlet extends HttpServlet { // 定义验证图片的宽和高,以及验证图片中字符数
private int width = 152;
private int height = 40;
private int codeCount = 6; // 验证字符的高度
private int fontHeight = 0; // 验证码中单个字符基线,即:验证码中的单个字符位于验证码图形左上角的 (codeX, codeY)位置处
private int codeX = 0;
private int codeY = 0; // 验证码由哪些字符组成
char[] codeSequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz23456789".toCharArray(); // 初始化验证码图形属性
public void init() {
fontHeight = height - 2;
codeX = width / (codeCount + 2);
codeY = height - 4;
} public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 定义一个类型为 BufferedImage.TYPE_INT_BGR 类型的图像缓存
BufferedImage buffImg;
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); // 在 buffImg 中创建一个 Graphics2D 图像
Graphics2D graphics2D = buffImg.createGraphics(); // 设置一个颜色,是 graphics2D 后续使用这个颜色
graphics2D.setColor(Color.white);
// 填充一个指定的矩形,x - 要填充矩形的 x 坐标,y - 要填充矩形的 y 坐标,width 要填充矩形的宽,height - 要填充矩形的高
graphics2D.fillRect(0, 0, width, height);
// 创建一个 font 对象,name 字体名称,style font 的样式常量,size font的点大小
Font font = new Font("", 1, fontHeight);
// Graphics2D 使用此字体
graphics2D.setFont(font); graphics2D.setColor(Color.black); // 绘制指定矩形矩形的边框,比构建宽和高大一个像素
graphics2D.drawRect(0, 0, width - 1, height - 1); // 产生干扰线
Random random = new Random();
graphics2D.setColor(Color.cyan); for (int i = 0; i < 55; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(20);
int y1 = random.nextInt(20);
graphics2D.drawLine(x, y, x + x1, y + y1);
}
// 创建 StringBuffer 对象,保存随机产生的验证码
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < codeCount; i++) {
String randCode = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
// 把随机数放入到 StringBuffer
stringBuffer.append(randCode); // 将字符绘制到图像
graphics2D.setColor(Color.PINK);
graphics2D.drawString(randCode, (i + 1) * codeX, codeY);
} // 将 StringBuffer 存入 session 中
request.getSession().setAttribute("CHECK_CODE_KEY", stringBuffer.toString()); // 禁止图像缓存
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 将图像输出到输出流中
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(buffImg, "jpeg", sos);
sos.close();
}
}
login.jsp
<%--
Created by IntelliJ IDEA.
User: yin‘zhao
Date: 2017/11/20
Time: 18:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<h3><%
String message = String.valueOf(session.getAttribute("message"));
if (message.equals("null")) {
message = "";
}
out.print(message);
%></h3>
<form action="<%=request.getContextPath()%>/checkCodeServlet" method="post">
Name: <input type="text" name="name"><br><br>
Code: <input type="text" name="CHECK_CODE_KEY"><br><br>
<img src="<%=request.getContextPath()%>/validateColorServlet"><br><br>
<button type="submit">Submit</button>
</form>
</body>
</html>
CheckCodeServlet.java
package com.java.token.servlet; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; /**
* Created by shkstart on 2017/11/20.
*/
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String sessionAttr = String.valueOf(session.getAttribute("CHECK_CODE_KEY"));
System.out.println(sessionAttr);
String nameValue = request.getParameter("CHECK_CODE_KEY"); if (nameValue != null && nameValue.equalsIgnoreCase(sessionAttr)) {
session.removeAttribute("CHECK_CODE_KEY");
} else {
session.setAttribute("message", "验证码错误");
System.out.println(sessionAttr);
response.sendRedirect(request.getContextPath() + "/checkCode/login.jsp");
return;
} request.getRequestDispatcher("/checkCode/success.jsp").forward(request, response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
success.jsp
<%--
Created by IntelliJ IDEA.
User: yin‘zhao
Date: 2017/11/20
Time: 18:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Success</title>
</head>
<body>
<h3>Hello <%= request.getParameter("name")%></h3>
</body>
</html>
这些是我前面因为一些事耽搁没写的内容,这次补上,有错误或者歧义的地方还望大家指出,谢谢!
本周的内容将会尽快补上,还望谅解!
Session、Cookie 学习笔记的更多相关文章
- 会话控制:cookie和session基础学习笔记
在多次HTTP连接间维护用户与同一用户发出的不同请求之间关联的情况称为维护一个会话(session) 我们可以简单理解为浏览器的开关. 其实对cookie和session也是主要为curd操作 coo ...
- Cookie学习笔记二:Cookie实例
今天说说刚刚学到的两个Cookie的最经典应用:自己主动登录和购物车设置 一:自己主动登录 须要两个页面:login.jsp与index.jsp,login.jsp用来输出登录信息,index.jsp ...
- 【转载】HTTP Cookie学习笔记
什么是cookie? cookie是什么?是饼干,小甜点? No! No! No! 我今天要总结的cookie并不是你所想的小甜心,我这里要说的cookie是Web开发中的一个重要的"武器& ...
- Cookie学习笔记
1.简介 1.什么是cookie:cookie是一种能够让网站服务器把少量数据(4kb左右)存储到客户端的硬盘或内存.并且读可以取出来的一种技术. 2.当你浏览某网站时,由web服务器放置于你硬盘上的 ...
- JavaWeb学习笔记总结 目录篇
JavaWeb学习笔记一: XML解析 JavaWeb学习笔记二 Http协议和Tomcat服务器 JavaWeb学习笔记三 Servlet JavaWeb学习笔记四 request&resp ...
- Redis学习笔记~目录
回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...
- JavaWeb学习笔记(六)—— Cookie&Session
一.会话技术简介 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程 ...
- python 学习笔记十九 django深入学习四 cookie,session
缓存 一个动态网站的基本权衡点就是,它是动态的. 每次用户请求一个页面,Web服务器将进行所有涵盖数据库查询到模版渲染到业务逻辑的请求,用来创建浏览者需要的页面.当程序访问量大时,耗时必然会更加明显, ...
- Django学习笔记之URL与视图cookie和session
cookie和session cookie:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了 ...
随机推荐
- Linux下简单C语言小程序的反汇编分析
韩洋原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 写在开始,本文为因为参加MOO ...
- C 指针的几个注意点
1.静态指针在初始化时必须使用编译时可以确定地址表达式完成赋值,如 static int a; static int* pa = &a;//初始化时必须使用可以确定地址的表达式 int b; ...
- 阿里JAVA开发手册零度的思考理解(一)
转载请注明原创出处,谢谢! 缘由 阿里JAVA开发手册已经发表有很长时间了,值得认真研究思考推广 阿里官方的Java代码规范标准,这份开发手册不仅规范了一些开发细节,也提出了很多工程开发的哲学,值得好 ...
- SpringBoot的几个使用技巧
SpringBoot的几个使用技巧 首先提供几个SpringBoot开发过程中常用的网站: Spring Boot官方文档:http://docs.spring.io/spring-boot/docs ...
- LeetCode 532. K-diff Pairs in an Array (在数组中相差k的配对)
Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in t ...
- 从零起步学python计划及感想
从纯传统bi转型过来的技术顾问,比较有优势的是对业务的熟悉,对数据有敏感度,熟悉数据模型.但是长年累月基本都是用sql处理问题.目前还没有经历过sql解决不了的问题,一个sql解决不了就用临时表,几个 ...
- Akka(34): Http:Unmarshalling,from Json
Unmarshalling是Akka-http内把网上可传输格式的数据转变成程序高级结构话数据的过程,比如把Json数据转换成某个自定义类型的实例.按具体流程来说就是先把Json转换成可传输格式数据如 ...
- 通过 ODBC 访问数据库获取数据集
Step1:(window 中完成): 控制面板/管理工具/ODBC 数据源/用户 Step2:(window 中完成): 添加/SQL Server Step3:(window 中完成): 自己定义 ...
- Vue.js之render函数基础
刚才翻了一下博客,才发现,距离自己写的第一篇Vue的博客vue.js之绑定class和style(2016-10-30)已经过去一年零两天.这一年里,自己从船厂的普通技术员,成为了一个微型不靠谱创业公 ...
- Day1作业-模拟登录
# /usr/bin/env python# -*- coding: utf-8 -*-# Author:jenvid.yangimport getpassimport shutiluserspwd ...