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的出现就是为了 ...
随机推荐
- Win10开启“上帝模式”
win10的上帝模式就是win10的全部功能展示模式,因为功能太强大,所以被戏称为"上帝模式".要开启win10的上帝模式,需要按下面的步骤来操作:1.在window桌面新建一个普 ...
- LINUX 笔记-wc命令
命令参数: -c 统计字节数. -l 统计行数. -m 统计字符数.这个标志不能与 -c 标志一起使用. -w 统计字数.一个字被定义为由空白.跳格或换行字符分隔的字符串.
- Tomcat 笔记-配置虚拟目录
,默认情况下,只有webapps下的目录才能被Tomcat自动管理成一个web站点,把web站点的目录分散到其他磁盘管理就需要配置虚拟目录.把web应用所在目录交给web服务器管理,这个过程称之为虚拟 ...
- OSW 快速安装部署
关于在运行Oracle的环境下部署OSW具体好处不再多说,只需要知晓,在日常Oracle定位各类故障,osw的数据可以协助诊断问题.MOS很多文档也多处提到需要osw的监控数据. 一.前期资料准备 1 ...
- struts2国际化相关问题
国际化资源文件的方式: Action范围的 包范围的 临时的 全局的(推荐) 一.配置全局的国际化资源文件 1.在类路径下,创建国际化资源文件 baseName.properties baseName ...
- 主键乱序插入对Innodb性能的影响
主键乱序插入对Innodb性能的影响 在平时的mysql文档学习中我们经常会看到这么一句话: MySQL tries to leave space so that future inserts do ...
- vue之地址栏#号问题
mode的两个值 histroy:当你使用 history 模式时,URL 就像正常的 url,例如 http://jsapng.com/lms/,也好看! hash:默认'hash'值,但是hash ...
- [C#]使用ILMerge将源DLL合并到目标EXE(.NET4.6.2)
本文为原创文章,如转载,请在网页明显位置标明原文名称.作者及网址,谢谢! 本文主要是使用微软的ILMerge工具将源DLL合并到目标EXE,因此,需要下载以下工具: https://www.micro ...
- openCV中直方图均衡化算法的理解
直方图均衡化就是调整灰度直方图的分布,即将原图中的灰度值映射为一个新的值.映射的结果直观表现是灰度图的分布变得均匀,从0到255都有分布,不像原图那样集中.图像上的表现就是对比度变大,亮的更亮,暗的更 ...
- gops - Go语言程序查看和诊断工具
想必 Java 的开发者没有不知道或者没用过 jps 这个命令的,这个命令是用来在主机上查看有哪些 Java 程序在运行的. 我刚用 Go 语言程序的时候也很苦恼,我部署在公司服务器上的 Go 程序, ...