期末测验 编程题 登录Demo系统


测验目标

分值(满分50分)

1 项目概述

1.1 需求分析

项目功能需求(14分)

图1 默认项目/ch16_xx/进入登录界面
图2 登录界面输入
图3 主界面及其相应的子资源
图4 登录界面输入错误
图5 主界面未登录进入登录界面
图6 主界面单击【用户注销】调用logout(servlet)转向login_xx.jsp进入登录界面
图7 登录2分钟内,浏览器地址栏输入index.jsp 直接进入主界面

设计、提交要求

2 数据库设计

数据库名: 登录Demo_zjy 数据表名: 用户表_zjy

图8 数据库实现(2分)----高亮要求提交截图

建表语句

-- 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包

图9 项目包名、文件名(2分)
包名 说明
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文件,

图10 jar包

项目中jar_bootstarp文件下载

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 界面设计

图11 BootStrap登录界面(2分)

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>
图12 BootStrap首页界面(2分)

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&amp;useUnicode=true&amp;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);
        }
    }
}

返回