网站3天免输入登录页面编程
网站3天免输入登录页面编程
一、实验目的
掌握JSP的内置对象技术以及表单验证在服务器端的实现技术
二、实验内容与设计思想
编写网站的登录页面,要求能保存用户登录成功时输入的用户名及密码信息,当同一用户 3天内再次登录网站首页时,能自动读取之前保存的用户信息判断身份是否合法,如果合法自动完成登录。如果当同一用户超过3天再次登录网站首页时,则需要重新输入用户名及密码进行身份验证,通过验证方能登录并显示欢迎信息。否则提示:身份验证失败,必须重新输入输入
三、实验步骤
1. 分析题目
- 制作网站登录页面
包含用户名、密码输入框和登录按钮 - 保存用户登录信息(3天有效期)
登录成功后,要把用户名和密码保存到客户端,并且3天内有效 - 3天内自动登录
用户再次访问首页时,系统自动读取保存的信息,验证合法则直接自动登录,不用重新输入 - 超过3天必须重新登录
保存信息过期后,系统自动清除记录,用户必须重新输入账号密码 - 身份验证规则
验证通过 → 显示欢迎信息
验证失败 → 提示 “身份验证失败,必须重新输入”
2. 实现思路
(1)核心思路:用 Cookie 保存登录状态
- Cookie 是浏览器本地存储数据的技术,可以设置保存时间
- 本次实验设置 Cookie 有效期 = 3 天
(2)流程思路:
用户第一次访问首页
→ 无 Cookie → 跳转到登录页
用户输入账号密码登录
→ 验证成功
→ 把用户名、密码存入 Cookie(3 天有效期)
→ 进入首页
用户3 天内再次访问首页
→ 读取 Cookie
→ 验证信息合法
→ 自动登录成功
用户超过 3 天访问
→ Cookie 已过期
→ 自动跳转登录页
→ 必须重新输入账号密码
输入错误账号密码
→ 提示验证失败,留在登录页重新输入
3. 项目结构
WebContent/
├── css/
│ └── style.css # 独立CSS文件
├── login.jsp # 登录页面
├── index.jsp # 首页(自动登录判断)
├── loginCheck.jsp # 登录验证处理
└── logout.jsp # 退出登录(可选)
4. 源代码
style.css
/* 全局样式初始化:清除默认内外边距,统一盒子模型,设置全局字体 */
* {
margin: 0; /* 0:清除所有元素默认外边距,不留空白 */
padding: 0; /* 0:清除所有元素默认内边距 */
box-sizing: border-box; /* 统一盒模型,宽高包含边框+内边距,不会撑大元素 */
font-family: "Microsoft YaHei", sans-serif; /* 全局统一微软雅黑字体 */
}
/* 页面整体主体样式 */
body {
position: relative; /* 相对定位,方便后期添加页面动态元素 */
overflow: hidden; /* 隐藏页面滚动条,页面固定全屏显示 */
/* 135deg:渐变倾斜角度;#74c0f8浅天蓝色起始色;#5b3cb8深紫色结束色 */
background: linear-gradient(135deg, #74c0f8, #5b3cb8);
display: flex; /* 启用弹性布局,快速居中 */
justify-content: center; /* 水平方向居中对齐 */
align-items: center; /* 垂直方向居中对齐 */
height: 100vh; /* 100vh:高度占满浏览器整个可视屏幕高度 */
background-size: 400% 400%; /* 400%:把渐变背景放大4倍,留出移动空间实现流动效果 */
/* gradientFlow动画名 14s执行时长 ease-in-out先慢后慢 infinite无限循环 */
animation: gradientFlow 14s ease-in-out infinite;
}
/* 背景渐变流动动画关键帧 */
@keyframes gradientFlow {
0% {background-position: 0% 50%;} /* 0%动画起点:水平0%位置,垂直居中50% */
50% {background-position: 100% 50%;} /* 50%动画中点:水平100%最右侧,垂直居中 */
100% {background-position: 0% 50%;} /* 100%动画终点:回到起点位置,循环流动 */
}
/* 登录外层卡片容器 */
.login-box {
width: 420px; /* 420px:固定登录卡片宽度,适中大小适配页面 */
padding: 45px; /* 45px:卡片上下左右统一内边距,拉开内容与边框距离 */
background: rgba(255, 255, 255, 0.82); /* 0.82:白色透明度,数值越大越不透明 */
border-radius: 20px; /* 20px:卡片圆角数值,数值越大边角越圆润 */
border: 1px solid rgba(120, 150, 255, 0.3); /* 1px:边框粗细;0.3:边框透明度 */
/* 0 0 30px:外阴影四周扩散30px;inset内阴影四周扩散15px */
box-shadow: 0 0 30px rgba(90, 110, 220, 0.25),
inset 0 0 15px rgba(90, 110, 220, 0.1);
z-index: 10; /* 10:层级数值,保证卡片在背景最上层显示 */
transition: all 0.4s ease; /* 0.4s:所有过渡动画执行时长,0.4秒完成渐变 */
}
/* 登录卡片悬浮上浮效果 */
.login-box:hover {
transform: translateY(-6px); /* -6px:向上移动6像素,实现悬浮效果 */
/* 40px:加大外阴影扩散距离;0.35加深阴影透明度 */
box-shadow: 0 0 40px rgba(90, 110, 220, 0.35),
inset 0 0 20px rgba(90, 110, 220, 0.15);
}
/* 登录页面大标题样式 */
.login-box h2 {
text-align: center; /* 标题文字水平居中 */
margin-bottom: 35px; /* 35px:标题底部外边距,和下方输入框拉开35px距离 */
color: #4a3296; /* 设置标题深紫色字体颜色 */
font-weight: 600; /* 600:字体加粗程度,600为中度加粗 */
letter-spacing: 3px; /* 3px:文字之间间距3像素,排版更美观 */
}
/* 每一组输入框外层容器 */
.input-item {
margin-bottom: 24px; /* 24px:每组输入框底部间距24px,分行整齐排列 */
}
/* 用户名、密码文字标签 */
.input-item label {
display: block; /* 转为块级元素,单独占一行 */
margin-bottom: 9px; /* 9px:文字标签与输入框之间间距9像素 */
color: #6048b0; /* 标签浅紫色字体 */
font-size: 15px; /* 15px:标签文字字号大小 */
}
/* 文本输入框默认样式 */
.input-item input {
width: 100%; /* 100%:输入框宽度铺满父容器 */
height: 46px; /* 46px:输入框固定高度,输入手感舒适 */
padding: 0 15px; /* 上下0内边距,左右15px内边距,文字不贴边框 */
border: 1px solid #b4a6e8; /* 1px:输入框边框粗细,搭配浅紫色边框 */
border-radius: 10px; /* 10px:输入框圆角大小 */
font-size: 16px; /* 16px:输入内容文字字号 */
background: #f5f1ff; /* 输入框淡紫色底色 */
outline: none; /* 取消浏览器默认聚焦黑边框 */
transition: all 0.3s ease; /* 0.3秒完成输入框所有样式过渡 */
color: #3f2e7c; /* 输入文字深紫色 */
}
/* 输入框鼠标点击聚焦样式 */
.input-item input:focus{
border-color: #7c64d8; /* 聚焦后边框变为深紫色 */
box-shadow: 0 0 12px rgba(110,90,210,0.35); /* 12px:聚焦发光扩散距离 */
background: #ffffff; /* 聚焦后输入框变为纯白色 */
}
/* 登录提交按钮默认样式 */
.btn {
width: 100%; /* 按钮宽度铺满整行 */
height: 50px; /* 50px:按钮高度,大气醒目 */
/* 135deg渐变角度,浅蓝转深紫,和页面主题统一 */
background: linear-gradient(135deg, #6fb6f5, #6744c9);
color: #ffffff; /* 按钮内文字纯白色 */
border: none; /* 取消按钮默认边框 */
border-radius: 10px; /* 10px:按钮圆角大小 */
font-size: 17px; /* 按钮文字字号17px */
cursor: pointer; /* 鼠标悬浮变为手型,提示可点击 */
letter-spacing: 2px; /* 2px:按钮文字间距2像素 */
transition: all 0.3s ease; /* 0.3秒完成按钮所有动态效果 */
}
/* 登录按钮悬浮效果 */
.btn:hover {
background: linear-gradient(135deg, #58a3e8, #5332b8); /* 加深按钮渐变颜色 */
transform: scale(1.02); /* 1.02:按钮放大1.02倍,轻微变大 */
box-shadow: 0 0 15px rgba(100,75,200,0.4); /* 15px:按钮悬浮发光范围 */
}
/* 按钮鼠标点击按压效果 */
.btn:active{
transform: scale(0.98); /* 0.98:按钮缩小至0.98倍,模拟按下手感 */
}
/* 登录失败错误提示文字 */
.msg {
text-align: center; /* 错误文字居中显示 */
margin-top: 18px; /* 18px:提示文字距离按钮顶部18像素 */
color: #e55555; /* 红色错误提示字体 */
font-size: 15px; /* 提示文字字号15px */
}
/* 登录成功欢迎页面文字 */
.welcome {
text-align: center; /* 欢迎文字居中 */
font-size: 22px; /* 22px:大号欢迎字体 */
color: #4a3296; /* 深紫色欢迎文字 */
line-height: 1.8; /* 1.8:文字行高,数值越大上下间距越宽松 */
}
/* 退出登录超链接样式 */
.logout {
display: block; /* 转为块级元素独占一行 */
text-align: center; /* 文字居中 */
margin-top: 25px; /* 25px:距离上方文字顶部25像素 */
color: #6048b0; /* 紫色链接字体 */
text-decoration: none; /* 取消默认下划线 */
font-size: 15px; /* 链接文字大小15px */
transition: 0.3s; /* 0.3秒完成链接样式变化 */
}
/* 退出链接悬浮效果 */
.logout:hover{
color: #3f2e7c; /* 悬浮后字体颜色加深 */
text-decoration: underline; /* 悬浮出现下划线,提示可点击 */
}
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!--
page指令:配置JSP页面
language="java":使用Java语言
contentType="text/html; charset=UTF-8":响应内容类型为HTML,编码UTF-8
pageEncoding="UTF-8":页面文件本身编码为UTF-8
-->
<!DOCTYPE html>
<!-- 声明文档类型为HTML5 -->
<html>
<!-- HTML根标签 -->
<head>
<!-- 头部区域:存放页面配置信息 -->
<meta charset="UTF-8">
<!-- 设置网页字符编码为UTF-8,防止中文乱码 -->
<title>首页</title>
<!-- 网页标题:显示在浏览器标签上 -->
<link rel="stylesheet" href="css/style.css">
<!-- 引入外部CSS样式文件,路径:项目下css文件夹中的style.css -->
</head>
<body>
<!-- 页面主体区域:所有可见内容都写在这里 -->
<div class="login-box">
<!-- 登录卡片容器,使用class="login-box"调用CSS样式,实现美观布局 -->
<%
// Java代码块开始:JSP中编写后台逻辑
// 1. 获取浏览器发送过来的所有Cookie数据,存入Cookie数组
Cookie[] cookies = request.getCookies();
// 2. 声明两个变量,用于存储从Cookie中取出的用户名和密码
String username = null; // 初始值为null,表示还没有获取到用户名
String password = null; // 初始值为null,表示还没有获取到密码
// 3. 判断:如果Cookie数组不为null(说明浏览器有携带Cookie)
if (cookies != null) {
// 遍历循环所有Cookie,一个一个查找
for (Cookie c : cookies) {
// 判断当前Cookie的name是否为"username"
if ("username".equals(c.getName())) {
// 如果是,就把Cookie中的value赋值给username变量
username = c.getValue();
}
// 判断当前Cookie的name是否为"password"
if ("password".equals(c.getName())) {
// 如果是,就把Cookie中的value赋值给password变量
password = c.getValue();
}
}
}
// 4. 定义系统固定的合法账号(实验模拟,固定账号密码)
final String OK_USER = "admin"; // OK_USER:正确用户名,值为"admin"
final String OK_PWD = "123456"; // OK_PWD:正确密码,值为"123456"
// 5. 核心判断:验证Cookie中的账号密码是否合法
// 条件1:username不为null 条件2:password不为null
// 条件3:取出的用户名等于正确用户名 条件4:取出的密码等于正确密码
if (username != null && password != null
&& OK_USER.equals(username)
&& OK_PWD.equals(password)) {
// 所有条件满足 → Cookie有效,自动登录成功
// 将用户名存入Session会话,标记用户已登录
session.setAttribute("user", username);
%>
<!-- HTML片段:自动登录成功后显示的欢迎界面 -->
<div class="welcome">
<h2>自动登录成功!</h2>
<p>欢迎回来,<%=username%></p> <!-- 输出当前登录的用户名 -->
<p>3天内免登录已生效</p> <!-- 提示Cookie有效期 -->
</div>
<a href="logout.jsp" class="logout">退出登录</a>
<!-- 退出链接,跳转到logout.jsp清除Cookie -->
<%
} else {
// 条件不满足:无Cookie / Cookie过期 / 账号密码错误
// 执行重定向,跳转到登录页面login.jsp
response.sendRedirect("login.jsp");
}
%>
</div>
<!-- 关闭.login-box卡片 -->
</body>
</html>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!--
JSP page指令:配置当前页面参数
language="java":指定脚本语言为Java
contentType="text/html; charset=UTF-8":设置响应内容类型与编码,防止中文乱码
pageEncoding="UTF-8":设置当前JSP文件自身的编码格式
-->
<!DOCTYPE html>
<!-- 声明文档类型为HTML5标准格式 -->
<html>
<!-- HTML文档的根标签,所有内容必须写在里面 -->
<head>
<!-- 头部区域:存放网页配置、标题、引入的样式文件等 -->
<meta charset="UTF-8">
<!-- 设置网页字符编码为UTF-8,确保中文正常显示 -->
<title>登录页面</title>
<!-- 浏览器标签页上显示的标题文字 -->
<link rel="stylesheet" href="css/style.css">
<!-- 引入外部CSS样式文件,href="css/style.css"表示路径为项目下css文件夹中的style.css -->
</head>
<body>
<!-- 网页主体区域:用户能看到的所有内容都在这里 -->
<div class="login-box">
<!-- 登录卡片容器,class="login-box"使用CSS中定义好的样式,实现美观布局 -->
<h2>用户登录</h2>
<!-- 登录标题,h2为二级标题 -->
<form action="loginCheck.jsp" method="post">
<!--
表单标签:用于提交用户输入的数据
action="loginCheck.jsp":表单数据提交到 loginCheck.jsp 页面进行验证处理
method="post":提交方式为POST,数据安全、不显示在地址栏
-->
<div class="input-item">
<!-- 输入框组容器,统一样式 -->
<label>用户名</label>
<!-- 用户名文字标签,提示用户输入 -->
<%
// Java代码块:从Cookie中读取用户名,实现自动回填功能
String uname = ""; // 定义变量uname,初始值为空字符串,用于存放用户名
Cookie[] cs = request.getCookies(); // 获取浏览器带来的所有Cookie,存入数组cs
if (cs != null) { // 判断Cookie数组不为null(浏览器有Cookie)
for (Cookie c : cs) { // 遍历所有Cookie
if ("username".equals(c.getName())) { // 找到name为"username"的Cookie
uname = c.getValue(); // 将Cookie中的值赋值给uname变量
}
}
}
%>
<input type="text" name="username" value="<%=uname%>" required>
<!--
用户名输入框:
type="text":文本输入框
name="username":后台获取数据的参数名
value="<%=uname%>":将Cookie中的用户名自动回填到输入框
required:HTML5验证,表示此项必须填写,不能为空
-->
</div>
<div class="input-item">
<!-- 密码输入框组 -->
<label>密码</label>
<!-- 密码文字提示标签 -->
<input type="password" name="password" required>
<!--
密码输入框:
type="password":密码格式,输入内容隐藏为小黑点
name="password":后台获取密码的参数名
required:必须填写,不能为空
-->
</div>
<button type="submit" class="btn">登录</button>
<!--
登录按钮:
type="submit":提交表单按钮,点击后发送数据到action指定页面
class="btn":使用CSS中定义的按钮样式
-->
</form>
<!-- 表单结束 -->
<%
// 获取登录验证失败后的提示信息
String msg = (String) request.getAttribute("msg");
// 从request域中获取名为"msg"的属性值,并强转为字符串类型
if (msg != null) { // 判断提示信息不为null(有错误信息)
%>
<div class="msg"><%=msg%></div>
<!-- 显示错误提示信息,class="msg"使用CSS红色提示样式 -->
<% } %>
<!-- 判断结束 -->
</div>
<!-- 登录卡片结束 -->
</body>
</html>
loginCheck.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!--
JSP页面指令:配置页面参数
language="java":使用Java语言
contentType="text/html; charset=UTF-8":设置响应内容类型和编码
pageEncoding="UTF-8":设置JSP文件自身编码,防止中文乱码
-->
<%
// 设置请求的编码格式为UTF-8,解决前端传递过来的中文乱码问题
request.setCharacterEncoding("UTF-8");
// 获取登录页面表单提交的用户名
// request.getParameter("name属性值"):根据表单输入框的name获取输入内容
String username = request.getParameter("username");
// 获取登录页面表单提交的密码
String password = request.getParameter("password");
// ---------------------- 模拟后台固定合法账号(实验用)----------------------
// final 表示常量,值不可修改
final String USER = "admin"; // 正确的用户名:admin
final String PWD = "123456"; // 正确的密码:123456
// ---------------------- 验证账号密码是否正确 ----------------------
// 判断:用户输入的用户名 和 密码 与 固定正确值 完全一致
if (USER.equals(username) && PWD.equals(password)) {
// ====================== 登录成功 ======================
// 创建Cookie对象,存储用户名,name为"username"
Cookie c1 = new Cookie("username", username);
// 创建Cookie对象,存储密码,name为"password"
Cookie c2 = new Cookie("password", password);
// 设置Cookie的最大有效期:3天
// 计算公式:3天 × 24小时 × 60分钟 × 60秒 = 259200 秒
int maxAge = 3 * 24 * 60 * 60;
// 给用户名Cookie设置有效期3天
c1.setMaxAge(maxAge);
// 给密码Cookie设置有效期3天
c2.setMaxAge(maxAge);
// 将Cookie写入客户端(浏览器),浏览器会保存3天
response.addCookie(c1);
response.addCookie(c2);
// 将用户名存入Session会话,表示用户已登录
session.setAttribute("user", username);
// 重定向跳转到首页 index.jsp
response.sendRedirect("index.jsp");
} else {
// ====================== 登录失败 ======================
// 将错误提示信息存入request域中,名为"msg"
request.setAttribute("msg", "身份验证失败,必须重新输入!");
// 请求转发:跳回登录页面,并携带错误提示信息
request.getRequestDispatcher("login.jsp").forward(request, response);
}
%>
logut.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!--
JSP page指令:配置页面参数
language="java":指定使用Java语言
contentType="text/html; charset=UTF-8":设置响应内容类型与编码
pageEncoding="UTF-8":设置当前JSP文件编码,防止乱码
-->
<%
// ===================== 1. 清除Cookie(实现退出登录核心步骤) =====================
// 创建名为username的Cookie,值设为空字符串"",覆盖原来的Cookie
Cookie c1 = new Cookie("username", "");
// 创建名为password的Cookie,值设为空字符串""
Cookie c2 = new Cookie("password", "");
// 设置Cookie的最大有效期为 0 秒
// 0 表示立即过期、立即删除
c1.setMaxAge(0);
c2.setMaxAge(0);
// 将这两个立即过期的Cookie发送给浏览器
// 浏览器收到后,会自动删除原来保存的username和password Cookie
response.addCookie(c1);
response.addCookie(c2);
// ===================== 2. 销毁Session(清除登录状态) =====================
// session.invalidate():强制销毁当前会话
// 清除所有登录状态信息
session.invalidate();
// ===================== 3. 跳回登录页面 =====================
// 重定向到 login.jsp,让用户重新登录
response.sendRedirect("login.jsp");
%>
浙公网安备 33010602011771号