期末测验 编程题 登录Demo系统
测验目标
- 熟练掌握JSP网页设计
- 熟练掌握Servlet程序设计
- 熟练掌握Filter程序设计
- 熟练掌握DB访问技术(Dao,Service,Servlet)
分值(满分50分)
- 完成项目功能需求(14分)
- 数据库实现(2分--1个截图)
- 项目搭建(6分--1个截图、2个xml文件)
- 界面实现(8分--2个jsp代码、2个截图)
- Java代码(20分--7个java文件)
1 项目概述
1.1 需求分析
项目功能需求(14分):
- ①默认项目/ch16_xx/进入登录界面,如图1所示。
- ②登录界面输入:管理员-123456或 个人姓名-个人学号进入主界面index.jsp,如图2所示。
- ③进入主界面index.jsp点击相应的链接打开相应的资源,如图3所示。。
- ④登录界面输入错误的用户名和或密码,重新进入登录界面并指出错误,如图4所示。。
- ⑤登出后或未登录,浏览器地址栏输入:http://ip地址:8080/ch16_xx/index.jsp 进入登录界面,如图5所示。
- ⑥登录2分钟因会话超时,浏览器地址栏输入:http://ip地址:8080/ch16_xx/index.jsp 进入登录界面,如图5所示。
- ⑦登录2分钟内,浏览器地址栏输入:http://ip地址:8080/ch16_xx/index.jsp 直接进入主界面。
设计、提交要求
- ① 系统版本要求 Tomcat 9、servlet 4、MySql 8、html5;
- ② 数据库中数据表字段用汉字命名,名、表名后加下划线和姓名拼音缩写;
- ③ Java ee项目中包名为cn.xxx.开始,其中xxx姓名拼音首字母缩写(小写);
- ④ Java ee项目中java源代码(除DataSourceUtils.java外)、页面的jsp(除index.jsp外)文件名后加下划线和姓名拼音字母首缩写;
- ⑤ Java ee项目要单独部署到阿里云中,数据库部署到云端的mysql数据库,项目及在线md文档要求在2024.06.20 23:00之前部署个人云端,并保证在正常运行15天;
- ⑥ 项目要求在2024.06.20 23:00之前将开发md文档(填上完整的代码)及图片(高亮要求的截图)、源代码包、IP及密码.doc打包成xxxxxxxxx-XXX《登录Demo系统》作业.zip(其中:xxxxxxxxx学号,XXX中文姓名)向122234434@qq.com邮箱提交存档。
2 数据库设计
数据库名: 登录Demo_zjy 数据表名: 用户表_zjy
建表语句
-- 1. 用户
DROP TABLE IF EXISTS `用户表_zjy`;
CREATE TABLE `用户表_zjy` (
`用户名` varchar(45) NOT NULL PRIMARY KEY,
`密码` varchar(45) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `用户表_zjy` VALUES
('管理员','123456'),
('张婧怡','山西省晋中市');
3 项目实现
3.1 确定项目开发环境
Tomcat9.0 MySQL 8.0 JDK8
3.2 创建数据库表
见上述数据库部分
3.3 创建项目、包名、引入JAR包
| 包名 | 说明 |
|---|---|
| cn.zjy.utils | 工具类:数据源工具、单价计算器工具 |
| cn.zjy.model | JavaBean类 |
| cn.zjy.dao | 数据访问 |
| cn.zjy.service | 服务层 |
| cn.zjy.servlet | web servlet层 |
| cn.zjy.filter | 过滤器 |
jar包 在web/WEB-INF创建lib文件夹,并粘贴下列5个jar文件,
web/WEB-INF/web.xml(2分)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<welcome-file-list>
<welcome-file>login_zjy.jsp</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>2</session-timeout>
</session-config>
</web-app>
3.3 界面设计
web/login_zjy.jsp(2分)
<%@ page contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>张婧怡的登录Demo系统.登录</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<style>
body{
width: 100%;
height: 100%;
overflow: hidden;
background: url(Images/bg.png) no-repeat;
background-size: 100% 100%;
background-attachment: fixed;
}
form{
width: 400px;
margin: 200px auto;
padding: 20px 30px;
background-color: rgba(255, 255, 255, 0.8);
}
form div{
margin-bottom:10px;
}
a:link, a:visited, a:hover, a:active {
text-decoration: none;
color: rgba(0, 0, 0, 0.5);
}
</style>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<form action="login" method="post" onsubmit="return login()">
<div style="margin-bottom:20px;">
<h4 style="text-align:center;">张婧怡的登录Demo系统.登录</h4>
</div>
<div class="form-group has-success has-feedback">
<input type="text" class="form-control" name="姓名" placeholder="用户名" value="${uname}">
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
<div class="form-group has-success has-feedback">
<input type="password" class="form-control" name="口令" placeholder="密码" value="${upass}">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="d-grid gap-1">
<button type="submit" class="btn btn-primary btn-lg btn-block">登录</button>
</div>
<div style="color: red">
${failMsg }
</div>
</form>
</div>
</body>
</html>
web/index.jsp(2分)
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>张婧怡的登录Demo系统</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<style>
body{
width: 100%;
height: 100%;
overflow: hidden;
background: url(Images/bg.png) no-repeat;
background-size: 100% 100%;
background-attachment: fixed;
}
ul a{
width: 400px;
background-color: rgba(255, 255, 255, 0.8);
}
<!-- 通过background-color设置点击状态的背景颜色 B2FF99 FFFF85 -->
a:link {background-color:#FFFF85;}
a:visited {background-color:#B2FF99;}
a:hover {background-color:#FF704D;}
a:active {background-color:#FF704D;}
</style>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<h3>张婧怡的登录Demo系统</h3>
<hr>
<p>用户名:${sessionScope.user.用户名} | <a href="logout">用户注销</a></p>
<ul class="list-group nav nav-pills">
<li><a class="list-group-item list-group-item-success" href="index.jsp">首页 index.jsp</a></li>
<li><a class="list-group-item list-group-item-success" href="test.html">访问test.html</a></li>
<li><a class="list-group-item list-group-item-success" href="test.txt">访问test.txt(GBK编码)</a></li>
<li><a class="list-group-item list-group-item-success" href="zjy.jpg">访问zjy.jpg</a></li>
<li><a class="list-group-item list-group-item-success" href="abcd.jpg">访问不存在的abcd.jpg</a></li>
<li><a class="list-group-item list-group-item-success" href="sub/test2.html">访问sub/test2.html</a></li>
<li><a class="list-group-item list-group-item-success" href="sub/test2.txt">访问sub/test2.txt(GBK编码)</a></li>
<li><a class="list-group-item list-group-item-success" href="sub/zjy2.jpg">访问sub/zjy2.jpg</a></li>
<li><a class="list-group-item list-group-item-success" href="sub/abcd.jpg">访问不存在的sub/abcd.jpg</a></li>
</ul>
<hr>
</body>
</html>
3.4 配置c3p0-config.xml文件
src\c3p0-config.xml(2分)
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://www.zjyzhaojiang.cn:3306/登录Demo_zjy?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8</property>
<property name="user">root</property>
<property name="password">********</property>
</default-config>
</c3p0-config>
3.5 DBUtils工具类
cn.zjy.utils.DataSourceUtils(2分)
package cn.zjy.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class DataSourceUtils {
// 读取 src/c3p0-config.xml 配置信息,生成静态final变量 ds
private static final DataSource ds=new ComboPooledDataSource();
// 静态方法 getDataSource() 获取数据源
public static DataSource getDataSource(){
return ds;
}
// 静态方法 getConnection() 获取数据库连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
3.6 model
cn/zjy/model/User_zjy.java(2分)
package cn.zjy.model;
import lombok.Data;
@Data
public class User_zjy {
private String 用户名;
private String 密码;
}
3.7 dao
cn/zjy/dao/UserDao_zjy.java(2分)
package cn.zjy.dao;
import cn.zjy.model.User_zjy;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import cn.zjy.utils.DataSourceUtils;
import java.sql.SQLException;
public class UserDao_zjy {
public User_zjy selectByUsernamePassword(String username,String password) throws SQLException {
QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
String sql = "select * from 用户表_zjy where 用户名=? and 密码=?";
return r.query(sql, new BeanHandler<User_zjy>(User_zjy.class),username,password);
}
}
3.8 service
cn/zjy/service/UserService_zjy.java(2分)
package cn.zjy.service;
import cn.zjy.dao.UserDao_zjy;
import cn.zjy.model.User_zjy;
import java.sql.SQLException;
public class UserService_zjy {
private UserDao_zjy uDao = new UserDao_zjy();
public User_zjy login(String username, String password) {
User_zjy user = null;
try {
user = uDao.selectByUsernamePassword(username, password);
} catch (SQLException e) {
e.printStackTrace();
}
if (user != null) {
return user;
}
return null;
}
}
3.8 servlet
cn/zjy/servlet/LoginServlet_zjy.java(4分)
package cn.zjy.servlet;
import cn.zjy.service.UserService_zjy;
import cn.zjy.model.User_zjy;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet_zjy extends HttpServlet {
private UserService_zjy uService = new UserService_zjy();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String uname = request.getParameter("姓名");
String password = request.getParameter("口令");
User_zjy user = uService.login(uname, password);
if (user == null) {
request.setAttribute("uname", uname);
request.setAttribute("upass", password);
request.setAttribute("failMsg", "用户名、邮箱或者密码错误,请重新登录!");
request.getRequestDispatcher("/login_zjy.jsp").forward(request, response);
} else {
request.getSession().setAttribute("user", user);
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
}
}
cn/zjy/servlet/LogoutServlet_zjy.java(2分)
package cn.zjy.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/logout")
public class LogoutServlet_zjy extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getSession().removeAttribute("user");
request.getSession().invalidate();
request.getRequestDispatcher("/login_zjy.jsp").forward(request, response);
}
}
3.9 编写登录过滤器
cn.zjy.filter.LoginFilter_zjy.java(6分)
登录过滤器:登录用户可访问/* 所有资源,用户没有登录仅可访问 跳转到首页
package cn.zjy.filter;
import cn.zjy.model.User_zjy;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(value = "/*")
public class LoginFilter_zjy implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
// 由于设置Filter过滤全部请求,可以排除不需要过滤的url
String requestURI = request.getRequestURI();
if (requestURI.endsWith("login")) {
chain.doFilter(req, resp);
return;
}
if (requestURI.endsWith("login_zjy.jsp")) {
chain.doFilter(request, resp);
return;
}
if (requestURI.endsWith("png")) {
chain.doFilter(req, resp);
return;
}
if (requestURI.endsWith("css")) {
chain.doFilter(req, resp);
return;
}
if (requestURI.endsWith("map")) {
chain.doFilter(req, resp);
return;
}
if (requestURI.endsWith("js")) {
chain.doFilter(req, resp);
return;
}
User_zjy u = (User_zjy) request.getSession().getAttribute("user");
// 判断用户是否登录,进行页面的处理
if (u == null) {
// 未登录用户,转向到登录页面
request.getRequestDispatcher("/login_zjy.jsp").forward(request, response);
return;
} else {
// 已登录用户,允许访问
chain.doFilter(request, response);
}
}
}