一、含义
1.1 含义
是Web服务器保存在客户端的一系列文本信息。
1.2 作用
(1)对特定对象的追踪。如“购物车”的处理。
(2)保存用户网页记录与习惯。如浏览网站历史。
(3)简化登录。如用户登录“记住密码”功能。
缺点:安全性低。容易泄露用户信息。
1.3 常用方法
常用方法 | 作用 | 返回值 |
---|---|---|
getName() | 获取cookie的名称,名称创建后将不能被修改 | String |
getValue() | 获取cookie的值 | String |
setValue() | cookie创建后,给cookie赋值 | void |
setMaxAge() | 设置cookie的有效期。秒。 | void |
getMaxAge() | 获取cookie的有效期。秒。 | int |
setDomain(String pattern) | 设置cookie域名,如 zhangsan.com | void |
getDomain() | 获取cookie域名,比如 zhangsan.com | String |
setPath(String uri) | 设置cookie 的URL,默认为当前URL+子目录 | void |
getPath() | 获取cookie 的URL | String |
setSecure(boolean flag) | cookie是否要加密传输 | void |
setComment(String purpose) | 设置cookie注释。 | void |
getComment() | 获取cookie注释。 | String |
1.4 语法
1.4.1 创建cookie对象。
Cookie newCookie = new Cookie(String key,Object value);
1.4.2 写入cookie对象。
读取:指写入到响应中。
response.addCookie(newCookie);
1.4.3 读取cookie对象
读取:指从请求中读取。
Cookie[] cookies = request.getCookie();
1.5 中文乱码(Cookie)
1.5.1 写入时——URLEncoding.encode(str,“utf-8”)
request.setCharacterEncoding("utf-8");
String username = URLEncoder.encode(request.getParameter("username"),"utf-8");
Cookie usernameCookie = new Cookie("username",username);
1.5.2 读取时——URLDecoder.decode(str,“utf-8”)
request.setCharacterEncoding("utf-8");
Cookie[] cookies = request.getCookies();
username = URLDecoder.decode(cookies[i].getValue(),"utf-8");
二、Session与Cookie的对比
用户信息 | session | cookie |
---|---|---|
保存位置 | 服务器端 | 客户端 |
保存类型 | Object类型 | String类型 |
销毁时间 | 会话结束 | 可长期保存 |
重要性 | 重要 | 不重要 |
存储共同点 | 键值对 | 键值对 |
三、在JSP中使用cookie——项目
3.1 用户登录
需求:实现记住用户名和密码功能。
3.1.1 登录页面
步骤:
1、获取请求中的所有Cookie集合。
Cookie[] cookies = request.getCookies();
2、遍历Cookie集合。查询是否有cookie的键名为“username”或“password”的cookie。
for (Cookie c : cookies) {
if (c.getName().equals("username")) {
username = URLDecoder.decode(c.getValue(),"utf-8");
}
if (c.getName().equals("password")) {
password = URLDecoder.decode(c.getValue(),"utf-8");
}
}
3、若有,则获取对应的cookie值并赋值给相应的变量。
username = URLDecoder.decode(c.getValue(),"utf-8");
4、使用键值。
<td><input type="text" name="username" value="<%=username %>"/></td>
login.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ page import="java.net.*" %>
<!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>用户登录</title>
</head>
<body>
<div id="container">
<div class="logo">
<a href="#"><img src="#" alt="" /></a>
</div>
</div>
<div id="box">
<%
// 设置请求体中的编码为utf-8。
request.setCharacterEncoding("utf-8");
String username = "";
String password = "";
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie c : cookies) {
// 寻找cookie中是否已经保存过该用户。
if (c.getName().equals("username")) {
username = URLDecoder.decode(c.getValue(),"utf-8");
}
if (c.getName().equals("password")) {
password = URLDecoder.decode(c.getValue(),"utf-8");
}
}
}
%>
<form name="loginForm" action="dologin.jsp" method="get">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" value="<%=username %>"/></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" value="<%=password %>"/></td>
</tr>
<tr>
<td colspan="2"><input type="checkbox" name="isUseCookie"
value="read" />记住用户名和密码功能10天。</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="提交" /></td>
</tr>
</table>
</form>
</div>
</body>
</html>
3.1.2 登录成功页面
步骤:
1、获取请求中的参数值。
String username = URLEncoder.encode(request.getParameter("username"),"utf-8");
2、创建cookie对象,放入参数及参数值。
Cookie usernameCookie = new Cookie("username",username);
3、把新cookie的键值对添加到响应中。
usernameCookie.setMaxAge(864000);
response.addCookie(usernameCookie);
4、若选择不缓存信息时:
——先获取所有Cookie集合,
——再遍历集合(获取相同键名的cookie)
——若有,则生命周期置0,然后添加到响应中。
Cookie[] cookies = request.getCookies();
if(cookies != null && cookies.length > 0){
for(Cookie c:cookies){
if(c.getName().equals("username") || c.getName().equals("password")){
c.setMaxAge(0);
response.addCookie(c);
}
}
}
dologin.jsp:
<%@ page language="java" import="java.util.*,java.text.*" contentType="text/html; charset=UTF-8"%>
<%@ page import="java.net.*" %>
<!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>cookie</title>
</head>
<body>
<h1>登录成功!</h1><hr/>
<%
// 设置请求体中的编码为utf-8。
request.setCharacterEncoding("utf-8");
// 判断是否选择记住。
String[] isUseCookies = request.getParameterValues("isUseCookie");
if(isUseCookies != null && isUseCookies.length > 0){
// 保存用户名和密码。
String username = URLEncoder.encode(request.getParameter("username"),"utf-8");
// 解决Cookie中无法保存中文。使用net包中的URLencode.encode(str,"utf-8")方法,对请求中的获取的数据进行转码。
String password = URLEncoder.encode(request.getParameter("password"),"utf-8");
// 创建Cookie类的实例对象。
Cookie usernameCookie = new Cookie("username",username);
Cookie passwordCookie = new Cookie("password",password);
// 设置Cookie的有效期。1天=10*24*60*60=864000
usernameCookie.setMaxAge(864000);
passwordCookie.setMaxAge(864000);
// 响应中,写入cookie对象。
response.addCookie(usernameCookie);
response.addCookie(passwordCookie);
}else{
// 在请求中,读取cookie。
Cookie[] cookies = request.getCookies();
if(cookies != null && cookies.length > 0){
for(Cookie c:cookies){
// 寻找cookie中是否已经保存过该用户。
if(c.getName().equals("username") || c.getName().equals("password")){
// 若保存过,则让其失效。并添加到响应中。
c.setMaxAge(0);
response.addCookie(c);
}
}
}
}
%>
<a href="users.jsp" target="_blank">查看用户信息。</a>
</body>
</html>
3.1.3 用户信息页面
步骤:
1、获取请求中的所有Cookie集合。
Cookie[] cookies = request.getCookies();
2、遍历Cookie集合。查询是否有cookie的键名为“username”的cookie。
for (Cookie c : cookies) {
if (c.getName().equals("username")) {
username = URLDecoder.decode(c.getValue(),"utf-8");
}
}
3、若有,则获取对应的cookie值并赋值给相应的变量。
username = URLDecoder.decode(c.getValue(),"utf-8");
4、使用键值。
用户名:<%=username %><br />
users.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ page import="java.net.*" %>
<!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>用户登录</title>
</head>
<body>
<h1>用户信息</h1>
<br />
<%
// 设置请求体中的编码为utf-8。
request.setCharacterEncoding("utf-8");
String username = "";
String password = "";
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie c : cookies) {
// 寻找cookie中是否已经保存过该用户。
if (c.getName().equals("username")) {
username = URLDecoder.decode(c.getValue(),"utf-8");
}
if (c.getName().equals("password")) {
password = URLDecoder.decode(c.getValue(),"utf-8");
}
}
}
%>
用户名:<%=username %><br />
密码:<%=password %><br />
</body>
</html>
3.2 商品浏览记录
需求:实现商品浏览记录。
架构:Model 1(JSP + JavaBean)。
步骤:
(1)数据库设计。
(2)连接数据库。创建DBHelper工具类。
(3)创建实体类。
(4)DAO(CRUD)+ Service设计。创建业务逻辑类,JavaBean类封装商品操作。
(5)页面层设计。
3.2.1 数据库设计
JSPViewListDemo/WebContent/sql/items.sql:
-- 创建数据库。
CREATE DATABASE IF NOT EXISTS shopping CHARACTER SET = utf8;
-- 创建表
CREATE TABLE items(
`id` INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT NULL,
`city` VARCHAR(50) DEFAULT NULL,
`price` DECIMAL(11,2) DEFAULT NULL,
`number` INT(11) DEFAULT NULL,
`picture` VARCHAR(500) DEFAULT NULL
)ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=UTF8;
-- 插入数据items
INSERT INTO items VALUES(DEFAULT,"沃特篮球鞋","佛山",180,500,"001.jpg"),(DEFAULT,"安踏运动鞋","福州",120,800,"002.jpg"),(DEFAULT,"耐克运动鞋","广州",500,1000,"003.jpg"),(DEFAULT,"阿迪达斯T恤衫","上海",388,600,"004.jpg"),(DEFAULT,"李宁文化衫","广州",180,900,"005.jpg"),(DEFAULT,"小米3","北京",1999,3000,"006.jpg"),(DEFAULT,"小米2S","北京",1299,1000,"007.jpg"),(DEFAULT,"thinkpad笔记本","北京",6999,500,"008.jpg"),(DEFAULT,"Dell笔记本","北京",3999,500,"009.jpg"),(DEFAULT,"iPad5","北京",5999,500,"010.jpg");
3.2.2 连接数据库
com.my.util.DBHelper:
package com.my.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBHelper {
private static final String driver = "com.mysql.jdbc.Driver";// 数据库驱动。
private static final String url = "jdbc:mysql://127.0.0.1:3306/shopping?useUnicode=true&characterEncoding=UTF-8";// 数据库的URL。
private static final String username = "root"; // 数据库的用户名。
private static final String password = "123456";// 数据库的密码。
private static Connection conn = null;
// 静态代码块。负责加载驱动。
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 单例模式——饱汉式。返回数据库的连接
public static Connection getConnection() {
if (conn == null) {
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
}
return conn;
}
public static void main(String[] args){
Connection c = DBHelper.getConnection();
if(c != null){
System.out.println("测试连接数据库成功!");
}else{
System.out.println("测试连接数据库失败!");
}
}
}
3.2.3 创建实体类
com.my.entity.Items:
package com.my.entity;
// 遵循JavaBean设计原则。
public class Items {
private int id;// 商品编号
private String name;// 商品名称
private String city;// 商品城市
private float price;// 商品价格
private int number;// 商品数量
private String picture;// 商品图片
public Items() {
}
// getter/setter方法暂略
}
3.2.4 DAO+Service设计
com.my.dao.ItemsDAO:
package com.my.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.my.entity.Items;
import com.my.util.DBHelper;
public class ItemsDAO {
private Connection conn = null; // 连接对象。
private PreparedStatement ps = null; // SQL语句对象。
private ResultSet rs = null; // 数据集对象。
//==========================DAO层方法=============================
// 方法1:查询。所有商品信息。
public List<Items> getAllItems() {
List<Items> list = new ArrayList<Items>();// 商品集合。
try {
conn = DBHelper.getConnection();// 创建连接
String sql = "SELECT * FROM items;";// SQL语句。
ps = conn.prepareStatement(sql);// 创建SQL语句对象
rs = ps.executeQuery(); // 执行SQL语句,并把查询结果放入结果集中。
Items item = null;
while (rs.next()) {
item = setItemBySQL(rs);
list.add(item);// 把每一个商品加入商品集合。
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeRsAndPs();
}
return list;
}
// 方法2:查询。根据商品编号,获取商品的信息。
public Items getItem(int id) {
Items item = null; // 商品。
try {
conn = DBHelper.getConnection();// 创建连接
String sql = "SELECT * FROM items WHERE id = ?;";// SQL语句。
ps = conn.prepareStatement(sql);// 创建SQL语句对象
ps.setInt(1, id); // 设置SQL语句中?的值。
rs = ps.executeQuery(); // 执行SQL语句,并把查询结果放入结果集中。
if (rs.next()) {
item = setItemBySQL(rs);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeRsAndPs();
}
return item;
}
// 方法3:释放结果集和SQL语句对象。
private void closeRsAndPs() {
try {
// 释放数据集对象。
if (rs != null) {
rs.close();
rs = null;
}
// 释放SQL语句对象。
if (ps != null) {
ps.close();
ps = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// 方法4:单个商品设置从数据库中获取的属性。
private Items setItemBySQL(ResultSet rs){
Items item = new Items();
try {
item.setId(rs.getInt("id"));
item.setName(rs.getString("name"));
item.setCity(rs.getString("city"));
item.setNumber(rs.getInt("number"));
item.setPicture(rs.getString("picture"));
item.setPrice(rs.getFloat("price"));
} catch (SQLException e) {
e.printStackTrace();
}
return item;
}
//==========================Service层方法=============================
// 方法5:根据cookie的值(商品ID),获取浏览过的商品(前5条)。
public List<Items> getViewList(String list){
int iCount = 5; //每次显示最近浏览的5条记录。
List<Items> items = new ArrayList<Items>();
// 判断list是否为空。在数据库查询时出现空指针异常。
if(list != null && list.length() > 0){
// 把传入的cookie值转换成字符串数组。分割符根据cookie中自定义的分割符,一般为“,”。
String[] stringArray = list.split(",");
// 判断获取数量。
if(stringArray.length < iCount){
iCount = stringArray.length;
}
// 遍历字符串数组。倒序获取展示。
for(int i = stringArray.length - 1 ; i > stringArray.length - 1 - iCount; i--){
int id = Integer.parseInt(stringArray[i]); // 将数字字符串转化成数字
Items item = getItem(id);// 根据id获取商品信息。
items.add(item);// 把商品添加到商品集合中。
}
}
return items;
}
public static void main(String[] args) {
ItemsDAO itemsdao = new ItemsDAO();
// 测试查询所有商品。
System.out.println("================测试查询所有商品。================");
List<Items> items = itemsdao.getAllItems();
for (Items item : items) {
System.out.println(item);
}
// 测试通过id获取商品信息。
System.out.println("================测试通过id获取商品信息。================");
Items item = itemsdao.getItem(11);
System.out.println(item);
}
}
3.2.5 视图层设计。
主页:index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.my.dao.ItemsDAO,com.my.entity.Items,java.util.*"%>
<!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>
<h1>商品展示</h1>
<center>
<table>
<tr>
<%
ItemsDAO itemsdao = new ItemsDAO();
List<Items> items = itemsdao.getAllItems();
if (items != null && items.size() > 0) { // 防止抛出空指针异常。
for (int i = 0; i < items.size(); i++) {
Items item = items.get(i);
%>
<%-- 商品循环开始 --%>
<div>
<dl>
<dt>
<a href="details.jsp?id=<%=item.getId() %>"><img src="images/<%=item.getPicture()%>" width="120" height="60" /></a>
</dt>
<dd class="dd_name"><%=item.getName()%></dd>
<dd class="dd_city">
产地:<%=item.getCity()%> 价格:¥<%=item.getPrice()%></dd>
</dl>
</div>
<%-- 商品循环结束 --%>
<%
}
}
%>
</tr>
</table>
</center>
</body>
</html>
商品详细页:details.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.my.dao.ItemsDAO,com.my.entity.Items,java.util.*"%>
<!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>商品详细</title>
</head>
<body>
<h1>商品详细</h1>
<hr />
<center>
<table width="750" heigth="60" cellpadding="0" cellspacing="0" border="0">
<tr>
<%
ItemsDAO itemsdao = new ItemsDAO();
// 获取请求中的id参数的值,并把其转化为整型。
int id = Integer.parseInt(request.getParameter("id"));
// 创建商品(id)。
Items item = itemsdao.getItem(id);
if(item != null){
%>
<td>
<table>
<tr>
<td rowspan="4"><img src="images/<%=item.getPicture()%>" width="200" heigth="160"/></td>
</tr>
<tr>
<td><B><%=item.getName() %></B></td>
</tr>
<tr>
<td>产地:<%=item.getCity() %></td>
</tr>
<tr>
<td>价格:<%=item.getPrice() %>¥</td>
</tr>
<tr>
<td>库存:<%=item.getNumber() %>¥</td>
</tr>
</table>
</td>
<%
}
%>
<%-- 创建商品cookie思路:只需要记录商品的id和该项目的名称即可。 --%>
<%
// 定义list字符串。接收ListViewCookie项目名为ListViewCookie的cookie。
String list = "";
// 读取请求中的所有cookie。即客户端cookie集合。
Cookie[] cookieArray = request.getCookies();
if(cookieArray != null && cookieArray.length > 0){
// 遍历cookie集合。目的:判断是否有名为ListViewCookie的cookie。
for(Cookie cookie:cookieArray){
// 判断是否有名为ListViewCookie的cookie。
if(cookie.getName().equals("ListViewCookie")){
// 若有,则获取该键值。
list = cookie.getValue();
// 获取请求中的商品id。并把其加入到list字符串中。加“,”是为了便于清零操作。
list += request.getParameter("id") + ",";
// 如果浏览记录超过1000条,则清零。
String[] stringArray = list.split(",");//cookies.length
if(stringArray != null && stringArray.length > 0){
if(stringArray.length >= 1000){
list = "";
}
}
}
}
}
// 新建名称为ListViewCookie的cookie(键值对项目名 + list值)。
Cookie cookie = new Cookie("ListViewCookie",list);
// 并把名称为ListViewCookie的cookie写入响应中。
response.addCookie(cookie);
%>
<!-- 浏览过的商品 -->
<td width="30%" bgcolor="green" align="center"><br/>
<b>您浏览过的商品</b><br/>
<%-- 循环开始 --%>
<%
List<Items> items = new ArrayList();
items = itemsdao.getViewList(list);
if(items != null && items.size() > 0){
for(Items item2:items){
%>
<div>
<dl>
<dt>
<a href="details.jsp?id=<%=item2.getId() %>"><img src="images/<%=item2.getPicture()%>" width="120" height="60" /></a>
</dt>
<dd class="dd_name"><%=item2.getName()%></dd>
<dd class="dd_city">产地:<%=item2.getCity()%> 价格:¥<%=item2.getPrice()%></dd>
</dl>
</div>
<%
}
}
%>
<%-- 循环结束 --%>
</td>
</tr>
</table>
</center>
</body>
</html>