文章目录
1 实现代码
实现要求:
前面我们实现了用户登录功能,当时我们要求用户登录成功后,跳转到
success.html 页面,现在需要做需求迭代,用户登录成功后,要求跳转到
success.jsp 页面,这个页面展示登录成功后的用户姓名,格式为:欢迎您,XXX
退出。当用户点击退出按钮时,清除 session,跳回到登录页面。
1.1 思路
- 首先login.html不用大改,只要修改form的提交地址(action),修改为"login_result.jsp"(注意action的首位没有
/
)。 - 在login_result.jsp中实现之前servlet的验证,并且根据验证结果显示相应的标签。如果登录成功显示一个"退出"按钮,跳转到另一个jsp去做session失效和跳转回登录界面的功能。
- 在invalidate_session.jsp中就进行一个操作:让session失效,并且跳转回登录界面。
1.2 login.html
和V1不同的是,修改了提交的地址,从servlet变为jsp。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<script src="js/jquery-1.11.1.js"></script>
<script src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="css/bootstrap-theme.css" />
<script>
$(function(){
$("#myForm").submit(function(){
var flag = validateUserName() && validatePassword();
if(!flag){
alert("有字段未完成!");
return false;
}else {
return true;
}
});
$("#userName").keyup(function(){
validateUserName();
});
$("#userPass").keyup(function(){
validatePassword();
});
});
function validateNull(value) {
return !(value == null || value === "");
}
//用户名验证规则:必须是超过6位数,仅允许数字、大写字母、小写字母、下划线,不能以下划线开头
function validateUserName() {
var userName = $("#userName").val();
var regex = /[A-Za-z0-9]\w+/;
var msg = $("#userNameMsg");
if(regex.test(userName)) {
msg.css("color", "green");
msg.html("用户名合法");
return true;
} else {
if(!validateNull(userName)) {
msg.html("输入不为空!");
} else if(userName.match(/_\w*/)) {
msg.html("第一个字符不允许为下划线!");
} else if(userName.length < 2) {
msg.html("用户名必须至少2位");
} else {
msg.html("包含非法字符!仅允许数字、字母、下划线");
}
msg.css("color", "red");
return false;
}
}
//密码验证规则:必须是超过6位数,包含数字、大写字母、小写字母
function validatePassword() {
var password = $("#userPass").val();
var regex1 = /[0-9]+[a-z]+[A-Z]+/;
var regex2 = /[a-z]+[0-9]+[A-Z]+/;
var regex3 = /[0-9]+[A-Z]+[a-z]+/;
var regex4 = /[a-z]+[A-Z]+[0-9]+/;
var regex5 = /[A-Z]+[0-9]+[a-z]+/;
var regex6 = /[A-Z]+[a-z]+[0-9]+/;
var msg = $("#passwordMsg");
if(password.length < 6) {
msg.html("长度不足6位!");
msg.css("color", "red");
return false;
}
if(regex1.test(password) || regex2.test(password) || regex3.test(password) || regex4.test(password) || regex5.test(password) || regex6.test(password)) {
msg.html("密码有效");
msg.css("color", "green");
return true;
} else {
if(!validateNull(password)) {
msg.html("输入为空!");
} else {
msg.html("密码无效,必须包含数字、大小写字母!");
}
msg.css("color", "red");
return false;
}
}
</script>
</head>
<body>
<div class="container">
<h2 class="text-center">用户登录</h2>
<form id="myForm" role="form" class="form-horizontal" action="login_result.jsp" method="post">
<div class="form-group">
<label class="control-label col-sm-1" for="userName">用户名:</label>
<div class="col-sm-5">
<input class="form-control" type="text" name="name" id="userName"/>
</div>
<div class="col-sm-6">
<label id="userNameMsg" class="control-label text-info">仅允许数字、大小写字母、下划线,第一个字符不能为下划线</label>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-1" for="userPass">密码:</label>
<div class="col-sm-5">
<input type="password" class="form-control" name="pass" id="userPass"/>
</div>
<div class="col-sm-6">
<label id="passwordMsg" class="control-label text-info text-left">密码至少6位,需要包含大小写字母和数字</label>
</div>
</div>
<div class="form-group text-center">
<button type="submit" class="btn btn-info col-sm-3 col-sm-offset-3">登录</button>
<button type="reset" class="btn btn-normal col-sm-3">重置</button>
</div>
</form>
</div>
</body>
</html>
1.3 login_result.jsp
登录界面提交后即跳转到此页面。这里使用了EL表达式和JSTL标签库。标签库使用了核心库c和数据库sql。
<%@ page import="com.kkb.xzk.validation.DatabaseValidation" %>
<%@ page import="java.sql.SQLException" %><%--
Created by IntelliJ IDEA.
User: handi
Date: 2021/7/23
Time: 11:16
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=GBK" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%>
<html>
<head>
<title>登录结果</title>
<script src="js/jquery-1.11.1.js"></script>
<script src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="css/bootstrap-theme.css" />
</head>
<body>
<sql:setDataSource var="userDatabase" driver="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb6?serverTimeZone=UTC" user="root" password="123456"></sql:setDataSource>
<sql:query var="result" dataSource="${userDatabase}" sql="select userpass from user where username=?">
<sql:param value="${param.name}"></sql:param>
</sql:query>
<c:choose>
<c:when test="${!(empty result)}">
<c:forEach var="row" items="${result.rows}">
<c:if test="${row.userpass == param.pass}">
<h1>欢迎您!${param.name}</h1>
<form action="invalidate_session.jsp" method="post">
<button type="submit" class="btn btn-default">退出</button>
</form>
</c:if>
</c:forEach>
</c:when>
<c:otherwise>
<h1>登录失败!</h1>"
</c:otherwise>
</c:choose>
</body>
</html>
1.4 invalidate_session.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%session.invalidate();%>
<%response.sendRedirect("login.html");%>
</body>
</html>
2 注意点
2.1 不能在javascript标签中通过jsp进行session失效操作
以下做法是错误的。
<script>
$(function(){
$("#exit").click(function(){
<%session.invalidate();%>
});
});
</script>
这个做法会导致session直接失效,而不是点击按钮后才失效。因为<%session.invalidate();%>这句话是一个执行操作,相当于浏览器解析到这里直接就执行了。
正确做法是,用form包裹住button,点击button后跳转到一个单独的jsp用于进行session失效。
2.2 表单数据接收
一定要注意,EL表达式大括号内的参数必须是xxx.setAttribute()
方式设置的参数名称。而表单数据提交后实际保存在了request的parameters里,在普通JSP代码中取出是这样的:
用户名:<%=request.getParameter("userName") %>
那么使用EL表达式时,正确的操作是使用隐藏对象param来获得。
用户名:${param.userName}
2.3 使用JSTL操作数据库
正确做法:
<sql:setDataSource var="userDatabase" driver="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb6?serverTimeZone=UTC" user="root" password="123456"></sql:setDataSource>
<sql:query var="result" dataSource="${userDatabase}" sql="select userpass from user where username=?">
<sql:param value="${param.name}"></sql:param>
</sql:query>
需要注意的是,不能通过拼接的方式设置sql语句,比如:
<sql:query var="result" dataSource="${userDatabase}" sql="select userpass from user where username=${param.name}">
,这样是取不到的。
应该用预状态通道的sql语句,?的设置通过sql:param标签实现。