今天和大家分享一个小案例,也是我的课程作业,就是使用Cookie存储的方式,来完成用户登录界面功能的一个实现。
首先我们要知道,cookie实际上是客户端浏览器的一种存储方式,他是依赖于客户端浏览器的存储文本,也就是说我们可以用它把数据存在浏览器中来保证我们项目对数据的引用,但是它并不是很安全,不过我们这也只是作业,目的是为了让我们更熟练的掌握罢了,话不多说,开始我们项目的搭建:
这个项目分为两个大的部分:Servlet部分和jsp部分,我们分别来说:
Servlet部分:
首先是要实现三个功能:注册、登录和验证,那么我们就需要三个Servlet来分别完成这个工作。
registerServlet:
主要是创建Cookie对象,并将从前端获取的数据存储进去,由于Cookie是键值对形式存储的,起初我是想用Cookie的name做用户名,用Value来做用户的密码,从而形成一个键值对的关系,但是因为Cookie的Name不能是中文,所以就需要变通一下,使用name做密码,然后用Value来做用户名就好了,同样形成了一个键值对的关系,源码如下:
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "registerServlet", value = "/registerServlet")
public class registerServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Content-Type","text/html;charset=UTF-8");//设置浏览器编码为utf-8,防止出现中文乱码
//接收前端表单输入的用户名和密码
String username = request.getParameter("Username");
String userPassword = request.getParameter("UserPassword");
//创建cookie,并将上文接收的用户名和密码存入cookie中
Cookie cookie=new Cookie(userPassword,username);
cookie.setMaxAge(60*10);//设置cookie存活时间为10分钟
//发送cookie至客户端,并跳转至注册成功页面
response.addCookie(cookie);
String massage="<meta http-equiv='refresh' content='3;url=/Cookie_war_exploded/Login.jsp'>三秒后跳转到登陆页面,如果没有跳转,请点击<a href='login.jsp'>跳转按钮</a>";//实现三秒之后自动跳转功能。
request.setAttribute("massage",massage);
request.getRequestDispatcher("/registerVictory.jsp").forward(request,response);
}
}
LoginServlet:
它主要是通过判断逻辑,来判断输入的用户名和密码与Cookie中存储的用户名密码是否匹配,匹配则登录成功,否则登陆失败。
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "LoginServlet", value = "/LoginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Content-Type","text/html;charset=UTF-8");
String username = request.getParameter("Username");//获取输入的用户名
String userPassword = request.getParameter("UserPassword");//获取输入的密码
Cookie[] cookies = request.getCookies();//获取Cookie信息
//定义一个布尔变量flag=false,用于用户登陆条件的判断
boolean flag=false;
//使用for循环遍历获取到的cookie,并判断cookie.getName是否与输入的密码一致,
// 进而判断cookie.getValue是否与输入的用户名一致,如果两者都满足,则令flag=true,否则不变
for (Cookie cookie : cookies) {
if(cookie.getName().equals(userPassword)){
if(cookie.getValue().equals(username)){
flag=true;
}
}
}
//这里对flag进行判断,如果为true,则表示登陆条件满足,否则不满足登陆条件,执行else最后弄得语句
if(flag){
request.getRequestDispatcher("/Victory.jsp").forward(request,response);
//这里没有使用重定向,因为想要把用户名转发到欢迎界面,让欢迎界面输出欢迎用户名登陆的字样,所以使用转发
}else {
String err="";//定义存储错误字符串
err="用户名或密码输入错误,请重新输入!";
request.setAttribute("err",err);//发送存储错误字符串到页面
request.getRequestDispatcher("/Login.jsp").forward(request,response);
//这里将错误提示字符串转发到登录界面,由登录界面的EL表达式进行接收给出错误提示信息。
}
}
}
deleteServlet:
主要用于Cookie的删除,但是并没有直接删除Cookie的方法,一般我们都是使用同名的0时长cookie覆盖要删除的cookie,从而达到立即消失的效果。
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "DeleteServlet", value = "/DeleteServlet")
public class DeleteServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Content-Type","text/html;charset=UTF-8");
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
Cookie DeleteCookie=new Cookie(cookie.getName(),cookie.getValue());//创建同名cookie
DeleteCookie.setMaxAge(0);//设置存活时间为0
response.addCookie(DeleteCookie);//将原先cookie覆盖,使之立刻消失。
}
response.sendRedirect("Login.jsp");//注销完毕所有cookie后,重定向至登录页面。
//使用for循环,将所有用户的cookie都用同名0时长的cookie覆盖,所有用户的信息都将被注销!!
}
}
到了这里,我们就实现了创建、验证、注销的三个功能了,接下来就是要与前端结合起来:
JSP部分:
在这里有四个jsp页面,分别负责注册、注册成功、登陆、登录成功界面,由于jsp是动态页面,所以我们可以多使用EL表达式,来实现页面内容的灵活变化,同时我们也可以使用bootstrap框架:
注册页面jsp及效果:
<%--
Created by IntelliJ IDEA.
User: 阿煊
Date: 2022/4/10
Time: 10:22
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册界面</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
<style>
body,html{
background-color: antiquewhite;;
background-size: 100% ,100%;
}
.logindiv{
width: 350px;
height: 450px;
background-color: white;
opacity: 0.9;
border-radius: 25px;
display: inline-block;
position:absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
box-shadow: 0px,0px,100px,10px,gray;
border-style: outset;
}
.divs{
margin-bottom: 20px;
padding-top: 20px;
}
</style>
</head>
<body>
<div class="logindiv">
<center><h1>注册用户</h1>
<form action="registerServlet">
<div ><h3>用户名:</h3></div>
<div class="divs"><input type="text" name="Username"></div>
<div ><h3>密码:</h3></div>
<div class="divs"><input type="text" name="UserPassword"></div>
<a href="Login.jsp">已经有账户?点击去登陆!</a>
<div><input type="submit" class="btn btn-primary btn-lg " value="提交"></div>
</form></center>
</div>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</body>
</html>
效果:
点击提交跳转到注册成功页面:
注册成功页面jsp和效果:
<%--
Created by IntelliJ IDEA.
User: 阿煊
Date: 2022/4/10
Time: 13:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册成功提示页面</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
<style>
body,html{
background-color: antiquewhite;;
background-size: 100% ,100%;
}
.logindiv{
width: 350px;
height: 150px;
background-color: white;
opacity: 0.9;
border-radius: 25px;
display: inline-block;
position:absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
margin-top: 0;
box-shadow: 0px,0px,100px,10px,gray;
border-style: outset;
}
</style>
</head>
<body>
<div class="logindiv">
<center>
<div><h1>恭喜注册成功!</h1></div>
<div><h4><%=request.getAttribute("massage") %></h4></div>
</center>
</div>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</body>
</html>
效果:
由于我们在rigesterServlet中写好了三秒后自动跳转的语法,然后我们在前端接收写好的语句,这样就可以实现三秒后自动跳转到登录页面的功能了
同时Cookie的变化:
可以看到,我们已经有一个cookie,并且cookie的name是密码,value是用户名。
接下来我们只需要等待三秒钟,他就会自动跳转到登录页面:
登录页面jsp和效果:
登录界面和注册界面大同小异,只不过在这个页面多了一个使用EL表达式接受错误提示信息的代码,他的作用是当我们用户名或者密码输入错误的时候,会发送错误提示信息给我们。
<%--
Created by IntelliJ IDEA.
User: 阿煊
Date: 2022/4/10
Time: 13:03
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录界面</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
<style>
body,html{
background-color: antiquewhite;;
background-size: 100% ,100%;
}
.logindiv{
width: 350px;
height: 450px;
background-color: white;
opacity: 0.9;
border-radius: 25px;
display: inline-block;
position:absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
box-shadow: 0px,0px,100px,10px,gray;
border-style: outset;
}
.divs{
margin-bottom: 20px;
padding-top: 20px;
}
.font-color{
color: #FF0000;
}
</style>
</head>
<body>
<div class="logindiv">
<center>
<h2>请输入登录信息</h2>
<div class="font-color"><h4>${requestScope.err}</h4></div>
<form action="LoginServlet">
<div><h3>用户名:</h3></div>
<div class="divs"><input type="text" name="Username"></div>
<div><h3>密码:</h3></div>
<div class="divs"><input type="password" name="UserPassword"></div>
<a href="index.jsp">找不到或没有账户?点此注册!</a>
<div><input type="submit" class="btn btn-primary btn-lg " value="登录"></div>
</form>
</center>
</div>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</body>
</html>
效果:
如果密码错误,则会跳转回登录页面,并将错误信息发送给登录页面:
效果如下:
如果密码验证成功,则跳转到系统页面:
系统界面jsp和效果:
<%--
Created by IntelliJ IDEA.
User: 阿煊
Date: 2022/4/10
Time: 13:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>一个很棒的系统</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
<style>
body,html{
background-color: antiquewhite;;
background-size: 100% ,100%;
}
.goodInfo{
width: 260px;
height: 350px;
background-color: white;
opacity: 0.9;
border-radius: 25px;
display: inline-block;
margin: 20px;
padding-top: 20px;
box-shadow: 0px,0px,100px,10px,gray;
border-style: outset;
}
.proPrice{
color: red;
font-weight: 200px;
font-weight: bold;
}
.proName{
font-size: 20px;
font-weight: bold;
}
.add_btn{
background-color: #FF0000;
color: white;
width: 80px;
height: 30px;
border: 0;
font-size: 16px;
box-sizing: content-box;
border-radius: 5px;
}
.add_btn:hover{
background-color:#f66f6a;
}
.top ul{
/* 清除ul标签的默认样式 */
width: auto;/*宽度也改为自动*/
list-style-type: none;
white-space:nowrap;
overflow: hidden;
margin-left: 5%;
/* margin-top: 0; */
padding: 0;
}
.top li {
float:left; /* 使li内容横向浮动,即横向排列 */
margin-right:5%; /* 两个li之间的距离*/
position: relative;
overflow: hidden;
}
.top li a{
/* 设置链接内容显示的格式*/
display: block; /* 把链接显示为块元素可使整个链接区域可点击 */
color:white;
text-align: center;
padding: 3px;
overflow: hidden;
text-decoration: none; /* 去除下划线 */
}
.top li a:hover{
/* 鼠标选中时背景变为黑色 */
background-color: #111;
}
.top ul li ul{
/* 设置二级菜单 */
margin-left: -0.2px;
background:rgb(189, 181, 181);
position: relative;
display: none; /* 默认隐藏二级菜单的内容 */
}
.top ul li ul li{
/* 二级菜单li内容的显示 */
float:none;
text-align: center;
}
.top ul li:hover ul{
/* 鼠标选中二级菜单内容时 */
display: block;
}
.car .check i{
color: #fff;
display: inline-block;
width: 18px;
height: 18px;
line-height: 18px;
border: 1px solid #e0e0e0;
margin-left: 24px;
background-color: #fff;
font-size: 16px;
text-align: center;
vertical-align: middle;
position: relative;
top: 25px;
cursor: pointer;
font-family: "iconfont";
}
.car .img img {
display: block;
width: 80px;
height: 80px;
margin: 3px auto;
}
.car .name span {
line-height: 1;
margin-top: 8px;
margin-bottom: 8px;
font-size: 18px;
font-weight: normal;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.car .price span {
color: #ff6700;
font-size: 16px;
}
.car .ctrl a {
font-size: 20px;
cursor: pointer;
display: block;
width: 26px;
height: 26px;
margin: 30px auto;
line-height: 26px;
}
.car .ctrl a:hover {
color: #FFF;
background: #ff6700;
border-radius: 50%;
}
</style>
</head>
<body>
<hgroup>
<h1>恭喜用户[<%=request.getParameter("Username")%>]登陆成功!</h1>
<h1>您的密码是:[<%= request.getParameter("UserPassword")%>]</h1>
<h1>这是一个很棒的系统,有一点东西,以后会有更多</h1>
<h3>编程也就图一乐~</h3>
<h3><a href="DeleteServlet">点击注销用户[<%=request.getParameter("Username")%>]</a></h3>
</hgroup>
<div id="container">
<div class="goodInfo">
<center>
<img class="imgUrl" src="./img/GG.jpg" name="goodImg" />
<p class="proName">价格低廉,童叟无欺1</p>
<span class="proPrice">¥888</span>
<input class="add_btn" type="button" value="加入购物车" onclick="action()">
</center>
</div>
<div class="goodInfo">
<center>
<img class="imgUrl" src="./img/GG.jpg" name="goodImg" />
<p class="proName">价格低廉,童叟无欺2</p>
<span class="proPrice">¥888</span>
<input class="add_btn" type="button" value="加入购物车">
</center>
</div>
<div class="goodInfo">
<center>
<img class="imgUrl" src="./img/GG.jpg" name="goodImg" />
<p class="proName">价格低廉,童叟无欺</p>
<span class="proPrice">¥888</span>
<input class="add_btn" type="button" value="加入购物车">
</center>
</div>
<div class="goodInfo">
<center>
<img class="imgUrl" src="./img/GG.jpg" name="goodImg" />
<p class="proName">价格低廉,童叟无欺</p>
<span class="proPrice">¥888</span>
<input class="add_btn" type="button" value="加入购物车">
</center>
</div>
<div class="goodInfo">
<center>
<img class="imgUrl" src="./img/GG.jpg" name="goodImg" />
<p class="proName">价格低廉,童叟无欺</p>
<span class="proPrice">¥888</span>
<input class="add_btn" type="button" value="加入购物车">
</center>
</div>
<div class="goodInfo">
<center>
<img class="imgUrl" src="./img/GG.jpg" name="goodImg" />
<p class="proName">价格低廉,童叟无欺</p>
<span class="proPrice">¥888</span>
<input class="add_btn" type="button" value="加入购物车">
</center>
</div>
</div>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</body>
</html>
这里我添加了一些效果,你完全可以不添加这些效果,只保留182行~187行的内容即可。
效果:
可以看到,我使用了<%=>的方式接收了后端传过来的用户名和密码,这就算登陆进我们的系统了,现在我们点击注销用户,就会跳转回登录界面,并且注销我们的cookie。
点击注销用户之后:
我们先看cookie的变化:
可以看到cookie已经消失。
我们再使用张三的用户名和密码登陆的时候已经不能登陆了:
系统的整个流程已经完成了。
可以将项目结构分享给大家:
这里的index.jsp就是我们的注册页面jsp。