文章目录
- [📍 前置说明](#📍 前置说明)
- [实验一 Web服务器开发环境配置](#实验一 Web服务器开发环境配置)
- [实验二 HTML和Javascript的应用](#实验二 HTML和Javascript的应用)
- [实验三 登录与注册](#实验三 登录与注册)
-
- 一、实验目的
- 二、实验要求
- 三、实验步骤
-
- [3.1 主页 index.jsp](#3.1 主页 index.jsp)
- [3.2 注册页面 zhuce.jsp](#3.2 注册页面 zhuce.jsp)
- [3.3 处理注册 treatZhuCe.jsp](#3.3 处理注册 treatZhuCe.jsp)
- [3.4 注册失败页面 zhuCeFail.jsp](#3.4 注册失败页面 zhuCeFail.jsp)
- [3.5 注册成功页面 zhuCeSuccess.jsp](#3.5 注册成功页面 zhuCeSuccess.jsp)
- [3.6 登录页面 denglu.jsp](#3.6 登录页面 denglu.jsp)
- [3.7 处理登录 treatDengLu.jsp](#3.7 处理登录 treatDengLu.jsp)
- [3.8 登录失败页面 dengLuFail.jsp](#3.8 登录失败页面 dengLuFail.jsp)
- [3.9 登录成功页面 dengLuSuccess.jsp](#3.9 登录成功页面 dengLuSuccess.jsp)
- 四、实验心得
- [实验四 登录与注册](#实验四 登录与注册)
- [实验五 登录与注册(JavaBean)](#实验五 登录与注册(JavaBean))
- [实验六 登录与注册(Servlet)](#实验六 登录与注册(Servlet))
-
- 一、实验目的
- 二、实验要求
- 三、实验步骤
-
- [3.1 index.jsp](#3.1 index.jsp)
- [3.2 zhuce.jsp](#3.2 zhuce.jsp)
- [3.3 zhuCeResult.jsp](#3.3 zhuCeResult.jsp)
- [3.4 denglu.jsp](#3.4 denglu.jsp)
- [3.5 dengLuResult.jsp](#3.5 dengLuResult.jsp)
- [3.6 UserBean.java](#3.6 UserBean.java)
- [3.7 Servlet-treatZhuCe.java](#3.7 Servlet-treatZhuCe.java)
- [3.8 Servlet-treatDengLu.java](#3.8 Servlet-treatDengLu.java)
- 四、实验心得
- [实验七 登录与注册(JDBC)](#实验七 登录与注册(JDBC))
-
- 一、实验目的
- 二、实验要求
- 三、实验步骤
-
- [3.1 创建数据库与表](#3.1 创建数据库与表)
- [3.2 下载 jar 包](#3.2 下载 jar 包)
-
- [① druid-1.1.10.jar](#① druid-1.1.10.jar)
- [② mysql-connector-java-xxx.jar](#② mysql-connector-java-xxx.jar)
- [3.3 将第三方 jar 包添加到项目](#3.3 将第三方 jar 包添加到项目)
- [3.4 数据库配置文件 druid.properties](#3.4 数据库配置文件 druid.properties)
- [3.5 基于 druid 数据库连接池的工具类 JDBCUtilsByDruid](#3.5 基于 druid 数据库连接池的工具类 JDBCUtilsByDruid)
- [3.6 DAO 层-UserDAO](#3.6 DAO 层-UserDAO)
- [3.7 Servlet 层](#3.7 Servlet 层)
-
- [① treatZhuCe.java](#① treatZhuCe.java)
- [② treatDengLu.java](#② treatDengLu.java)
- [3.8 效果演示](#3.8 效果演示)
- 四、实验心得
📍 前置说明
建议从实验一开始从头进行阅读与代码粘贴,因为有些实验的代码是基于前面的实验进行改动。
同时,如果使用的是本文的代码,请将 Tomcat 配置进行如下修改:
实验一 Web服务器开发环境配置
一、实验目的
搭建Web服务器,配置支持Java EE的开发环境。
二、实验内容
Web服务器搭建包括两个部分:
- JDK的安装和配置,Tomcat服务器的安装;
- JavaEE 开发环境包括 IDEA 的安装与配置。
三、实验步骤
3.1 JDK 的安装与配置
🏠 JDK 下载地址:https://www.oracle.com/cn/java/
3.2 IDEA 中配置 Tomcat
⚠️ 注意:不同版本的 IDEA,创建 Java Web 工程的方式可能会有所不同。
🏠 Tomcat 下载地址:https://tomcat.apache.org/
在 IDEA 中配置 Tomcat 之前,需要保证已经下载并解压了 Tomcat 到磁盘。
接下来,我们在 IDEA 中配置 Tomcat:
🏠 Settings --> Build, Execution, Deployment --> Application Servers
配置 Tomcat Server 的位置(根据自己 Tomcat 在磁盘上的安装位置决定):
3.3 创建 Web 工程
我们先创建一个普通项目(或模块),命名为 javaweb02:
为当前项目(或模块)添加模块支持:
🏠 Project Structure --> Project Settings --> Facets
添加 Servlet 相关库:
此时我们再来看项目(或模块结构):
为了稍后方便测试,我们在 web 文件夹下新增一个 index.jsp
文件:
jsp
<%--
Created by IntelliJ IDEA.
User: 狐狸半面添
Date: 2023/10/6
Time: 17:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>狐狸半面添的客栈</title>
</head>
<body>
欢迎来到<a href="https://www.zhulang.love" target="_blank">狐狸半面添的客栈</a>,持续的实战开发技术分享与编程指南。
</body>
</html>
3.4 配置 web 工程
3.5 运行服务
🏠 浏览器访问:http://localhost:8080/
3.6 乱码的解决
如果 Tomcat 日志出现乱码:
解决方案:
-
点击 Help --> Edit custom VM Options
-
在文件最后面添加:
-Dfile.encoding=UTF-8
-
在当前 Tomcat 实例中配置 VM option,添加:
-Dfile.encoding=UTF-8
-
在当前 Tomcat 实例配置界面的 Startup/Connection 页签的 Run 和 Debug 添加一个 key 为
JAVA_TOOL_OPTIONS
,value 为-Dfile.encoding=UTF-8
的环境变量。 -
重启 IDEA;
-
启动服务。
四、实验心得
我们需要安装适合自己操作系统的 JDK,并配置了JAVA_HOME环境变量。这是 Java Web 开发的基础,因为它提供了 Java 编译器和其他必要的工具。
选择合适的 Java Web 服务器,根据自身的需求和项目要求,选择适合的 Java Web 服务器。常见的选择包括 Apache Tomcat、Jetty 和 WildFly 等。了解不同服务器的特点和功能,选择最适合我们项目的服务器。
实验二 HTML和Javascript的应用
一、实验目的
- 掌握HTML文件的编写;
- 掌握表单以及各种标签的使用;
- 掌握表单信息的传递和接收;
- 了解JavaScript技术以及CSS技术。
二、实验要求
- 编写一个注册界面,包括:姓名,密码,性别,爱好,一段自我简介以及确认和重设按钮;
- 扩展一:使用 table 来对注册界面进行格式控制;
- 扩展二:接收表单各种信息并显示;
- 扩展三:分别利用 JavaScript 技术和 JSP 技术实现检查用户名和密码是否为空,并思考分析两种方式各自的优缺点;
- 扩展四:利用 CSS 技术对注册界面进行格式控制。
三、实验步骤
3.1 denglu.html
编写 denglu.html 页面,其中包括表单,用于用户输入注册信息。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录界面</title>
</head>
<body>
<form action="/treat.jsp">
<table>
<tr>
<td>姓名</td>
<td><input name="username" type="text"></td>
</tr>
<tr>
<td>密码</td>
<td><input name="password" type="password"></td>
</tr>
<tr>
<td>性别</td>
<td>
<label>
<input type="radio" name="gender" value="male"> 男
</label>
<label>
<input type="radio" name="gender" value="female"> 女
</label>
</td>
</tr>
<tr>
<td>爱好</td>
<td>
<label>
<input type="checkbox" name="hobby" value="sing"> 唱
</label>
<label>
<input type="checkbox" name="hobby" value="dance"> 跳
</label>
<label>
<input type="checkbox" name="hobby" value="rap"> rap
</label>
<label>
<input type="checkbox" name="hobby" value="basketball"> 篮球
</label>
</td>
</tr>
<tr>
<td style="vertical-align: top">自我介绍</td>
<td><textarea name="introduce" cols="30" rows="10"></textarea></td>
</tr>
</table>
<input type="submit" value="登录">
<input type="reset" value="重置">
</form>
<script>
document.querySelector("[type='submit']").addEventListener("click", evt => {
const username = document.querySelector("[name='username']").value
const password = document.querySelector("[name='password']").value
if (username.trim() === '' || password.trim() === '') {
alert("用户名或密码为空")
evt.preventDefault()
}
})
</script>
</body>
</html>
3.2 treat.jsp
编写treat.jsp页面,接收表单中的各种信息并显示。
jsp
<%@ page import="java.util.Arrays" %>
<%@ page import="java.util.stream.Collectors" %>
<%@ page import="java.util.function.Consumer" %>
<%@ page import="java.util.function.Function" %><%--
Created by IntelliJ IDEA.
User: 狐狸半面添
Date: 2023/10/15
Time: 0:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>处理页面</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username == null
|| username.trim().isEmpty()
|| password == null
|| password.trim().isEmpty()
) {
// 重定向
response.sendRedirect("/denglu.html");
return;
}
Function<String, String> genderFun = gender -> {
if ("male".equals(gender)) {
return "男";
} else if ("female".equals(gender)) {
return "女";
} else {
return "未知";
}
};
String gender = genderFun.apply(request.getParameter("gender"));
String hobby = Arrays.asList(request.getParameterValues("hobby")).stream()
.map(item -> {
String name;
switch (item) {
case "sing":
name = "唱";
break;
case "dance":
name = "跳";
break;
case "rap":
name = "rap";
break;
case "basketball":
name = "篮球";
break;
default:
name = "nothing";
}
return name;
}).collect(Collectors.joining(", "));
String introduce = request.getParameter("introduce");
%>
性别:<%=username%> <br>
密码:<%=password%> <br>
性别:<%=gender%> <br>
爱好:<%=hobby%> <br>
自我介绍:<%=introduce%>
</body>
</html>
3.3 效果演示
四、实验心得
目前主流的技术是前后端分离(比如:SpringBoot + Vue/React),而 JSP 技术使用正在逐渐减少,但使用少和没有使用是两个意思,一些老项目和中小公司还在使用 JSP,工作期间,还是可能遇见 JSP。但我们不必深入学习 JSP,只需要能基本使用,能看得懂,能维护相关项目即可。
JavaScript方式的优点:
- 客户端验证:JavaScript在用户浏览器上执行,可以在用户提交表单之前立即验证用户名和密码是否为空,提供了即时反馈。
- 减轻服务器负担:不需要向服务器发送请求,减少了服务器的负担。
- 用户体验:可以通过JavaScript在页面上直接显示错误消息,提高用户体验。
JavaScript方式的缺点:
- 可被绕过:由于JavaScript在客户端执行,用户可以禁用或修改JavaScript代码,从而绕过验证。
- 安全性:对于安全性要求较高的验证,仅使用JavaScript验证是不够的,还需要在服务器端进行验证。
JSP方式的优点:
- 服务器验证:JSP在服务器端执行,可以在提交表单后进行服务器端验证,确保数据的合法性。
- 可靠性:服务器端验证不受用户篡改或禁用JavaScript的影响,提供了更可靠的验证机制。
JSP方式的缺点:
- 增加服务器负担:需要向服务器发送请求进行验证,增加了服务器的负担。
- 用户体验:服务器端验证需要等待服务器响应,可能会导致用户体验稍差。
实验三 登录与注册
一、实验目的
- 熟练使用 JSP 指令和动作标签;
- 熟练使用 request 等内置对象。
二、实验要求
基本要求:
- 编写主页面 index.jsp,该页面提供两个超链接,分别链接到注册页面和登录页面;
- 编写一个注册页面 zhuce.jsp,包括:用户名,密码,密码确认以及确认和重设按钮;
- 编写一个登录页面 denglu.jsp,包括:用户名,密码以及确认和重设按钮;
- 注册处理页面 treatZhuCe.jsp,分别判断用户名和密码是否为空、密码和密码确认是否相同,并在用户名和密码为空以及密码或密码确认不相同时提示用户,否则提示用户注册成功"您好!注册成功";
- 登录处理页面treatDengLu.jsp,判断用户名和密码是否为空,若为空则提示用户,否则判断用户名是否为"姓名"以及密码是否为"学号",全部相等则显示"您好!登录成功",否则提示用户用户名或密码错误。
扩展要求:
-
基于 Forward 动作标签,将注册处理页面 treatZhuCe.jsp 拆成三个页面:注册处理页面 treatZhuCe.jsp、注册处理结果页面 zhuCeSuccess.jsp 以及zhuCeFail.jsp。其中注册处理页面 treatZhuCe.jsp 负责接收注册页面 zhuce.jsp 传递过来的用户注册信息,并处理信息,根据注册是否成功分别交给注册处理结果页面 zhuCeSuccess.jsp 以及 zhuCeFail.jsp 显示。具体如下图所示:
-
基于 Forward 动作标签,将登录处理页面 treatDengLu.jsp 拆成三个页面:登录处理页面 treatDengLu.jsp、登录处理结果页面 dengLuSuccess.jsp 以及 dengLuFail.jsp。其中登录处理页面 treatDengLu.jsp 负责接收登录页面 denglu.jsp 传递过来的用户登录信息,并处理信息,根据登录是否成功分别交给登录处理结果页面 dengLuSuccess.jsp 以及 dengLuFail.jsp 显示。具体如下图所示:
三、实验步骤
3.1 主页 index.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页</title>
</head>
<body>
<a href="/zhuce.jsp">注册</a>
<a href="/denglu.jsp">登录</a>
</body>
</html>
3.2 注册页面 zhuce.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="/treatZhuCe.jsp">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>确认密码</td>
<td><input type="password" name="confirmPassword"></td>
</tr>
</table>
<input type="submit" value="确认">
<input type="reset" value="重置">
</form>
</body>
</html>
3.3 处理注册 treatZhuCe.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>处理注册</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String confirmPassword = request.getParameter("confirmPassword");
if (username == null || username.trim().isEmpty() || password == null || password.trim().isEmpty() || confirmPassword == null || confirmPassword.trim().isEmpty()) {
%>
<jsp:forward page="/zhuCeFail.jsp">
<jsp:param name="info" value="用户名或密码为空"></jsp:param>
</jsp:forward>
<%
}
if (!password.equals(confirmPassword)) {
%>
<jsp:forward page="/zhuCeFail.jsp">
<jsp:param name="info" value="两次密码不一致"></jsp:param>
</jsp:forward>
<%
}
String info = "您好!" + username + "注册成功!";
%>
<jsp:forward page="/zhuCeSuccess.jsp">
<jsp:param name="info" value="<%=info%>"></jsp:param>
</jsp:forward>
</body>
</html>
3.4 注册失败页面 zhuCeFail.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册失败</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String info = request.getParameter("info");
%>
信息:<%=info%> <br>
<a href="${pageContext.request.contextPath}/index.jsp">回到首页</a>
</body>
</html>
3.5 注册成功页面 zhuCeSuccess.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册成功</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String info = request.getParameter("info");
%>
<%=info%><br>
<a href="${pageContext.request.contextPath}/index.jsp">回到首页</a>
</body>
</html>
3.6 登录页面 denglu.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="/treatDengLu.jsp">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
</table>
<input type="submit" value="确认">
<input type="reset" value="重置">
</form>
</body>
</html>
3.7 处理登录 treatDengLu.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>处理登录</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username == null || username.trim().isEmpty() || password == null || password.trim().isEmpty()) {
%>
<jsp:forward page="/dengLuFail.jsp">
<jsp:param name="info" value="用户名或密码为空"></jsp:param>
</jsp:forward>
<%
}
if ("姓名".equals(username) && "学号".equals(password)) {
String info = "你好,登陆成功";
%>
<jsp:forward page="/dengLuSuccess.jsp">
<jsp:param name="info" value="<%=info%>"></jsp:param>
</jsp:forward>
<%
} else {
%>
<jsp:forward page="/dengLuFail.jsp">
<jsp:param name="info" value="用户名或密码错误"></jsp:param>
</jsp:forward>
<%
}
%>
</body>
</html>
3.8 登录失败页面 dengLuFail.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录失败</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String info = request.getParameter("info");
%>
信息: <%=info%><br>
<a href="${pageContext.request.contextPath}/index.jsp">回到首页</a>
</body>
</html>
3.9 登录成功页面 dengLuSuccess.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录成功</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String info = request.getParameter("info");
%>
<%=info%><br>
<a href="${pageContext.request.contextPath}/index.jsp">回到首页</a>
</body>
</html>
四、实验心得
通过对登录注册的处理,我们其实不难看出 JSP 可以对数据进行校验与处理。
JSP 页面本质上是 Servlet 程序,其性能和 Java 相关。第一次访问 JSP 页面的时候,Tomcat 服务器会把 JSP 页面解析成 Java 源文件,并对它编译称为 class 字节码程序。
实验四 登录与注册
一、实验目的
- 理解Web编程的四个作用范围;
- 熟练掌握各内置对象的使用;
- 熟练掌握application对象和session对象。
二、实验要求
基本要求:
- 编写主页面index.jsp,该页面提供两个超链接,分别链接到注册页面和登录页面;
- 编写一个注册页面zhuce.jsp,包括:用户名,密码,密码确认以及确认和重设按钮;
- 编写一个登录页面denglu.jsp,包括:用户名,密码以及确认和重设按钮;
- 注册处理页面treatZhuCe.jsp,分别判断用户名和密码是否为空、密码和密码确认是否相同,并在用户名和密码为空以及密码或密码确认不相同时提示用户,否则提示用户注册成功"您好!注册成功",并将用户的姓名和密码作为键值对存入application对象中;
- 登录处理页面treatDengLu.jsp,判断用户名和密码是否为空,若为空则提示用户,否则判断用户名和密码是否是application对象中的键值对,如果是则显示"您好!登录成功",并在在session中存入名为"isLogin",值为true的键值对,否则提示用户用户名或密码错误。
扩展要求:
-
基于Forward动作标签,将注册处理页面treatZhuCe.jsp拆成三个页面:注册处理页面treatZhuCe.jsp、注册处理结果页面zhuCeSuccess.jsp以及zhuCeFail.jsp。其中注册处理页面treatZhuCe.jsp负责接收注册页面zhuce.jsp传递过来的用户注册信息,并处理信息,根据注册是否成功分别交给注册处理结果页面zhuCeSuccess.jsp以及zhuCeFail.jsp显示。具体如下图所示:
-
基于Forward动作标签,将登录处理页面treatDengLu.jsp拆成三个页面:登录处理页面treatDengLu.jsp、登录处理结果页面dengLuSuccess.jsp以及dengLuFail.jsp。其中登录处理页面treatDengLu.jsp负责接收登录页面denglu.jsp传递过来的用户登录信息,并处理信息,根据登录是否成功分别交给登录处理结果页面dengLuSuccess.jsp以及dengLuFail.jsp显示。具体如下图所示:
三、实验步骤
相较于实验三,我们只需要做以下调整:
3.1 修改 treatZhuCe.jsp
jsp
<%--
Created by IntelliJ IDEA.
bean.User: 狐狸半面添
Date: 2023/10/15
Time: 1:32
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>处理注册</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String confirmPassword = request.getParameter("confirmPassword");
if (username == null || username.trim().isEmpty() || password == null || password.trim().isEmpty() || confirmPassword == null || confirmPassword.trim().isEmpty()) {
%>
<jsp:forward page="/zhuCeFail.jsp">
<jsp:param name="info" value="用户名或密码为空"></jsp:param>
</jsp:forward>
<%
}
if (!password.equals(confirmPassword)) {
%>
<jsp:forward page="/zhuCeFail.jsp">
<jsp:param name="info" value="两次密码不一致"></jsp:param>
</jsp:forward>
<%
}
// 判断是否已经被注册过了
if (application.getAttribute(username) != null) {
String info = "用户名 `" + username + "` 已被注册,请尝试其它用户名";
%>
<jsp:forward page="/zhuCeFail.jsp">
<jsp:param name="info" value="<%=info%>"></jsp:param>
</jsp:forward>
<%
}
// 将信息存入 application
application.setAttribute(username, password);
String info = "您好!" + username + "注册成功!";
%>
<jsp:forward page="/zhuCeSuccess.jsp">
<jsp:param name="info" value="<%=info%>"></jsp:param>
</jsp:forward>
</body>
</html>
3.2 修改 treatDengLu.jsp
jsp
<%--
Created by IntelliJ IDEA.
bean.User: 狐狸半面添
Date: 2023/10/15
Time: 2:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>处理登录</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username == null || username.trim().isEmpty() || password == null || password.trim().isEmpty()) {
%>
<jsp:forward page="/dengLuFail.jsp">
<jsp:param name="info" value="用户名或密码为空"></jsp:param>
</jsp:forward>
<%
}
String storePassword = (String) application.getAttribute(username);
if (storePassword == null || !storePassword.equals(password)) {
%>
<jsp:forward page="/dengLuFail.jsp">
<jsp:param name="info" value="用户名或密码错误"></jsp:param>
</jsp:forward>
<%
}
// 登录成功
session.setAttribute("isLogin", true);
String info = "你好,+" + username + " 登陆成功";
%>
<jsp:forward page="/dengLuSuccess.jsp">
<jsp:param name="info" value="<%=info%>"></jsp:param>
</jsp:forward>
</body>
</html>
四、实验心得
JSP 内置对象是 Tomcat 在翻译 JSP 页面成为 Servlet 后,内部提供的九大对象。它们可以直接使用,不需要我们再手动定义。
像 application
就对应了 ServletContext
,session
是会话对象。
application
也是域对象,存放的数据在整个 Web 应用运行期间有效。它可以像 Map 一样存取数据。
实验五 登录与注册(JavaBean)
一、实验目的
- 熟练掌握JSP环境下Java类的编写和使用;
- 熟练掌握JavaBean的配置与使用。
二、实验要求
2.1 基本要求
- 编写一个UserBean类,要求该类具有两个属性name和password,并给出两个属性对应的getter和setter方法。
- 编写主页面index.jsp,该页面提供两个超链接,分别链接到注册页面和登录页面;
- 编写一个注册页面zhuce.jsp,包括:用户名,密码,密码确认以及确认和重设按钮;
- 编写一个登录页面denglu.jsp,包括:用户名,密码以及确认和重设按钮;
- 注册处理treatZhuce.jsp。判断用户名和密码是否为空、密码和密码确认是否相同。如果用户名和密码不为空且密码和密码确认相同,则认为注册成功,将用户的姓名和密码生成UserBean类型对象user,并将该对象按照"user"的键名存入application中。否则认为注册失败。处理结果交给zhuCeResult.jsp显示。
- 登录处理页面treatDengLu.jsp,判断用户名和密码是否为空,若为空则提示用户,否则判断用户名和密码是否与application中"user"对象的用户名和密码匹配。如果是则显示"您好!***登录成功",生成UserBean类型对象user,设置user的name和password为用户名和密码,并将user对象按照"user"的键名存入到session中;否则提示用户用户名或密码错误。
2.2 扩展要求
-
基于Forward动作标签,将注册处理页面treatZhuCe.jsp拆成三个页面:注册处理页面treatZhuCe.jsp、注册处理结果页面zhuCeSuccess.jsp以及zhuCeFail.jsp。其中注册处理页面treatZhuCe.jsp负责接收注册页面zhuce.jsp传递过来的用户注册信息,并处理信息,根据注册是否成功分别交给注册处理结果页面zhuCeSuccess.jsp以及zhuCeFail.jsp显示。具体如下图所示:
-
2.基于Forward动作标签,将登录处理页面treatDengLu.jsp拆成三个页面:登录处理页面treatDengLu.jsp、登录处理结果页面dengLuSuccess.jsp以及dengLuFail.jsp。其中登录处理页面treatDengLu.jsp负责接收并处理登录页面denglu.jsp传递过来的用户登录信息,根据登录是否成功分别交给登录处理结果页面dengLuSuccess.jsp以及dengLuFail.jsp显示。具体如下图所示:
三、实验步骤
3.1 添加 UserBean
在 src/bean 下:
java
public class UserBean {
private String name;
private String password;
public UserBean(String name, String password) {
this.name = name;
this.password = password;
}
public UserBean() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
3.2 修改treatZhuCe.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="bean.UserBean" %>
<html>
<head>
<title>处理注册</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String confirmPassword = request.getParameter("confirmPassword");
if (username == null || username.trim().isEmpty() || password == null || password.trim().isEmpty() || confirmPassword == null || confirmPassword.trim().isEmpty()) {
%>
<jsp:forward page="/zhuCeFail.jsp">
<jsp:param name="info" value="用户名或密码为空"></jsp:param>
</jsp:forward>
<%
}
if (!password.equals(confirmPassword)) {
%>
<jsp:forward page="/zhuCeFail.jsp">
<jsp:param name="info" value="两次密码不一致"></jsp:param>
</jsp:forward>
<%
}
// 将信息存入 application
application.setAttribute("user", new UserBean(username, password));
String info = "您好!" + username + "注册成功!";
%>
<jsp:forward page="/zhuCeSuccess.jsp">
<jsp:param name="info" value="<%=info%>"></jsp:param>
</jsp:forward>
</body>
</html>
3.3 修改treatDengLu.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="bean.UserBean" %>
<html>
<head>
<title>处理登录</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username == null || username.trim().isEmpty() || password == null || password.trim().isEmpty()) {
%>
<jsp:forward page="/dengLuFail.jsp">
<jsp:param name="info" value="用户名或密码为空"></jsp:param>
</jsp:forward>
<%
}
UserBean storeUser = (UserBean) application.getAttribute("user");
if (storeUser == null || !storeUser.getName().equals(username) || !storeUser.getPassword().equals(password)) {
%>
<jsp:forward page="/dengLuFail.jsp">
<jsp:param name="info" value="用户名或密码错误"></jsp:param>
</jsp:forward>
<%
}
// 登录成功
session.setAttribute("user", new UserBean(username, password));
String info = "你好," + username + " 登陆成功";
%>
<jsp:forward page="/dengLuSuccess.jsp">
<jsp:param name="info" value="<%=info%>"></jsp:param>
</jsp:forward>
</body>
</html>
四、实验心得
JavaBean 是一种符合特定规范的 Java 类,用于封装数据和提供操作这些数据的方法。它通常被用于在 Web 应用程序中处理业务逻辑和数据交互。
在 JSP 环境下使用和引入 JavaBean 的通常步骤:
- 创建 JavaBean 类;
- 导入 JavaBean 类:在 JSP 文件中,使用
<%@ page import="包名.类名" %>
指令来导入 JavaBean 类。将包名和类名替换为你的 JavaBean 类所在的包名和类名; - 在
<% %>
中使用这个类。
实验六 登录与注册(Servlet)
一、实验目的
- 熟练掌握Servlet的编写和配置;
- 理解Servlet在MVC框架中所处的位置和作用。
二、实验要求
-
编写一个UserBean类,要求该类具有两个属性name和password,并给出两个属性对应的getter和setter方法。
-
编写主页面index.jsp,该页面提供两个超链接,分别链接到注册页面和登录页面;
-
编写一个注册页面zhuce.jsp,包括:用户名,密码,密码确认以及确认和重设按钮;
-
编写一个登录页面denglu.jsp,包括:用户名,密码以及确认和重设按钮;
-
注册处理Servlet:treatZhuCe.java。该Servlet判断用户名和密码是否为空、密码和密码确认是否相同。如果用户名和密码不为空且密码和密码确认相同,则认为注册成功,并将用户的姓名和密码生成UserBean类型对象存入application中。否则认为注册失败。处理结果交给zhuCeResult.jsp显示。
-
登录处理Servlet:treatDengLu.java。该Servlet判断判断用户名和密码是否为空,若不为空,则判断用户名和密码是否为application对象中的键值对。如果用户名和密码是application对象中的键值对,则认为登录成功,生成UserBean对象user,在session对象以"user"的名字存入。其它情况均认为登录失败。处理结果交给dengLuResult.jsp显示。
三、实验步骤
3.1 index.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页</title>
</head>
<body>
<a href="/zhuce.jsp">注册</a>
<a href="/denglu.jsp">登录</a>
</body>
</html>
3.2 zhuce.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="/treatZhuCe">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>确认密码</td>
<td><input type="password" name="confirmPassword"></td>
</tr>
</table>
<input type="submit" value="确认">
<input type="reset" value="重置">
</form>
</body>
</html>
3.3 zhuCeResult.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册结果</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String info = (String) request.getAttribute("info");
%>
信息:<%=info%><br>
<a href="${pageContext.request.contextPath}/index.jsp">回到首页</a>
</body>
</html>
3.4 denglu.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="/treatDengLu">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"></td>
</tr>
</table>
<input type="submit" value="确认">
<input type="reset" value="重置">
</form>
</body>
</html>
3.5 dengLuResult.jsp
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录结果</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String info = (String) request.getAttribute("info");
%>
信息:<%=info%><br>
<a href="${pageContext.request.contextPath}/index.jsp">回到首页</a>
</body>
</html>
3.6 UserBean.java
在 src/bean 下新建 UserBean.java
java
public class UserBean {
private String name;
private String password;
public UserBean(String name, String password) {
this.name = name;
this.password = password;
}
public UserBean() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
3.7 Servlet-treatZhuCe.java
在 src/servlet 下新建 treatZhuCe.java
java
@WebServlet(urlPatterns = {"/treatZhuCe"})
public class treatZhuCe extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置字符集避免乱码
req.setCharacterEncoding("UTF-8");
// 获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String confirmPassword = req.getParameter("confirmPassword");
String info;
if (username == null || username.isEmpty() || password == null || password.isEmpty() || confirmPassword == null || confirmPassword.isEmpty()) {
info = "用户名或密码为空";
} else if (!password.trim().equals(confirmPassword)) {
info = "两次密码不一致";
} else {
// 将信息存入 application
this.getServletContext().setAttribute("user", new UserBean(username, password));
info = "您好!" + username + "注册成功!";
}
req.setAttribute("info", info);
req.getRequestDispatcher("/zhuCeResult.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.8 Servlet-treatDengLu.java
在 src/servlet 下新建 treatDengLu.java
java
@WebServlet(urlPatterns = {"/treatDengLu"})
public class treatDengLu extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置字符集避免乱码
req.setCharacterEncoding("UTF-8");
// 获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String info;
if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
info = "用户名或密码为空";
} else {
ServletContext application = this.getServletContext();
UserBean user = (UserBean) application.getAttribute("user");
if (user.getName().equals(username) && user.getPassword().equals(password)) {
req.getSession().setAttribute("user", new UserBean(username, password));
info = "你好," + username + " 登陆成功";
} else {
info = "用户名或密码错误";
}
}
req.setAttribute("info", info);
req.getRequestDispatcher("/dengLuResult.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
四、实验心得
在 MVC(Model-View-Controller)框架中,Servlet 扮演着 Controller(控制器)的角色。它负责接收用户的请求并根据请求的类型和参数来决定如何处理请求。Servlet 从用户界面(View)接收输入,并将其传递给模型(Model)进行处理。
实验七 登录与注册(JDBC)
一、实验目的
- 学会安装MySQL数据库;
- 熟练掌握JDBC;
- 理解登录和注册在数据库中的体现。
二、实验要求
-
编写一个UserBean类,要求该类具有两个属性name和password,并给出两个属性对应的getter和setter方法。
-
在MySQL数据库中新建wgw数据库,并建立名为tb_user的用户信息表,tb_user表包括name和password两个属性,此两个属性均为varchar(50)类型,均不为空,name为主键。
-
编写主页面index.jsp,该页面提供两个超链接,分别链接到注册页面和登录页面;
-
编写一个注册页面zhuce.jsp,包括:用户名,密码,密码确认以及确认和重设按钮;
-
编写一个登录页面denglu.jsp,包括:用户名,密码以及确认和重设按钮;
-
注册处理Servlet:treatZhuCe.java。该Servlet判断用户名和密码是否为空、密码和密码确认是否相同。如果用户名和密码不为空且密码和密码确认相同,则认为注册成功,并将用户的姓名和密码存入到数据库wgw的tb_user表中。否则认为注册失败。处理结果交给zhuCeResult.jsp显示。
-
登录处理Servlet:treatDengLu.java。该Servlet判断判断用户名和密码是否为空,若不为空,在数据库wgw的tb_user表中查询用户名和密码是否匹配。如果匹配则认为登录成功,生成UserBean对象user,在session对象以"user"的名字存入。其它情况均认为登录失败。处理结果交给dengLuResult.jsp显示。
三、实验步骤
最终项目结构:
基于实验六进行改动即可,所有的 jsp 文件与 Javabean 无需改动。
3.1 创建数据库与表
数据库安装参考:https://blog.csdn.net/qq_62982856/article/details/127768220
sql
CREATE DATABASE wgw;
USE wgw;
CREATE TABLE tb_user (
`name` VARCHAR(50) NOT NULL PRIMARY KEY COMMENT '用户名',
`password` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '密码'
);
3.2 下载 jar 包
这里我们需要下载两个 jar 包,由于我在这里是直接访问外网,因此如果你的网速不行请切换为流量。
- mysql-connector-java-xxx.jar:mysql 的 java 驱动程序库;
- druid-1.1.10.jar:采用阿里巴巴提供的 druid 作为数据库连接池。
① druid-1.1.10.jar
🏠 下载地址:https://repo1.maven.org/maven2/com/alibaba/druid/1.1.10/
② mysql-connector-java-xxx.jar
这里需要特别注意,需要下载的数据库驱动 jar 包根据你的 mysql 版本会有所不同。
查看自己的mysql版本:
mysqld --version
1️⃣ 如果你是mysql5.7的版本
🏠 下载地址:https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.37/
2️⃣ 如果你是mysql8.0的版本
🏠 下载地址:https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.16/
3.3 将第三方 jar 包添加到项目
在 web/WEB-INF 下创建一个 lib
文件夹,将 commons-dbutils、druid、mysql-connector-java 拷贝到 lib 文件夹下。
由于我装的是 mysql8.0 的版本,因此我使用的 mysql jar 包是 mysql-connector-java-8.0.16.jar。
3.4 数据库配置文件 druid.properties
在 src 下创建 druid.properties
properties
# key=value
# 如果 mysql 版本是 5.7,需要将 driverClassName 的值修改为 com.mysql.jdbc.Driver
# 如果 mysql 版本是 8.0,需要将 driverClassName 的值修改为 com.mysql.cj.jdbc.Driver
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/wgw?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username=root
password=123456
# initial connection Size
initialSize=10
# min idle connecton size
minIdle=5
# max active connection size
maxActive=50
# max wait time (5000 mil seconds)
maxWait=5000
3.5 基于 druid 数据库连接池的工具类 JDBCUtilsByDruid
在 src/utils 下创建 JDBCUtilsByDruid.java
java
public class JDBCUtilsByDruid {
private static DataSource dataSource;
static {
try {
Properties properties = new Properties();
// 因为我们是web项目,他的工作目录在out, 文件的加载,需要使用类加载器
// 找到我们的工作目录
properties.load(JDBCUtilsByDruid.class.getClassLoader().getResourceAsStream("druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// 关闭连接
public static void close(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection) {
try {
if (resultSet != null) {
resultSet.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
3.6 DAO 层-UserDAO
在 src/dao 下创建 UserDAO.java
java
public class UserDAO {
// 查询某个用户是否存在
public boolean existUsername(String username) {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
Connection conn = null;
try {
// 获取连接
conn = JDBCUtilsByDruid.getConnection();
// 预处理方式
preparedStatement = conn.prepareStatement("SELECT 1 FROM tb_user WHERE `name` = ?");
// 设置第一个问号的参数值
preparedStatement.setString(1, username);
// 执行查询
resultSet = preparedStatement.executeQuery();
// 如果查询到一条记录,则说明用户存在
return resultSet.next();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接
JDBCUtilsByDruid.close(resultSet, preparedStatement, conn);
}
return false;
}
// 将注册用户保存到 tb_user
public void insert(String username, String password) {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
Connection conn = null;
try {
// 获取连接
conn = JDBCUtilsByDruid.getConnection();
// 预处理方式
preparedStatement = conn.prepareStatement("INSERT INTO tb_user(`name`, `password`) VALUES(?, ?)");
// 设置第一个问号的参数值
preparedStatement.setString(1, username);
// 设置第二个问号的参数值
preparedStatement.setString(2, password);
// 执行查询
int updateNums = preparedStatement.executeUpdate();
// 如果执行成功,updateNums >= 1
if (updateNums == 0) {
throw new RuntimeException("服务器与数据库发生未知错误");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接
JDBCUtilsByDruid.close(resultSet, preparedStatement, conn);
}
}
// 验证用户登录
public boolean existUsernameAndPassword(String username, String password) {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
Connection conn = null;
try {
// 获取连接
conn = JDBCUtilsByDruid.getConnection();
// 预处理方式
preparedStatement = conn.prepareStatement("SELECT 1 FROM tb_user WHERE `name` = ? AND `password` = ?");
// 设置第一个问号的参数值
preparedStatement.setString(1, username);
// 设置第二个问号的参数值
preparedStatement.setString(2, password);
// 执行查询
resultSet = preparedStatement.executeQuery();
// 如果查询到一条记录,则说明用户存在
return resultSet.next();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接
JDBCUtilsByDruid.close(resultSet, preparedStatement, conn);
}
return false;
}
}
3.7 Servlet 层
① treatZhuCe.java
在 src/servlet 下创建 treatZhuCe.java
java
@WebServlet(urlPatterns = {"/treatZhuCe"})
public class treatZhuCe extends HttpServlet {
private UserDAO userDAO = new UserDAO();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置字符集避免乱码
req.setCharacterEncoding("UTF-8");
// 获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String confirmPassword = req.getParameter("confirmPassword");
String info;
if (username == null || username.isEmpty() || password == null || password.isEmpty() || confirmPassword == null || confirmPassword.isEmpty()) {
info = "用户名或密码为空";
} else if (!password.trim().equals(confirmPassword)) {
info = "两次密码不一致";
} else if (userDAO.existUsername(username)) {
// 判断是否在数据库中已存在
info = "用户已存在,注册失败";
} else {
// 注册
userDAO.insert(username, password);
info = "您好!" + username + "注册成功!";
}
req.setAttribute("info", info);
req.getRequestDispatcher("/zhuCeResult.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
② treatDengLu.java
在 src/servlet 下创建 treatDengLu.java
java
@WebServlet(urlPatterns = {"/treatDengLu"})
public class treatDengLu extends HttpServlet {
private final UserDAO userDAO = new UserDAO();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置字符集避免乱码
req.setCharacterEncoding("UTF-8");
// 获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String info;
if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
info = "用户名或密码为空";
} else if (userDAO.existUsernameAndPassword(username, password)) {
req.getSession().setAttribute("user", new UserBean(username, password));
info = "你好," + username + " 登陆成功";
} else {
info = "用户名或密码错误";
}
req.setAttribute("info", info);
req.getRequestDispatcher("/dengLuResult.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.8 效果演示
如果重复注册相同用户名:
四、实验心得
传统的JDBC数据库连接使用 DriverManager 连接的时候都要将 Connection 加载到内存中再验证IP地址,用户名和密码。需要数据库连接的时候就向数据库要求一个,频繁的进行数据库连接操作将占用很多的系统资源,容易造成服务器崩溃。每一次数据库连接,使用完后都得断开,如果程序出现异常而未能关闭,将导致数据库内存泄漏,最终将导致重启数据库。使用数据库连接池技术可以得到一定的安全性保证与性能提升。