javaweb课程设计,《卖淘乐》后台管理系统,开发帮助文档

项目展示效果

图4.1管理员登录图 

 图4.2登录成功图

图4.3登录失败图 

 图4.4超级管理员主页面

图4.5普通管理员主页面 

图4.6业务员主页面 

 图4.7菜单选项全部启用图

图4.7菜单选项部分禁用图 

图4.9角色查询图

图4.10角色添加图

图4.11角色添加成功图 

图4.12角色删除图

 图4.13角色删除成功图

 

图4.14角色修改成功图

一、问题定义

1.1《卖淘乐》后台管理系统介绍

 《卖淘乐》后台管理系统就是对卖淘乐系统进行管理的一个系统,对数据进行管理和维护。

1.2《卖淘乐》系统

卖淘乐非传统电商,用户如果有闲置的手机,可以通过此平台进行估价和交易,也就是二手数码电子物品回收系统。

二、可行性研究

技术:JDBC(Druid,commons-dbutils),Servlet,JQuery,Ajax,MySql

三、《卖淘乐》后台管理系统功能需求分析(需求分析)

3.1二手手机回收业务流程

3.2《卖淘乐》后台管理系统功能清单

 四、《卖淘乐》后台管理系统业务流程(概要设计)

4.1系统的业务流程

4.1.1HIPO图

项目的层次结构图:列出系统的功能,并建立起功能之间的层次关系。

4.1.2管理员登录的流程图 

功能说明:

功能名称

管理员登录

功能说明

管理员通过登录界面,输入登录信息,验证登录界面是否合法

输入项

登录账号,登录密码,登录验证码

处理

首先验证接收的登录验证码是否正确,再判断账号和密码。

输出项

如果登录成功则进入系统管理的首页,登录失败则进入登录页面并进行提示。

4.2系统的数据库设计

4.2.1数据库需求分析

4.2.1.1数据流图设计

1.产品业务数据流图:

2.用户数据流图:

 3.系统数据流图:

 

4.总体数据流图: 

五、详细设计

5.1管理员登录实现流程设计

1. 进⼊系统显示登录⻚⾯,管理员输⼊账号、密码点击登录按钮进⾏提交;

2. 账号和密码提交到ManagerLoginServlet类,在ManagerLoginServlet中接收账号和密

码,调⽤ManagerService验证账号和密码是否正确;

3. ManagerService先调⽤ManagerDAO中的⽅法,根据管理员名称查询管理员信息,将查

询结果返回给ManagerService;

4. 在ManagerService中:

如果ManagerDAO返回的信息为空,则表示根据⽤户输⼊的管理员登录账号没有查

询到管理员信息(账号不存在),就返回给ManagerLoginServlet⼀个null值

如果ManagerDAO返回的信息不为空,表示管理员账号是正确的,然后校验输⼊的

密码与查询的管理员信息密码是否⼀致:

如果密码不⼀致,则返回给ManagerLoginServlet⼀个null值;

如果密码⼀致,则返回给ManagerLoginServlet管理员对象;

5. ManagerLoginServlet接收ManagerService返回的验证结果:

如果返回的是null,则表示账号或者密码错误,转发到login.jsp并提示 ;

如果返回的管理员对象,则表示账号和密码都正确,将管理员信息存放到session中,跳转到index.jsp。

5.2登录认证过滤器

  1. 管理员登录成功后,将管理员信息存储到session中

创建登录过滤器拦截所有用户请求,然后在doFilter方法中写登录过滤器的拦截规则。

 

5.3密码的加密加盐

  1. 为了保证用户信息的安全性,防止黑客进入攻破数据库后得到用户完全透明的密码,在数据库中对用户密码进行加密。
  2. 加密后的密码数据从明文转换成密文,并以密文的方式存储在用户信息的密码字段。
  3. 当黑客攻破数据库后得到密码转换的密文,并在登录页面输入密码的密文是不能成功登录的,如果想成功登录只能输入密码的明文。
  4. 密码的明文转换成密文,和密文转换成明文都是根据加密规则进行转换的。

5.3.1加密方式

  1. 对称加密:明文按照一定规则加密成密文,这个密文可以按照对应的规则解密成明文。(隐患:当黑客知道加密规则后就可以解密,如base64)
  2. 非对称加密:明文按照一定规则加密成密文,密文没有对应的规则解密成明文。(加密后的明文是不能解密的,如MD5),但现在网上已经有了非对称加密的加密解密网址,如果黑客到的用户的密码的密文在该网站上输入密文,就可以得到该密码的明文(理论上加密后的明文是不能解密的,但这些网站通过穷举法就可以解密,底层原理十分复杂,规避方法为设置用户密码时不能为纯数字,或者对加密后的密文进行再次加密,但不能保证完全规避)

5.3.2加盐

为了有效应对黑客通过穷举法破解非对称加密,对用户输入的明文进行加盐后,再进行非对称加密操作。

加盐是在用户输入密码明文后进行,对密码明文的前面后面或者中间某个位置加入自定义的字符串,然后通过非对称加密加密技术(MD5)进行加密,得到的密文存储到数据库中,这样即使黑客攻破了数据库拿到了加密后的密文,并对密文通过穷举法进行转换,转换后也得不到正确的密文,而是得到用户密码和加盐后的字符串(还是建议密码不是纯数字)。

 

5.4系统权限管理功能的设计

超级管理员:商品管理,评估管理,订单管理,评价管理,会员管理,工单管理,消息管理,系统管理,授权管理。

普通管理员:商品管理,评估管理,订单管理,评价管理,会员管理,工单管理,消息管理。

业务员:订单管理,评价管理,会员管理,工单管理,消息管理。

5.5基于角色访问控制RBAC

5.5.1RABC数据库设计

5.5.2RABC实现流程

  1. 基于菜单实现:
  • 在创建系统用户时,为用户绑定对应的角色。

当登录成功进入主页面,根据用户查询角色,再根据角色查询到当前用户的权限列表

5.6主页菜单的加载显示功能

根据不同管理员身份加载并显示当前管理员可以操作的菜单。

5.6.1实现设计流程

5.6.2 数据库操作

操作:根据管理员的ID查询当前管理员的菜单;

1.涉及的数据表

管理员信息表 : tb_managers

管理员角色关联表:tb_mgr_role

角色表:tb_roles

角色菜单关联表:tb_role_menu

菜单表:tb_menus

5.6.3创建实体类

创建实体类封装查询的菜单信息;

二级菜单实体类 Menu2;

一级菜单实体类 Menu1;

5.6.4JDBC操作

先查询出当前管理员的一级菜单,再根据管理员一级菜单的ID查询出当前一级菜单所拥有的的二级菜单。

  1. 使用子查询进行五表关联查询

 SELECT menu_name FROM tb_menus WHERE menu_id in(

SELECT menu_id FROM tb_role_menu WHERE role_id in(

SELECT role_id FROM tb_mgr_role WHERE mgr_id='10000001'

)

)

  1. 使用连接查询

SELECT * FROM tb_mgr_role a INNER JOIN tb_role_menu b INNER JOIN tb_menus c

ON a.role_id=b.role_id AND b.menu_id=c.menu_id WHERE a.mgr_id='10000002'

5.6.5创建MenuDAO类实现JDBC操作

实现菜单的数据库操作;

根据管理员ID查询对应的一级菜单;

根据管理员ID及一级菜单ID,查询此管理员在这个一级菜单下拥有的二级菜单;

5.6.6功能流程代码

1.创建MenuService类;

2. 在Servlets中创建 IndexServlet;

3. 在ManagerLoginServlet中,登录成功之后重定向到IndexServlet;

4. 在 IndexServlet 根据管理员ID查询菜单集合,并传递到index.jsp;

5. 在 index.jsp 通过JSTL+EL显示菜单树;

5.7菜单信息管理

对于一个系统而言,系统功能是由程序员进⾏开发和实现的,菜单相对⽐较固定的;如果要新增一个菜单,则需要有对应的功能支撑,因此对于菜单的添加操作不会让管理员来实现,而是由程序员实现的。因此在《卖淘乐后台管理系统》中,菜单信息管理功能主要就是对菜单的展示。

5.7.1数据库操作代码实现

查询所有的一级菜单;

查询所有的二级级菜单;

根据一级菜单查询所有的二级级菜单;

5.7.2在MenuService中实现两个业务

查询所有一级菜单和二级菜单 ;

根据一级菜单查询二级菜单;

5.7.3一级菜单列表显示

1. 创建 MenuListServlet 类;

2. 点击【菜单管理】跳转到 MenuListServlet ,因为菜单是从数据库加载的,修改【菜单管理】的跳转路径应该要到数据库tb_menus进⾏修改;

3. 在 MenuListServlet 类查询菜单信息,传递到 admin_menu_list.jsp 页面;

5.7.4二级菜单联动显示

当点击一级菜单,异步请求二级菜单联动显示。

  1. 创建Menu2ListByMenu1Servlet类。
  2. 点击admin_menu_list.jsp 页面中的一级菜单,触发AJax请求,请求Menu2ListByMenu1Servlet。
  3. 在Menu2ListByMenu1Servlet类中接收ajax请求,并且根据一级菜单查询二级菜单,然后以JSON格式响应ajax请求。
  4. 将ajax得到的响应数据,二级菜单显示出来。

5.8菜单的启用和停用

权限/菜单的启用与停用功能,指的是当系统管理员禁用了某个菜单之后,即使拥有这个权限的用户也不能进⾏此操作了。

  1. 修改tb_menus数据表增加menu_state字段以支持启用停用功能。
  2. 流程设计
  3. 增加menu2实体类中menuState属性。
  4. 修改MenuDao和MenuService中查询Menu2的方法。
  5. 在admin_menu_list.jsp 页面显示二级菜单时,同时显示其对应的状态。
  6. 全部菜单中二级菜单的状态发生变化,相应的点击一级菜单所出现的二级菜单的条目的状态也应该发生变化。

5.9管理员登录成功后隐藏禁用菜单

如果一个权限被超级管理员禁用了之后,即使拥有该权限的管理员登录之后,此权限应当不可见或不可操作。

5.10管理员登录实现流程设计

1. 进⼊系统显示登录⻚⾯,管理员输⼊账号、密码点击登录按钮进⾏提交;

2. 账号和密码提交到ManagerLoginServlet类,在ManagerLoginServlet中接收账号和密

码,调⽤ManagerService验证账号和密码是否正确;

3. ManagerService先调⽤ManagerDAO中的⽅法,根据管理员名称查询管理员信息,将查

询结果返回给ManagerService;

4. 在ManagerService中:

如果ManagerDAO返回的信息为空,则表示根据⽤户输⼊的管理员登录账号没有查

询到管理员信息(账号不存在),就返回给ManagerLoginServlet⼀个null值

如果ManagerDAO返回的信息不为空,表示管理员账号是正确的,然后校验输⼊的

密码与查询的管理员信息密码是否⼀致:

如果密码不⼀致,则返回给ManagerLoginServlet⼀个null值;

如果密码⼀致,则返回给ManagerLoginServlet管理员对象;

5. ManagerLoginServlet接收ManagerService返回的验证结果:

如果返回的是null,则表示账号或者密码错误,转发到login.jsp并提示 ;

如果返回的管理员对象,则表示账号和密码都正确,将管理员信息存放到session中,跳转到index.jsp。

 

5.11角色权限管理

5.2.1查询角色信息

1、查询角色信息列表的流程图如图所示: 

 

角色信息列表显示是通过点击角色管理菜单,调用RoleServlet,在该Servlet中调用RoleService查询角色列表,Service页面又通过RoleDAO查询角色集合。将所查询到的结果返回给RoleServlet。将角色列表传递给admin_role_list.jsp。

2、将数据库访问操作放在RoleDAO类中。

3、在admin_role_list.jsp中使用JSTL和EL表达式

5.11.2添加角色信息

1、添加新角色的流程图如图所示:

2、在admin_role_list.jsp页面中,通过点击添加新角色,跳转到MenuListAllServlet页面,在该页面中调用MenuService中的方法,用于显示查询到的所有一级菜单以及每个一级菜单所对应的二级菜单。在Sevice中调用MenuDAO,在该页面中查询一级菜单以及所对应的二级菜单。

3、若想实现添加功能,则需要在admin_role_add.jsp页面通过点击提交按钮,传递到RoleAddServlet页面,进行接受提交的角色信息,并调用RoleService保存角色信息,RoleService通过调用RoleDAO来保存角色信息以及角色和菜单之间的关联关系。

5.11.3删除角色信息

1、从信息表中将某个角色信息删除,删除角色信息分为两个步骤:

(1)首先删除角色信息与菜单的关联(从tb_role_menu中删除)。

(2)删除角色表中的角色信息(从tb_roles中删除)。

2、删除角色的流程图如图所示:

(1)首先在admin_role_list.jsp页面点击删除按钮,跳转到RoleDeleteServlet页面中接受要删除的角色ID,并调用RoleService页面执行删除功能,在RoleService页面调用RoleDAO,从tb_role_menu表中删除角色与菜单之间的关联关系,从tb_roles表中删除角色信息。

(2)删除成功后,不在跳转到提示页面,而是使用异步请求,使用Ajax在本页面进行提示。

3、批量删除角色信息的流程图如图所示: 

(1)在admin_role_list.jsp页面中选择多个角色信息,进行批量删除,在RoleMultiDeleteServlet页面中,接收要删除的多个角色的ID,并调用RoleService中的deleteRole()方法,进行循环遍历删除,在调用RoleDAO中的selectRoles()方法,进行查询所有的角色信息,并显示在列表页面上。 

5.11.4修改角色信息

1、修改角色信息分为两个步骤:

(1)首先将所要修改的信息数据回显到文本框中。

(2)在admin_role_modify.jsp页面进行修改

2、修改角色信息流程图如图所示:

(1)首先在admin_role_list.jsp页面点击修改按钮,会自动传递一个角色ID到RoleQueryServlet页面中,在页面用于接收角色ID并根据角色ID查询角色信息以及角色所拥有的角色菜单,这些数据是通过RoleService和RoleDAO进行获取,并将获取到的数据回显到admin_role_modify.jsp。

(2)在admin_role_modify.jsp页面点击保存修改按钮,将所修改的角色信息和菜单ID传递到RoleUpdateServlet中,RoleUpdateServlet通过调用RoleService和RoleDAO对角色信息以及角色所拥有的权限进行修改。并将提示信息进行显示。

六、编码

6.1创建数据库连接信息文件

#数据库连接信息
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_mtl?characterEncoding=utf-8
userName=root
password=123456
#连接池参数如下

#1连接池初始连接数
initialSize=10
#2连接池最大连接数
maxActive=50
#3连接池最小连接数
minIdle=5
#4最大等待时间,单位毫秒
maxWait=5000

 6.2创建数据库连接池工具类

package com.it.untils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.Test;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;


//数据库连接池工具类
public class DruidUtils {

    //定义数据库连接池数据源
    private static DruidDataSource druidDataSource;

//    初始化数据库连接池
    static {
    try {
        InputStream resourceAsStream = DruidUtils.class.getResourceAsStream("Druid.properties");
//        实例化properties集合,它是一个映射集合
        Properties properties = new Properties();
//        把流中的数据全部加载到properties集合中
        properties.load(resourceAsStream);
//通过properties集合中的数据来创建连接池
        druidDataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

//返回DataSource对象
public static DataSource getDataSource(){
        return druidDataSource;
}

//    从连接池中获取数据库连接
    public static Connection getConnection() throws SQLException {
        Connection connection=null;
        connection=druidDataSource.getConnection();
        return  connection;
    }
}

6.3创建管理员实体类

package com.it.entity;

import java.util.Date;

//管理员信息实体类
//一般情况下类中属性个数的类型与对应的数据表是保持一致的
public class Manager {

    private String mgrId;
    private String loginName;
    private String loginPwd;
    private String mgrName;
    private String mgrGender;
    private String mgrTel;
    private String mgrEmail;
    private String mgrQQ;
    private Date createTime;

//    创建一个实体,一般情况下应写出它的无参构造器,全参构造器,get和set方法,toString方法
    
    public Manager() {
    }

    public Manager(String mgrId, String loginName, String loginPwd, String mgrName, String mgrGender, String mgrTel, String mgrEmail, String mgrQQ, Date createTime) {
        this.mgrId = mgrId;
        this.loginName = loginName;
        this.loginPwd = loginPwd;
        this.mgrName = mgrName;
        this.mgrGender = mgrGender;
        this.mgrTel = mgrTel;
        this.mgrEmail = mgrEmail;
        this.mgrQQ = mgrQQ;
        this.createTime = createTime;
    }

    public String getMgrId() {
        return mgrId;
    }

    public void setMgrId(String mgrId) {
        this.mgrId = mgrId;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getLoginPwd() {
        return loginPwd;
    }

    public void setLoginPwd(String loginPwd) {
        this.loginPwd = loginPwd;
    }

    public String getMgrName() {
        return mgrName;
    }

    public void setMgrName(String mgrName) {
        this.mgrName = mgrName;
    }

    public String getMgrGender() {
        return mgrGender;
    }

    public void setMgrGender(String mgrGender) {
        this.mgrGender = mgrGender;
    }

    public String getMgrTel() {
        return mgrTel;
    }

    public void setMgrTel(String mgrTel) {
        this.mgrTel = mgrTel;
    }

    public String getMgrEmail() {
        return mgrEmail;
    }

    public void setMgrEmail(String mgrEmail) {
        this.mgrEmail = mgrEmail;
    }

    public String getMgrQQ() {
        return mgrQQ;
    }

    public void setMgrQQ(String mgrQQ) {
        this.mgrQQ = mgrQQ;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Manager{" +
                "mgrId='" + mgrId + '\'' +
                ", loginName='" + loginName + '\'' +
                ", loginPwd='" + loginPwd + '\'' +
                ", mgrName='" + mgrName + '\'' +
                ", mgrGender='" + mgrGender + '\'' +
                ", mgrTel='" + mgrTel + '\'' +
                ", mgrEmail='" + mgrEmail + '\'' +
                ", mgrQQ='" + mgrQQ + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}

 6.4创建管理员DAO类(持久层)

package com.it.dao;

import com.it.entity.Manager;
import com.it.untils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

//用于完成管理员信息的数据库访问
public class ManagerDao {

    /**
     *查询管理员的信息通过selectManagerByLoginName
     * 根据管理员登录名查询管理员信息
     * @param loginName 管理员登录名
     * @return 如果查询成功则返回管理员对象,查询失败则返回为空。
     * @throws SQLException
     */
    public Manager selectManagerByLoginName(String loginName) throws SQLException {
        Manager query=null;
//       1.SQL指令
//如果数据库列名和实体类中的属性名不一致,需要在写SQL语句时,通过与实体类中属性名相同的别名使其与与实体类产生关联
        String sql="SELECT mgr_id mgrId,login_name loginName,login_pwd loginPwd," +
                "mgr_name mgrName,mgr_gender mgrGender,mgr_tel mgrTel," +
                "mgr_email mgrEmail,mgr_qq mgrQQ,create_time createTime" +
                " from tb_managers WHERE login_name=?";
//       2.导入commons-dbutils jar包中的 apache.commons.dbutils.QueryRunner
        QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
//       3.通过QueryRunner的query方法执行SQL,第一个参数是sql语句;第二个参数查询结果的存储集合;第三个参数查询的参数,代表SQL中的?
       query = queryRunner.query(sql, new BeanHandler<Manager>(Manager.class),loginName);
        return query;
    }
}

6.5创建管理员DAO类的测试类

package test.dao;

import com.it.dao.ManagerDao;
import com.it.entity.Manager;
import org.junit.Test;

import java.sql.SQLException;

import static org.junit.Assert.*;

public class ManagerDaoTest {
private ManagerDao managerDao=new ManagerDao();
    @Test
    public void selectManagerByLoginName() throws SQLException {
        Manager manager = managerDao.selectManagerByLoginName("admin");
//        assertNotNull(manager);
        System.out.println(manager);
    }
}

6.6创建管理员Service类(业务层)

package com.it.service;


import com.it.dao.ManagerDao;
import com.it.entity.Manager;

import java.sql.SQLException;

//用于实现管理员相关的业务
public class ManagerService {
    /**
     * 根据管理员输入的用户名和密码来判断登录是否成功
     * @param loginName
     * @param loginPwd
     * @return 如果登录成功返回manager对象,否则返回null
     */

    public Manager checkManagerLogin(String loginName,String loginPwd) throws SQLException {
        ManagerDao managerDao=new ManagerDao();
        Manager manager = managerDao.selectManagerByLoginName(loginName);
        if (manager!=null && loginPwd.equals(manager.getLoginPwd())){
            return manager;
        }
        return null;
    }
}

6.7创建管理员Service类的测试类

package test.service;

import com.it.entity.Manager;
import com.it.service.ManagerService;
import org.junit.Test;

import java.sql.SQLException;

import static org.junit.Assert.*;

public class ManagerServiceTest {

    @Test
    public void checkManagerLogin() throws SQLException {
        ManagerService managerService=new ManagerService();
        Manager admin = managerService.checkManagerLogin("admin", "4297f44b13955235245b2497399d7a93");
        System.out.println(admin);
    }
}

6.8创建管理员登录界面login.jsp(视图层)

<%--
  Created by IntelliJ IDEA.
  User: lijianglin
  Date: 2022/5/19
  Time: 17:32
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link href="assets/css/bootstrap.min.css" rel="stylesheet" />
    <link rel="stylesheet" href="assets/css/ace.min.css" />
    <link rel="stylesheet" href="assets/css/ace-rtl.min.css" />
    <link rel="stylesheet" href="assets/css/ace-skins.min.css" />
    <link rel="stylesheet" href="css/style.css"/>
    <script src="assets/js/ace-extra.min.js"></script>
    <script src="js/jquery-1.9.1.min.js"></script>
    <script src="assets/layer/layer.js" type="text/javascript"></script>
    <title>登录</title>
</head>

<body class="login-layout Reg_log_style" style="background: url(images/login_bg.png);">
<div class="logintop">
    <span>欢迎后台管理界面平台</span>
    <ul>
        <li><a href="#">返回首页</a></li>
        <li><a href="#">帮助</a></li>
        <li><a href="#">关于</a></li>
    </ul>
</div>
<div class="loginbody">
    <div class="login-container">
        <div class="center"></div>
        <div class="space-6"></div>

        <div class="position-relative">
            <div id="login-box" class="login-box widget-box no-border visible" style="margin-top: 50px;">
                <div class="widget-body" >
                    <div class="widget-main" >
                        <h4 class="header blue lighter bigger">
                            <i class="icon-coffee green"></i>
                            管理员登录
                        </h4>

                        <div class="login_icon"><img src="images/login.png" /></div>

                        <form class="" id="form1" action="ManagerLoginServlet" method="post">
                            <fieldset>
                                <ul>
                                    <li class="frame_style form_error">
                                        <label class="user_icon"></label>
                                        <input name="loginName" title="登录名" type="text"  id="username"/><i>用户名</i>
                                    </li>
                                    <li class="frame_style form_error">
                                        <label class="password_icon"></label>
                                        <input name="loginPwd" title="登录密码" type="password" id="userpwd"/><i>密码</i>
                                    </li>
                                    <li class="frame_style form_error">
                                        <label class="Codes_icon"></label>
                                        <input name="checkCode" title="验证码" type="text" id="Codes_text"/><i>验证码</i>
                                        <div class="Codes_region"></div>
                                    </li>
                                </ul>
                                <div class="space"></div>

                                <div class="clearfix">
                                    <label class="inline">
                                        <input type="checkbox" class="ace">
                                        <span class="lbl">保存密码</span>
                                    </label>

                                    <button type="submit" class="width-35 pull-right btn btn-sm btn-primary" id="login_btn">
                                        <i class="icon-key"></i>
                                        登录
                                    </button>
                                </div>

                                <div class="space-4"></div>
                            </fieldset>
                        </form>

                        <div class="social-or-login center">
                            <span class="bigger-110">通知</span>
                        </div>

                        <div class="social-login center">
<%--    从ManagerLoginServlet类中获取过来提示信息,取属性的value--%>
                            提示 ${tips}
                        </div>
                    </div><!-- /widget-main -->

                    <div class="toolbar clearfix"></div>
                </div><!-- /widget-body -->
            </div><!-- /login-box -->
        </div><!-- /position-relative -->
    </div>
</div>
<div class="loginbm">版权所有 2021</div><strong></strong>
</body>
</html>
<script>
    $('#form1').on('submit', function(){
        var num=0;
        var str="";
        $("input[type$='text'],input[type$='password']").each(function(n){
            if($(this).val()=="")
            {

                layer.alert(str+=""+$(this).attr("title")+"不能为空!\r\n",{
                    title: '提示框',
                    icon:0,
                });
                num++;
                return false;
            }
        });
        if(num>0){  return false;}
        else{
        //    管理员已经输入了密码,登录名,验证码
            return true;
        }

    });
    $(document).ready(function(){
        $("input[type='text'],input[type='password']").blur(function(){
            var $el = $(this);
            var $parent = $el.parent();
            $parent.attr('class','frame_style').removeClass(' form_error');
            if($el.val()==''){
                $parent.attr('class','frame_style').addClass(' form_error');
            }
        });
        $("input[type='text'],input[type='password']").focus(function(){
            var $el = $(this);
            var $parent = $el.parent();
            $parent.attr('class','frame_style').removeClass(' form_errors');
            if($el.val()==''){
                $parent.attr('class','frame_style').addClass(' form_errors');
            } else{
                $parent.attr('class','frame_style').removeClass(' form_errors');
            }
        });
    })

</script>

6.9创建后台管理系统首页index.jsp(视图层)

  <%--
  Created by IntelliJ IDEA.
  User: lijianglin
  Date: 2022/5/17
  Time: 22:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>网站后台管理系统  </title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link href="assets/css/bootstrap.min.css" rel="stylesheet" />
  <link rel="stylesheet" href="assets/css/font-awesome.min.css" />
  <!--[if IE 7]>
  <link rel="stylesheet" href="assets/css/font-awesome-ie7.min.css" />
  <![endif]-->
  <link rel="stylesheet" href="assets/css/ace.min.css" />
  <link rel="stylesheet" href="assets/css/ace-rtl.min.css" />
  <link rel="stylesheet" href="assets/css/ace-skins.min.css" />
  <link rel="stylesheet" href="css/style.css"/>
  <!--[if lte IE 8]>
  <link rel="stylesheet" href="assets/css/ace-ie.min.css" />
  <![endif]-->
  <script src="assets/js/ace-extra.min.js"></script>
  <!--[if lt IE 9]>
  <script src="assets/js/html5shiv.js"></script>
  <script src="assets/js/respond.min.js"></script>
  <![endif]-->
  <!--[if !IE]> -->
  <script src="js/jquery-1.9.1.min.js"></script>
  <!-- <![endif]-->
  <!--[if IE]>
  <script type="text/javascript">window.jQuery || document.write("<script src='assets/js/jquery-1.10.2.min.js'>"+"<"+"script>");</script>
  <![endif]-->
  <script type="text/javascript">
    if("ontouchend" in document) document.write("<script src='assets/js/jquery.mobile.custom.min.js'>"+"<"+"script>");
  </script>
  <script src="assets/js/bootstrap.min.js"></script>
  <script src="assets/js/typeahead-bs2.min.js"></script>
  <!--[if lte IE 8]>
  <script src="assets/js/excanvas.min.js"></script>
  <![endif]-->
  <script src="assets/js/ace-elements.min.js"></script>
  <script src="assets/js/ace.min.js"></script>
  <script src="assets/layer/layer.js" type="text/javascript"></script>
  <script src="assets/laydate/laydate.js" type="text/javascript"></script>
  <script src="js/jquery.nicescroll.js" type="text/javascript"></script>

  <script type="text/javascript">
    $(function(){
      var cid = $('#nav_list> li>.submenu');
      cid.each(function(i){
        $(this).attr('id',"Sort_link_"+i);

      })
    })
    jQuery(document).ready(function(){
      $.each($(".submenu"),function(){
        var $aobjs=$(this).children("li");
        var rowCount=$aobjs.size();
        var divHeigth=$(this).height();
        $aobjs.height(divHeigth/rowCount);
      });
      //初始化宽度、高度

      $("#main-container").height($(window).height()-76);
      $("#iframe").height($(window).height()-140);

      $(".sidebar").height($(window).height()-99);
      var thisHeight = $("#nav_list").height($(window).outerHeight()-173);
      $(".submenu").height();
      $("#nav_list").children(".submenu").css("height",thisHeight);

      //当文档窗口发生改变时 触发
      $(window).resize(function(){
        $("#main-container").height($(window).height()-76);
        $("#iframe").height($(window).height()-140);
        $(".sidebar").height($(window).height()-99);

        var thisHeight = $("#nav_list").height($(window).outerHeight()-173);
        $(".submenu").height();
        $("#nav_list").children(".submenu").css("height",thisHeight);
      });
      $(document).on('click','.iframeurl',function(){
        var cid = $(this).attr("name");
        var cname = $(this).attr("title");
        $("#iframe").attr("src",cid).ready();
        $("#Bcrumbs").attr("href",cid).ready();
        $(".Current_page a").attr('href',cid).ready();
        $(".Current_page").attr('name',cid);
        $(".Current_page").html(cname).css({"color":"#333333","cursor":"default"}).ready();
        $("#parentIframe").html('<span class="parentIframe iframeurl"> </span>').css("display","none").ready();
        $("#parentIfour").html(''). css("display","none").ready();
      });



    });
    /******/
    $(document).on('click','.link_cz > li',function(){
      $('.link_cz > li').removeClass('active');
      $(this).addClass('active');
    });
    /*******************/
    //jQuery( document).ready(function(){
    //	  $("#submit").click(function(){
    //	// var num=0;
    //     var str="";
    //     $("input[type$='password']").each(function(n){
    //          if($(this).val()=="")
    //          {
    //              // num++;
    //			   layer.alert(str+=""+$(this).attr("name")+"不能为空!\r\n",{
    //                title: '提示框',
    //				icon:0,
    //          });
    //             // layer.msg(str+=""+$(this).attr("name")+"不能为空!\r\n");
    //             layer.close(index);
    //          }
    //     });
    //})
    //	});

    /*********************点击事件*********************/
    $( document).ready(function(){
      $('#nav_list,.link_cz').find('li.home').on('click',function(){
        $('#nav_list,.link_cz').find('li.home').removeClass('active');
        $(this).addClass('active');
      });
//时间设置
      function currentTime(){
        var d=new Date(),str='';
        str+=d.getFullYear()+'年';
        str+=d.getMonth() + 1+'月';
        str+=d.getDate()+'日';
        str+=d.getHours()+'时';
        str+=d.getMinutes()+'分';
        str+= d.getSeconds()+'秒';
        return str;
      }

      setInterval(function(){$('#time').html(currentTime)},1000);
//修改密码
      $('.change_Password').on('click', function(){
        layer.open({
          type: 1,
          title:'修改密码',
          area: ['300px','300px'],
          shadeClose: true,
          content: $('#change_Pass'),
          btn:['确认修改'],
          yes:function(index, layero){
            if ($("#password").val()==""){
              layer.alert('原密码不能为空!',{
                title: '提示框',
                icon:0,

              });
              return false;
            }
            if ($("#Nes_pas").val()==""){
              layer.alert('新密码不能为空!',{
                title: '提示框',
                icon:0,

              });
              return false;
            }

            if ($("#c_mew_pas").val()==""){
              layer.alert('确认新密码不能为空!',{
                title: '提示框',
                icon:0,

              });
              return false;
            }
            if(!$("#c_mew_pas").val || $("#c_mew_pas").val() != $("#Nes_pas").val() )
            {
              layer.alert('密码不一致!',{
                title: '提示框',
                icon:0,

              });
              return false;
            }
            else{
              layer.alert('修改成功!',{
                title: '提示框',
                icon:1,
              });
              layer.close(index);
            }
          }
        });
      });
      $('#Exit_system').on('click', function(){
        layer.confirm('是否确定退出系统?', {
                  btn: ['是','否'] ,//按钮
                  icon:2,
                },
                function(){
                  location.href="login.html";

                });
      });
    });
    function link_operating(name,title){
      var cid = $(this).name;
      var cname = $(this).title;
      $("#iframe").attr("src",cid).ready();
      $("#Bcrumbs").attr("href",cid).ready();
      $(".Current_page a").attr('href',cid).ready();
      $(".Current_page").attr('name',cid);
      $(".Current_page").html(cname).css({"color":"#333333","cursor":"default"}).ready();
      $("#parentIframe").html('<span class="parentIframe iframeurl"> </span>').css("display","none").ready();
      $("#parentIfour").html(''). css("display","none").ready();


    }
  </script>
</head>
<body>
<div class="navbar navbar-default" id="navbar">
  <script type="text/javascript">
    try{ace.settings.check('navbar' , 'fixed')}catch(e){}
  </script>
  <div class="navbar-container" id="navbar-container">
    <div class="navbar-header pull-left">
      <a href="#" class="navbar-brand">
        <img src="images/mtl_logo.png" height="50" style="transform: translate(20px,12px);" onclick="location.href='#'"/>
        <img src="images/mtl_title.png" height="50" style="transform: translate(15px,14px);"/>
      </a><!-- /.brand -->
    </div><!-- /.navbar-header -->
    <div class="navbar-header operating pull-left">

    </div>
    <div class="navbar-header pull-right" role="navigation">
      <ul class="nav ace-nav">
        <li class="light-blue">
          <a data-toggle="dropdown" href="#" class="dropdown-toggle">
            <span  class="time"><em id="time"></em></span><span class="user-info"><small>欢迎光临,</small>超级管理员</span>
            <i class="icon-caret-down"></i>
          </a>
          <ul class="user-menu pull-right dropdown-menu dropdown-yellow dropdown-caret dropdown-close">
            <li><a href="javascript:void(0" name="Systems.html" title="系统设置" class="iframeurl"><i class="icon-cog"></i>网站设置</a></li>
            <li><a href="javascript:void(0)" name="admin_info.html" title="个人信息" class="iframeurl"><i class="icon-user"></i>个人资料</a></li>
            <li class="divider"></li>
            <li><a href="javascript:ovid(0)" id="Exit_system"><i class="icon-off"></i>退出</a></li>
          </ul>
        </li>

      </ul>

    </div>
  </div>
</div>
<div class="main-container" id="main-container">
  <script type="text/javascript">
    try{ace.settings.check('main-container' , 'fixed')}catch(e){}
  </script>
  <div class="main-container-inner">
    <a class="menu-toggler" id="menu-toggler" href="#">
      <span class="menu-text"></span>
    </a>
    <div class="sidebar" id="sidebar">
      <script type="text/javascript">
        try{ace.settings.check('sidebar' , 'fixed')}catch(e){}
      </script>
      <div class="sidebar-shortcuts" id="sidebar-shortcuts">
        <div class="sidebar-shortcuts-large" id="sidebar-shortcuts-large">
          <a class="btn btn-success">☻
            <!-- <i class="icon-signal"></i> -->
          </a>
          <a class="btn btn-info">☼
            <!-- <i class="icon-pencil"></i> -->
          </a>
          <a class="btn btn-warning">☪
            <!-- <i class="icon-group"></i> -->
          </a>
          <a class="btn btn-danger">★
            <!-- <i class="icon-cogs"></i> -->
          </a>
        </div>

        <div class="sidebar-shortcuts-mini" id="sidebar-shortcuts-mini">
          <span class="btn btn-success"></span>

          <span class="btn btn-info"></span>

          <span class="btn btn-warning"></span>

          <span class="btn btn-danger"></span>
        </div>
      </div><!-- #sidebar-shortcuts -->
      <div id="menu_style" class="menu_style">
        <ul class="nav nav-list" id="nav_list">
          <!-- 菜单1 -->
          <li class="home">
            <a href="javascript:void(0)" name="home.html" class="iframeurl" title="">
              <i class="icon-home"></i><span class="menu-text"> 系统首页 </span>
            </a>
          </li>
          <!-- 菜单2 -->
          <li>
            <a href="#" class="dropdown-toggle"><i class="icon-desktop"></i><span class="menu-text"> 商品管理 </span><b class="arrow icon-angle-down"></b></a>
            <ul class="submenu">
              <li class="home"><a  href="javascript:void(0)" name="category_list.html"  title="分类管理" class="iframeurl"><i class="icon-double-angle-right"></i>分类管理</a></li>
              <li class="home"><a  href="javascript:void(0)" name="brand_manage.html" title="品牌管理"  class="iframeurl"><i class="icon-double-angle-right"></i>品牌管理</a></li>
              <li class="home"><a href="javascript:void(0)" name="products_list.html" title="全部商品"  class="iframeurl"><i class="icon-double-angle-right"></i>全部商品</a></li>

            </ul>
          </li>
          <li>
            <a href="#" class="dropdown-toggle"><i class="icon-picture "></i><span class="menu-text"> 评估管理 </span><b class="arrow icon-angle-down"></b></a>
            <ul class="submenu">
              <li class="home"><a href="javascript:void(0)" name="basic_info_list.html" title="评估类目" class="iframeurl"><i class="icon-double-angle-right"></i>评估类目</a></li>
              <li class="home"><a href="javascript:void(0)" name="basic_info_detail.html" title="评估选项"  class="iframeurl"><i class="icon-double-angle-right"></i>评估选项</a></li>
            </ul>
          </li>
          <li>
            <a href="#" class="dropdown-toggle"><i class="icon-list"></i><span class="menu-text"> 订单管理 </span><b class="arrow icon-angle-down"></b></a>
            <ul class="submenu">
              <li class="home"><a href="javascript:void(0)" name="transaction.html" title="交易信息"  class="iframeurl"><i class="icon-double-angle-right"></i>交易信息</a></li>
              <li class="home"><a href="javascript:void(0)" name="order_list.html" title="全部订单"  class="iframeurl"><i class="icon-double-angle-right"></i>全部订单</a></li>
              <li class="home"><a href="javascript:void(0)" name="order_list.html" title="待处理订单"  class="iframeurl"><i class="icon-double-angle-right"></i>待处理订单</a></li>
              <li class="home"><a href="javascript:void(0)" name="order_list.html" title="已完成订单"  class="iframeurl"><i class="icon-double-angle-right"></i>已完成订单</a></li>
              <li class="home"><a href="javascript:void(0)" name="order_list.html" title="已取消订单"  class="iframeurl"><i class="icon-double-angle-right"></i>已取消订单</a></li>
            </ul>
          </li>
          <li>
            <a href="#" class="dropdown-toggle"><i class="icon-credit-card"></i><span class="menu-text"> 评价管理 </span><b class="arrow icon-angle-down"></b></a>
            <ul class="submenu">
              <li class="home"><a href="javascript:void(0)" name="comments_list.html" title="全部评价" class="iframeurl"><i class="icon-double-angle-right"></i>全部评价</a></li>
              <li class="home"><a href="javascript:void(0)" name="comments_list.html" title="待审核评价" class="iframeurl"><i class="icon-double-angle-right"></i>待审核评价</a></li>
            </ul>
          </li>
          <li>
            <a href="#" class="dropdown-toggle"><i class="icon-user"></i><span class="menu-text"> 会员管理 </span><b class="arrow icon-angle-down"></b></a>
            <ul class="submenu">
              <li class="home"><a href="javascript:void(0)" name="member_list.html" title="全部会员"  class="iframeurl"><i class="icon-double-angle-right"></i>全部会员</a></li>
              <li class="home"><a href="javascript:void(0)" name="member_list.html" title="已锁定会员"  class="iframeurl"><i class="icon-double-angle-right"></i>已锁定会员</a></li>
              <li class="home"><a href="javascript:void(0)" name="member_list.html" title="已注会销员"  class="iframeurl"><i class="icon-double-angle-right"></i>已注销会员</a></li>

            </ul>
          </li>

          <li><a href="#" class="dropdown-toggle"><i class="icon-comments-alt"></i><span class="menu-text"> 消息管理 </span><b class="arrow icon-angle-down"></b></a>
            <ul class="submenu">
              <li class="home"><a href="javascript:void(0)" name="guestbook.html" title="留言列表" class="iframeurl"><i class="icon-double-angle-right"></i>留言列表</a></li>
              <li class="home"><a href="javascript:void(0)" name="feedback.html" title="意见反馈" class="iframeurl"><i class="icon-double-angle-right"></i>意见反馈</a></li>
            </ul>
          </li>

          <li><a href="#" class="dropdown-toggle"><i class="icon-cogs"></i><span class="menu-text"> 系统管理 </span><b class="arrow icon-angle-down"></b></a>
            <ul class="submenu">
              <li class="home"><a href="javascript:void(0)" name="system_settings.html" title="系统设置" class="iframeurl"><i class="icon-double-angle-right"></i>系统设置</a></li>
              <li class="home"><a href="javascript:void(0)" name="system_logs.html" title="系统日志" class="iframeurl"><i class="icon-double-angle-right"></i>系统日志</a></li>
            </ul>
          </li>
          <li><a href="#" class="dropdown-toggle"><i class="icon-group"></i><span class="menu-text"> 权限管理 </span><b class="arrow icon-angle-down"></b></a>
            <ul class="submenu">
              <li class="home"><a href="javascript:void(0)" name="admin_manager_list.html" title="管理员列表" class="iframeurl"><i class="icon-double-angle-right"></i>管理员列表</a></li>
              <li class="home"><a href="javascript:void(0)" name="admin_role_list.html" title="角色管理"  class="iframeurl"><i class="icon-double-angle-right"></i>角色管理</a></li>
              <li class="home"><a href="javascript:void(0)" name="admin_menu_list.html" title="系统权限" class="iframeurl"><i class="icon-double-angle-right"></i>系统权限</a></li>
            </ul>
          </li>

          <!-- 菜单3 -->
          <li class="home">
            <a href="javascript:void(0)" name="admin_info.html" class="iframeurl" title="个人信息">
              <i class="icon-info"></i><span class="menu-text"> 个人信息 </span>
            </a>
          </li>
        </ul>
      </div>
      <script type="text/javascript">
        $("#menu_style").niceScroll({
          cursorcolor:"#888888",
          cursoropacitymax:1,
          touchbehavior:false,
          cursorwidth:"5px",
          cursorborder:"0",
          cursorborderradius:"5px"
        });
      </script>
      <div class="sidebar-collapse" id="sidebar-collapse">
        <i class="icon-double-angle-left" data-icon1="icon-double-angle-left" data-icon2="icon-double-angle-right"></i>
      </div>
      <script type="text/javascript">
        try{ace.settings.check('sidebar' , 'collapsed')}catch(e){}
      </script>
    </div>

    <div class="main-content">
      <script type="text/javascript">
        try{ace.settings.check('breadcrumbs' , 'fixed')}catch(e){}
      </script>
      <div class="breadcrumbs" id="breadcrumbs" >
        <ul class="breadcrumb" style="transform: translateY(8px)">
          <li>
            <i class="icon-home home-icon"></i>
            <a href="index.html">首页</a>
          </li>
          <li class="active"><span class="Current_page iframeurl"></span></li>
          <li class="active" id="parentIframe"><span class="parentIframe iframeurl"></span></li>
          <li class="active" id="parentIfour"><span class="parentIfour iframeurl"></span></li>
        </ul>
      </div>

      <iframe id="iframe" style="border:0; width:100%; background-color:#FFF;"
              name="iframe" frameborder="0" src="home.html">  </iframe>
    </div>
  </div>
</div>
<!--底部样式-->

<div class="footer_style" id="footerstyle">
  <script type="text/javascript">try{ace.settings.check('footerstyle' , 'fixed')}catch(e){}</script>
  <p class="l_f">版权所有</p>
</div>
<!--修改密码样式-->
<div class="change_Pass_style" id="change_Pass">
  <ul class="xg_style">
    <li><label class="label_name">原&nbsp;&nbsp;密&nbsp;码</label><input name="原密码" type="password" class="" id="password"></li>
    <li><label class="label_name">新&nbsp;&nbsp;密&nbsp;码</label><input name="新密码" type="password" class="" id="Nes_pas"></li>
    <li><label class="label_name">确认密码</label><input name="再次确认密码" type="password" class="" id="c_mew_pas"></li>
  </ul>
</div>

</body>
</html>

6.10修改web.xml文件中的起始页面

<?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.jsp</welcome-file>
    </welcome-file-list>
</web-app>

6.11创建管理员ManagerLoginServlet类(控制层)

package com.it.servlets;

import com.it.entity.Manager;
import com.it.service.ManagerService;

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;
import java.sql.SQLException;

//用于管理员登录验证的servlet
@WebServlet("/ManagerLoginServlet")
public class ManagerLoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// doGet中写了doPost方法,可以所有方法都在doPost方法,这样不管传过来是get还是post都可以成功调用方法
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//      1.接收账号、密码、验证码
        req.setCharacterEncoding("utf-8");
//        从输入框中获取输入的内容,参数是输入框的名字。
        String loginName = req.getParameter("loginName");
        String loginPwd = req.getParameter("loginPwd");
        String checkCode = req.getParameter("checkCode");
//      2.调用ManagerService进行校验
        ManagerService managerService = new ManagerService();
        try {
            Manager manager = managerService.checkManagerLogin(loginName, loginPwd);
//            3.判断验证结果
            if (manager==null){
//                登录失败,跳转到登录界面并进行错误提示
                req.setAttribute("tips","<label style='color:red'>登录失败,密码或账号错误!</label>");
                req.getRequestDispatcher("login.jsp").forward(req,resp);
            }else {
//                登录成功,跳转到index.jsp界面
                resp.sendRedirect("index.jsp");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
}

6.12创建登录页面验证码CheckCodeServlet类

package com.it.servlets;

import javax.imageio.ImageIO;
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 javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet("/CheckCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过java中awt中提供的类绘制验证码图片
//        1.创建一张图片
        int height=90;//验证码高度
        int width=300;//验证码宽度
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//实例化一个图片对象
//        2.绘制图片对象,从图片对象中获取绘制图片的笔
        Graphics2D pen = image.createGraphics();
        //a.绘制背景
        pen.setColor(getRandomColor());
        pen.fillRect(0,0,width,height);//绘制实心矩形

        //b.绘制验证码字符串
        int letterNum=4;//验证码图片上的字符的个数
        int space=20;//验证码图片上两个字母之间的空隙
        int letterWidth=(width-(letterNum+1)*space)/letterNum;//计算每个字母占据的宽度

//        for循环每循环一次,绘制一个字母(小写字母的ascii码:97-122)
        Random random = new Random();
        String code ="";
        for (int i=0;i<letterNum;i++){
//            随机生成一个小写字母
            int ascii = random.nextInt(26) + 97;//97-122
            byte[] bytes={(byte) ascii};
            String letter=new String(bytes);
            code = code + letter;//为了保存验证码字符到session
//            绘制字母
            pen.setColor(getRandomColor());
            pen.setFont(new Font("Gulim",Font.BOLD,70));
            pen.drawString(letter,space+(letterWidth+space)*i,height-space);//把该字母写在画布上

        }
        HttpSession session = req.getSession();
        session.setAttribute("code",code);
        //添加图片干扰,防止机器自动识别

//            图片绘制完成后,将图片通过response输出流响应到客户端
        ImageIO.write(image,"png",resp.getOutputStream());
    }

    private Color getRandomColor() {
        Random random = new Random();
        int r=random.nextInt(256);
        int g = random.nextInt(256);
        int b = random.nextInt(256);
        Color color = new Color(r, g, b);
        return color;
    }
}

6.13创建管理员登录认证过滤器

package com.it.untils;

import com.it.entity.Manager;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//登录过滤器,拦截所有的请求,然后在doFilter方法中写登录过滤器的拦截规则
@WebFilter("/*")
public class LoginFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//        1.获取用户请求资源的url
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        HttpServletResponse response= (HttpServletResponse) servletResponse;
        String url = request.getRequestURL().toString();
//        2.从url中截取请求的资源名称
        String path = url.substring(url.lastIndexOf("/") + 1);
        //如果url中的资源是非受限资源,直接放行
        if ("".equals(path) || "ManagerLoginServlet".equals(path) || "CheckCodeServlet".equals(path)
        || path.endsWith(".js") || path.endsWith(".css") || path.endsWith(".png") || path.endsWith(".jpg")
         || path.endsWith(".bmp") ){
            filterChain.doFilter(servletRequest,servletResponse);//放行
        }else{
            //如果url中的资源是受限资源,则需要验证管理员是否登录(即检查session中是否有管理员信息)
            Manager mgr = (Manager) request.getSession().getAttribute("mgr");
            if (mgr==null){
                //session中没有管理员信息,即没有登录访问了受限资源,跳转到登录界面,提示登录
                request.setAttribute("tips","<label style='color:blue;'>你没有权限,请先登录!</label>");
                request.getRequestDispatcher("login.jsp").forward(request,response);
            }else{
                //如果管理员登录了则放行
                filterChain.doFilter(request,response);
            }
        }

        System.out.println(url);
    }

    @Override
    public void destroy() {

    }
}

6.14创建MD5工具类

package com.it.untils;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {
    public static String mdtEncode(String str){
        String pwd=null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");//获得一个MD5加密的客户端
            md5.update(str.getBytes());//对用户输入的密码进行加密处理,参数为字节数组
            byte[] digest = md5.digest();//加密
            pwd = new BigInteger(1, digest).toString(16);//字节数组转16进制字符串
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return pwd;
    }

}

6.15创建菜单实体类

6.15.1创建菜单二级列表实体类

package com.it.entity;

public class Menu2 {
    private int menuId;
    private String menuCode;
    private String menuName;
    private int menuOrder;
    private int menuLevel;
    private String parentMenuCode;
    private String menuUrl;


    public Menu2() {
    }

    public Menu2(int menuId, String menuCode, String menuName, int menuOrder, int menuLevel, String parentMenuCode, String menuUrl) {
        this.menuId = menuId;
        this.menuCode = menuCode;
        this.menuName = menuName;
        this.menuOrder = menuOrder;
        this.menuLevel = menuLevel;
        this.parentMenuCode = parentMenuCode;
        this.menuUrl = menuUrl;
    }

    @Override
    public String toString() {
        return "Menu2{" +
                "menuId=" + menuId +
                ", menuCode='" + menuCode + '\'' +
                ", menuName='" + menuName + '\'' +
                ", menuOrder=" + menuOrder +
                ", menuLevel=" + menuLevel +
                ", parentMenuCode='" + parentMenuCode + '\'' +
                ", menuUrl='" + menuUrl + '\'' +
                '}';
    }

    public int getMenuId() {
        return menuId;
    }

    public void setMenuId(int menuId) {
        this.menuId = menuId;
    }

    public String getMenuCode() {
        return menuCode;
    }

    public void setMenuCode(String menuCode) {
        this.menuCode = menuCode;
    }

    public String getMenuName() {
        return menuName;
    }

    public void setMenuName(String menuName) {
        this.menuName = menuName;
    }

    public int getMenuOrder() {
        return menuOrder;
    }

    public void setMenuOrder(int menuOrder) {
        this.menuOrder = menuOrder;
    }

    public int getMenuLevel() {
        return menuLevel;
    }

    public void setMenuLevel(int menuLevel) {
        this.menuLevel = menuLevel;
    }

    public String getParentMenuCode() {
        return parentMenuCode;
    }

    public void setParentMenuCode(String parentMenuCode) {
        this.parentMenuCode = parentMenuCode;
    }

    public String getMenuUrl() {
        return menuUrl;
    }

    public void setMenuUrl(String menuUrl) {
        this.menuUrl = menuUrl;
    }
}

6.15.2创建菜单一级列表实体类

package com.it.entity;

import java.util.List;

public class Menu1 {
    private int menuId;
    private String menuCode;
    private String menuName;
    private int menuOrder;
    private int menuLevel;
    private String menuIcon;
    private List<Menu2> childMenus;

    public Menu1() {
    }

    public Menu1(int menuId, String menuCode, String menuName, int menuOrder, int menuLevel, String menuIcon, List<Menu2> childMenus) {
        this.menuId = menuId;
        this.menuCode = menuCode;
        this.menuName = menuName;
        this.menuOrder = menuOrder;
        this.menuLevel = menuLevel;
        this.menuIcon = menuIcon;
        this.childMenus = childMenus;
    }

    @Override
    public String toString() {
        return "Menu1{" +
                "menuId=" + menuId +
                ", menuCode='" + menuCode + '\'' +
                ", menuName='" + menuName + '\'' +
                ", menuOrder=" + menuOrder +
                ", menuLevel=" + menuLevel +
                ", menuIcon='" + menuIcon + '\'' +
                ", childMenus=" + childMenus +
                '}';
    }

    public int getMenuId() {
        return menuId;
    }

    public void setMenuId(int menuId) {
        this.menuId = menuId;
    }

    public String getMenuCode() {
        return menuCode;
    }

    public void setMenuCode(String menuCode) {
        this.menuCode = menuCode;
    }

    public String getMenuName() {
        return menuName;
    }

    public void setMenuName(String menuName) {
        this.menuName = menuName;
    }

    public int getMenuOrder() {
        return menuOrder;
    }

    public void setMenuOrder(int menuOrder) {
        this.menuOrder = menuOrder;
    }

    public int getMenuLevel() {
        return menuLevel;
    }

    public void setMenuLevel(int menuLevel) {
        this.menuLevel = menuLevel;
    }

    public String getMenuIcon() {
        return menuIcon;
    }

    public void setMenuIcon(String menuIcon) {
        this.menuIcon = menuIcon;
    }

    public List<Menu2> getChildMenus() {
        return childMenus;
    }

    public void setChildMenus(List<Menu2> childMenus) {
        this.childMenus = childMenus;
    }
}

6.16创建查询菜单列表的DAO类

package com.it.dao;

import com.it.entity.Menu1;
import com.it.entity.Menu2;
import com.it.untils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.Array;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

//实现菜单的查询
public class MenuDAO {
    public List<Menu1> selectFirstLevelMenusById(String mgrId) throws SQLException {
        List<Menu1> menu1List = new ArrayList<>();
        String str="SELECT c.menu_id menuId,menu_code menuCode,menu_name menuName,menu_order menuOrder,menu_level menuLevel,menu_icon menuIcon FROM tb_mgr_role a " +
                "INNER JOIN tb_role_menu b INNER JOIN tb_menus c ON a.role_id=b.role_id AND b.menu_id=c.menu_id WHERE a.mgr_id=? AND menu_level=1 ORDER BY c.menu_order";
        QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
        menu1List= queryRunner.query(str, new BeanListHandler<Menu1>(Menu1.class), mgrId);
        return menu1List;
    }

    public List<Menu2> selectSecondLevelMenusByIdAndParentCode(String mgrId,String parentCode) throws SQLException {
        List<Menu2> menu2List = new ArrayList<>();
        String sql="SELECT c.menu_id menuId,menu_code menuCode,menu_name menuName,menu_order menuOrder,menu_level menuLevel,parent_menu_code parentMenuCode,menu_url menuUrl FROM tb_mgr_role a " +
                "INNER JOIN tb_role_menu b INNER JOIN tb_menus c ON a.role_id=b.role_id AND b.menu_id=c.menu_id WHERE a.mgr_id=? AND menu_level=2 AND parent_menu_code=? ORDER BY c.menu_order";
        QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
        menu2List=queryRunner.query(sql,new BeanListHandler<Menu2>(Menu2.class),mgrId,parentCode);
        return menu2List;
    }
}

6.17创建查询菜单列表的Service类

package com.it.service;

import com.it.dao.MenuDAO;
import com.it.entity.Menu1;
import com.it.entity.Menu2;

import java.sql.SQLException;
import java.util.List;

public class MenuService {
    public List<Menu1> selectMenuByMgrId(String mgrId) throws SQLException {
        MenuDAO menuDAO = new MenuDAO();
        //根据管理员ID查询该管理员的一级菜单
        List<Menu1> menu1List = menuDAO.selectFirstLevelMenusById(mgrId);
        //查询每一个一级菜单中的二级菜单
        for (int i = 0; i < menu1List.size(); i++) {
            Menu1 menu1 = menu1List.get(i);
            List<Menu2> menu2s = menuDAO.selectSecondLevelMenusByIdAndParentCode(mgrId, menu1.getMenuCode());
            menu1.setChildMenus(menu2s);
        }
        return menu1List;
    }
}

6.18创建IndexServlet类

package com.it.servlets;

import com.it.entity.Manager;
import com.it.entity.Menu1;
import com.it.service.MenuService;

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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

@WebServlet("/IndexServlet")
public class IndexServlet extends HttpServlet {

    MenuService menuService=new MenuService();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        Manager mgr = (Manager) session.getAttribute("mgr");
        String mgrId = mgr.getMgrId();
        try {
            List<Menu1> menu1List = menuService.selectMenuByMgrId(mgrId);
            req.setAttribute("menuList",menu1List);
            req.getRequestDispatcher("index.jsp").forward(req,resp);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

6.18首页的菜单列表根据不同用户的身份动态加载

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- 菜单2 -->
          <c:forEach items="${menuList}" var="menu1">
          <li>
            <a href="#" class="dropdown-toggle">
              <i class="${menu1.menuIcon}"></i>
              <span class="menu-text"> ${menu1.menuName} </span>
              <b class="arrow icon-angle-down"></b>
            </a>
            <ul class="submenu">
              <c:forEach items="${menu1.childMenus}" var="menu2"></c:forEach>
              <li class="home">
                <a  href="javascript:void(0)" name="${menu2.menuUrl}"  title="${menu2.menuName}" class="iframeurl">
                  <i class="icon-double-angle-right"></i>${menu2.menuName}
                </a>
              </li>
            </ul>
          </li>
          </c:forEach>

6.19菜单信息管理的DAO方法增加在MenuDAO类中

/查询所有的一级菜单
    public List<Menu1> selectMenu1() throws SQLException {
        List<Menu1>  menu1List = new ArrayList<>();
        String sql="SELECT menu_id menuId,menu_code menuCode,menu_name menuName,menu_order menuOrder,menu_level menuLevel,menu_icon menuIcon FROM tb_menus WHERE menu_level=1 ORDER BY menu_order";
        QueryRunner queryRunner=new QueryRunner(DruidUtils.getDataSource());
        menu1List= queryRunner.query(sql, new BeanListHandler<Menu1>(Menu1.class));
        return  menu1List;
    }
    //查询所有的二级菜单
    public List<Menu2> selectMenu2() throws SQLException {
        List<Menu2> menu2List=new ArrayList<>();
        String sql="SELECT menu_id menuId,menu_code menuCode,menu_name menuName,menu_order menuOrder,menu_level menuLevel,parent_menu_code parentMenuCode,menu_url menuUrl FROM tb_menus WHERE menu_level=2 ORDER BY menu_code ";
        QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
        menu2List = queryRunner.query(sql, new BeanListHandler<Menu2>(Menu2.class));
        return menu2List;
    }
    //查询某一级菜单所拥有的二级菜单
    public List<Menu2> selectMenu2ByMenu1Code(String parentMenuCode) throws SQLException {
        List<Menu2> menu2List=new ArrayList<>();
       String sql="SELECT menu_id menuId,menu_code menuCode,menu_name menuName,menu_order menuOrder,menu_level menuLevel,parent_menu_code parentMenuCode,menu_url menuUrl FROM tb_menus " +
               "WHERE parent_menu_code=? AND menu_level=2 ORDER BY menu_code;";
        QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
        menu2List= queryRunner.query(sql, new BeanListHandler<Menu2>(Menu2.class), parentMenuCode);
        return menu2List;
    }

6.20菜单信息管理的service方法增加在MenuService类中

package com.it.service;

import com.it.dao.MenuDAO;
import com.it.entity.Menu1;
import com.it.entity.Menu2;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MenuService {
    public List<Menu1> selectMenuByMgrId(String mgrId) throws SQLException {
        MenuDAO menuDAO = new MenuDAO();
        //根据管理员ID查询该管理员的一级菜单
        List<Menu1> menu1List = menuDAO.selectFirstLevelMenusById(mgrId);
        //查询每一个一级菜单中的二级菜单
        for (int i = 0; i < menu1List.size(); i++) {
            Menu1 menu1 = menu1List.get(i);
            List<Menu2> menu2s = menuDAO.selectSecondLevelMenusByIdAndParentCode(mgrId, menu1.getMenuCode());
            menu1.setChildMenus(menu2s);
        }
        return menu1List;
    }
    //查询所有的一级二级菜单
    public Map<String,List> listMenus() throws SQLException {
        Map<String, List> mapMenus = new HashMap<>();
        MenuDAO menuDAO = new MenuDAO();
        List<Menu1> menu1List = menuDAO.selectMenu1();
        List<Menu2> menu2List = menuDAO.selectMenu2();
        mapMenus.put("menu1List",menu1List);
        mapMenus.put("menu2List",menu2List);
        return mapMenus;
    }
    //查询某个一级菜单所拥有的二级菜单
    public List<Menu2> selectMenu2ByMenu1Code(String menu1Code) throws SQLException {
        List<Menu2> menu2List = new ArrayList<>();
        MenuDAO menuDAO = new MenuDAO();
        menu2List = menuDAO.selectMenu2ByMenu1Code(menu1Code);
        return menu2List;
    }
}

6.21菜单信息管理MenuListServlet类

package com.it.servlets;

import com.it.service.MenuService;

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;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

@WebServlet("/MenuListServlet")
public class MenuListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        MenuService menuService = new MenuService();
        try {
            Map<String, List> map = menuService.listMenus();
            req.setAttribute("menu1List",map.get("menu1List"));
            req.setAttribute("menu2List",map.get("menu2List"));
            req.getRequestDispatcher("admin_menu_list.jsp").forward(req,resp);
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
}

6.21页面admin_menu_list.jsp

  <div class="widget-body">
                                    <ul class="b_P_Sort_list">
                                        <li><i class="fa fa-users green"></i> <a href="#">全部管理员(13)</a></li>
<%--                                   遍历一级菜单--%>
                                        <c:forEach items="${menu1List}" var="menu1">
                                        <li><i class="fa fa-users orange"></i> <a href="#">${menu1.menuName}</a></li>
                                        </c:forEach>
                                    </ul>
                                </div>

遍历二级菜单
 <div class="table_menu_list"  id="testIframe">
                    <table class="table table-striped table-bordered table-hover" id="sample_table">
                        <thead>
                        <tr>
                            <th width="25px"><label><input type="checkbox" class="ace"><span class="lbl"></span></label></th>
                            <th width="80px">菜单编号</th>
                            <th width="250px">菜单名称</th>
                            <th width="100px">菜单排序</th>
                            <th width="100px">菜单级别</th>
                            <th width="100px">菜单编号</th>
                            <th width="180px">菜单URL</th>
                            <th width="70px">状态</th>
                            <th width="200px">操作</th>
                        </tr>
                        </thead>
                        <tbody>
                        <c:forEach items="${menu2List}" var="menu2">
                        <tr>
                            <td><label><input type="checkbox" class="ace"><span class="lbl"></span></label></td>
                            <td>${menu2.menuCode}</td>
                            <td>${menu2.menuName}</td>
                            <td>${menu2.menuOrder}</td>
                            <td>${menu2.menuLevel}</td>
                            <td>${menu2.parentMenuCode}</td>
                            <td>${menu2.menuUrl}</td>
                            <td class="td-status"><span class="label label-success radius">已启用</span></td>
                            <td class="td-manage">
                                <a onClick="member_stop(this,'10001')"  href="javascript:;" title="停用"  class="btn btn-xs btn-success"><i class="fa fa-check  bigger-120"></i></a>
                                <a title="编辑" onclick="member_edit('编辑','member-add.html','4','','510')" href="javascript:;"  class="btn btn-xs btn-info" ><i class="fa fa-edit bigger-120"></i></a>
                                <a title="删除" href="javascript:;"  onclick="member_del(this,'1')" class="btn btn-xs btn-warning" ><i class="fa fa-trash  bigger-120"></i></a>
                            </td>
                        </tr>
                        </c:forEach>
                        </tbody>
                    </table>
                </div>

6.22增加页面admin_menu_list.jsp的ajax语句

<script type="text/javascript">
    function requestMenu2List(menu1Code) {
        //发送ajax请求,获取当前一级菜单下的二级菜单,res是一级菜单的集合
        $.post("Menu2ListByMenu1Servlet",{parentCode:menu1Code},function (res) {
            //将二级菜单通过DOM操作显示到表格中
            //a.将id=testIframe中原有的表格进行清除,同时重新加载一个table(id="testIframe")
            $("#testIframe").html("<table class=\"table table-striped table-bordered table-hover\" id=\"sample_table1\">\n" +
                "<thead>\n" +
                "<tr>\n" +
                "<th width=\"25px\"><label><input type=\"checkbox\" class=\"ace\"><span class=\"lbl\"></span></label></th>\n" +
                "<th width=\"80px\">菜单编号</th>\n" +
                "<th width=\"250px\">菜单名称</th>\n" +
                "<th width=\"100px\">菜单排序</th>\n" +
                "<th width=\"100px\">菜单级别</th>\n" +
                "<th width=\"100px\">菜单编号</th>\n" +
                "<th width=\"180px\">菜单URL</th>\n" +
                "<th width=\"70px\">状态</th>\n" +
                "<th width=\"200px\">操作</th>\n" +
                "</tr>\n" +
                "</thead>\n" +
                "<tbody></tbody></table>");

            //b.显示二级菜单
            for (var i = 0; i <res.length ; i++) {
             var menu2=res[i];
             var trTag="  <tr>\n" +
                 "<td><label><input type=\"checkbox\" class=\"ace\"><span class=\"lbl\"></span></label></td>\n" +
                 "<td>"+menu2.menuCode+"</td>\n" +
                 "<td>"+menu2.menuName+"</td>\n" +
                 "<td>"+menu2.menuOrder+"</td>\n" +
                 "<td>"+menu2.menuLevel+"</td>\n" +
                 "<td>"+menu2.parentMenuCode+"</td>\n" +
                 "<td>"+menu2.menuUrl+"</td>\n" +
                 "<td class=\"td-status\"><span class=\"label label-success radius\">已启用</span></td>\n" +
                 "<td class=\"td-manage\">\n" +
                 "<a onClick=\"member_stop(this,'10001')\"  href=\"javascript:;\" title=\"停用\"  class=\"btn btn-xs btn-success\"><i class=\"fa fa-check  bigger-120\"></i></a>\n" +
                 "<a title=\"编辑\" onclick=\"member_edit('编辑','member-add.html','4','','510')\" href=\"javascript:;\"  class=\"btn btn-xs btn-info\" ><i class=\"fa fa-edit bigger-120\"></i></a>\n" +
                 "<a title=\"删除\" href=\"javascript:;\"  onclick=\"member_del(this,'1')\" class=\"btn btn-xs btn-warning\" ><i class=\"fa fa-trash  bigger-120\"></i></a>\n" +
                 "</td>\n" +
                 "</tr>";
             $("#sample_table1 tbody").append(trTag);
            }
            //表格中的数据重新渲染了,分页效果也需要重新初始化
            //分页显示
                //将id=“sample_table”的表格进行初始化为数据表格(数据表格可排序,可分页)
            $('#sample_table1').dataTable( {
                "aaSorting": [[ 1, "desc" ]],//默认第几个排序
                "bStateSave": true,//状态保存
                "aoColumnDefs": [
                    {"orderable":false,"aTargets":[0,2,3,4,5,7,8,]}// 制定列不参与排序
                ] } );

            },"json")
        return false;
    }
</script>

6.22在 admin_menu_list.jsp 显示级菜单时,同时显示其状态

<c:forEach items="${menu2List}" var="menu2">
                        <tr>
                            <td><label><input type="checkbox" class="ace"><span class="lbl"></span></label></td>
                            <td>${menu2.menuCode}</td>
                            <td>${menu2.menuName}</td>
                            <td>${menu2.menuOrder}</td>
                            <td>${menu2.menuLevel}</td>
                            <td>${menu2.parentMenuCode}</td>
                            <td>${menu2.menuUrl}</td>
                            <td class="td-status">
                                <c:choose>
                                    <c:when test="${menu2.menuState == 1}">
                                        <span class="label label-success radius">已启用</span>
                                    </c:when>
                                    <c:otherwise>
                                        <span class="label label-defaunt radius">已停用</span>
                                    </c:otherwise>
                                </c:choose>
                            </td>
                            <td class="td-manage">
                                <c:choose>
                                    <c:when test="${menu2.menuState == 1}">
                                        <a onClick="member_stop(this,'10001')"  href="javascript:;" title="停用"  class="btn btn-xs btn-success">
                                            <i class="fa fa-check  bigger-120"></i>
                                        </a>
                                    </c:when>
                                    <c:otherwise>
                                        <a style="text-decoration:none" class="btn btn-xs " onClick="member_start(this,id)" href="javascript:;" title="启用">
                                            <i class="fa fa-close bigger-120"></i>
                                        </a>
                                    </c:otherwise>
                                </c:choose>
                                <a title="删除" href="javascript:;"  onclick="member_del(this,'1')" class="btn btn-xs btn-warning" ><i class="fa fa-trash  bigger-120"></i></a>
                            </td>
                        </tr>
                        </c:forEach>

6.23显示根据级菜单联动的级菜单状态

<script type="text/javascript">
    function requestMenu2List(menu1Code) {
        //发送ajax请求,获取当前一级菜单下的二级菜单,res是一级菜单的集合
        $.post("Menu2ListByMenu1Servlet",{parentCode:menu1Code},function (res) {
            //将二级菜单通过DOM操作显示到表格中
            //a.将id=testIframe中原有的表格进行清除,同时重新加载一个table(id="testIframe")
            $("#testIframe").html("<table class=\"table table-striped table-bordered table-hover\" id=\"sample_table1\">\n" +
                "<thead>\n" +
                "<tr>\n" +
                "<th width=\"25px\"><label><input type=\"checkbox\" class=\"ace\"><span class=\"lbl\"></span></label></th>\n" +
                "<th width=\"80px\">菜单编号</th>\n" +
                "<th width=\"250px\">菜单名称</th>\n" +
                "<th width=\"100px\">菜单排序</th>\n" +
                "<th width=\"100px\">菜单级别</th>\n" +
                "<th width=\"100px\">菜单编号</th>\n" +
                "<th width=\"180px\">菜单URL</th>\n" +
                "<th width=\"70px\">状态</th>\n" +
                "<th width=\"200px\">操作</th>\n" +
                "</tr>\n" +
                "</thead>\n" +
                "<tbody></tbody></table>");

            //b.显示二级菜单
            for (var i = 0; i <res.length ; i++) {
             var menu2=res[i];
             var str1=menu2.menuState==1?"<span class=\"label label-success radius\">已启用</span></td>":"<span class=\"label label-defaunt radius\">已停用</span></td>";
             var str2=menu2.menuState==1?"<a onClick=\"member_stop(this,'10001')\"  href=\"javascript:;\" title=\"停用\"  class=\"btn btn-xs btn-success\"><i class=\"fa fa-check  bigger-120\"></i></a>"
                 :"<a style=\"text-decoration:none\" class=\"btn btn-xs \" onClick=\"member_start(this,id)\" href=\"javascript:;\" title=\"启用\"><i class=\"fa fa-close bigger-120\"></i></a>";
             var trTag="  <tr>\n" +
                 "<td><label><input type=\"checkbox\" class=\"ace\"><span class=\"lbl\"></span></label></td>\n" +
                 "<td>"+menu2.menuCode+"</td>\n" +
                 "<td>"+menu2.menuName+"</td>\n" +
                 "<td>"+menu2.menuOrder+"</td>\n" +
                 "<td>"+menu2.menuLevel+"</td>\n" +
                 "<td>"+menu2.parentMenuCode+"</td>\n" +
                 "<td>"+menu2.menuUrl+"</td>\n" +
                 "<td class=\"td-status\">"+str1+"</td>\n" +
                 "<td class=\"td-manage\">"+str2+"</td>"+
                 "</tr>";
             $("#sample_table1 tbody").append(trTag);
            }
            //表格中的数据重新渲染了,分页效果也需要重新初始化
            //分页显示
                //将id=“sample_table”的表格进行初始化为数据表格(数据表格可排序,可分页)
            $('#sample_table1').dataTable( {
                "aaSorting": [[ 1, "desc" ]],//默认第几个排序
                "bStateSave": true,//状态保存
                "aoColumnDefs": [
                    {"orderable":false,"aTargets":[0,2,3,4,5,7,8,]}// 制定列不参与排序
                ] } );

            },"json")
        return false;
    }
</script>

6.24实现菜单的启用和停用

1. 完成数据库操作

public class MenuDAO {
//根据menuCode修改菜单状态
    public int updateMenuState(String menuCode,int state) throws SQLException {
        int i=0;
        String sql="UPDATE tb_menus SET menu_state=? WHERE menu_code=?;";
        Object[] params={state,menuCode};
        QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
        i = queryRunner.update(sql, params);
        return  i;
    }
}

2.完成业务逻辑层实现

public class MenuService {
 //启用菜单
    public boolean enableMenu(String menuCode) throws SQLException {
        return changeMenuState(menuCode,1);
    }
    //停用菜单
    public boolean disableMenu(String menuCode) throws SQLException {
        return changeMenuState(menuCode,0);
    }

    private boolean changeMenuState(String menuCode,int state) throws SQLException {
        MenuDAO menuDAO = new MenuDAO();
        int i = menuDAO.updateMenuState(menuCode, state);
        boolean b=i>0;
        return b;
    }
}

3.启用与停用功能实现

1. 创建 MenuStateChangeServlet 类

package com.it.servlets;
 
import com.google.gson.Gson;
import com.it.service.MenuService;
 
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;
import java.io.PrintWriter;
import java.sql.SQLException;
@WebServlet("/MenuStateChangeServlet")
public class MenuStateChangeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
 
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        MenuService menuService = new MenuService();
        req.setCharacterEncoding("utf-8");
        String menuCode = req.getParameter("menuCode");
        String oper = req.getParameter("oper");
//根据oper执行启用或停用
        MenuService menuService1 = new MenuService();
        Gson gson = new Gson();
        boolean b=false;
        if ("stop".equals(oper)){
            //停用操作
            try {
               b = menuService.disableMenu(menuCode);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }else if ("start".equals(oper)){
            //启用
            try {
               b = menuService.enableMenu(menuCode);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        //返回操作结果(响应ajax请求)
        //构造JSon格式字符串来响应
        String jsonStr=b?"{\"code\":1000,\"msg\":\"success\"}":"{\"code\":1001,\"msg\":\"fail\"}";
        resp.setContentType("application/json;charset=utf-8");
        resp.setContentType("utf-8");
        PrintWriter writer = resp.getWriter();
        writer.println(jsonStr);
        writer.flush();
        writer.close();
    }
}

2. 在 amdin_menu_list.jsp 点击停用或启用按钮,通过ajax请 求 MenuStateChangeServlet 类

/*菜单-停用*/
    function member_stop(obj,id){
        //1.提示确认是否要停用
        layer.confirm('确认要停用吗?',function(index){
            //发送ajax请求,MenuStateChangeServlet,将当前菜单停用掉。
            $.post("MenuStateChangeServlet",{menuCode:id,oper:"stop"},function (res) {
                if (res.code == 1000){
                    //2.将按钮状态修改为启用状态
                    $(obj).parents("tr").find(".td-manage").prepend('<a style="text-decoration:none" class="btn btn-xs " onClick="member_start(this,id)" href="javascript:;" title="启用"><i class="fa fa-close bigger-120"></i></a>');
                    //3.将菜单显示的状态修改为已停用
                    $(obj).parents("tr").find(".td-status").html('<span class="label label-defaunt radius">已停用</span>');
                    //移除当前按钮
                    $(obj).remove();
                    //弹窗显示操作成功!
                    layer.msg('已停用!',{icon: 5,time:1000});
                } else if (res.code == 1001) {
                    layer.msg('停用操作失败!',{icon:5,time:1000})
                }
            },"json")
        });
    }
    /*菜单-启用*/
    function member_start(obj,id){
        layer.confirm('确认要启用吗?',function(index){
            $.post("MenuStateChangeServlet",{menuCode:id,oper:"start"},function (res) {
                if (res.code == 1000) {
                    $(obj).parents("tr").find(".td-manage").prepend('<a style="text-decoration:none" class="btn btn-xs btn-success" onClick="member_stop(this,id)" href="javascript:;" title="停用"><i class="fa fa-check  bigger-120"></i></a>');
                    $(obj).parents("tr").find(".td-status").html('<span class="label label-success radius">已启用</span>');
                    $(obj).remove();
                    layer.msg('已启用!',{icon: 6,time:1000});
                }else if (res.code ==1001) {
                    layer.msg('启用失败!',{icon: 6,time:1000});
                }
            },"json");
        });
    }

6.25管理员登录成功后隐藏禁用菜单

1.设置为不可用

在Index.jsp页面添加如下语句

 <!-- 菜单2 -->
          <c:forEach items="${menuList}" var="menu1">
          <li>
            <a href="#" class="dropdown-toggle">
              <i class="${menu1.menuIcon}"></i>
              <span class="menu-text"> ${menu1.menuName} </span>
              <b class="arrow icon-angle-down"></b>
            </a>
            <ul class="submenu">
              <c:forEach items="${menu1.childMenus}" var="menu2">
              <li class="home">
                <c:if test="${menu2.menuState==1}">
                <a  href="javascript:void(0)" name="${menu2.menuUrl}"  title="${menu2.menuName}" class="iframeurl">
                  <i class="icon-double-angle-right"></i>${menu2.menuName}[停用]                </a>
                </c:if>
                <c:if test="${menu2.menuState==0}">
                  <a  href="javascript:void(0)"  class="iframeurl">
                    <i class="icon-double-angle-right"></i>${menu2.menuName}
                  </a>
                </c:if>
              </li>
              </c:forEach>
            </ul>
          </li>
          </c:forEach>

6.26创建角色实体类

package com.it.entity;

public class Role {
    private int roleId;
    private String roleName;
    private String roleDesc;

    //    创建一个实体,一般情况下应写出它的无参构造器,全参构造器,get和set方法,toString方法
    public Role() {
    }

    public Role(int roleId, String roleName, String roleDesc) {
        this.roleId = roleId;
        this.roleName = roleName;
        this.roleDesc = roleDesc;
    }

    @Override
    public String toString() {
        return "Role{" +
                "roleId=" + roleId +
                ", roleName='" + roleName + '\'' +
                ", roleDesc='" + roleDesc + '\'' +
                '}';
    }

    public int getRoleId() {
        return roleId;
    }

    public void setRoleId(int roleId) {
        this.roleId = roleId;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleDesc() {
        return roleDesc;
    }

    public void setRoleDesc(String roleDesc) {
        this.roleDesc = roleDesc;
    }
}

6.27查询角色DAO

创建DAO类,完成数据库操作。
package com.it.dao;

import com.it.entity.Role;
import com.it.untils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 完成对角色信息的数据库访问操作
 */
public class RoleDAO {
    /**
     * 查询对所有的角色信息
     */
    public List<Role> selectRoles(){
        List<Role> roleList=new ArrayList<>();
        try {
            String sql="select role_id roleId,role_name roleName,role_desc roleDesc from tb_roles";
            QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
            roleList= queryRunner.query(sql, new BeanListHandler<Role>(Role.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return roleList;
    }
}

6.28查询角色DAO类的测试类

package test.dao;

import com.it.dao.RoleDAO;
import com.it.entity.Role;
import org.junit.Test;

import java.util.List;

import static org.junit.Assert.*;

public class RoleDAOTest {
    private RoleDAO roleDAO=new RoleDAO();

    @Test
    public void selectRoles() {
        List<Role> roleList = roleDAO.selectRoles();
        assertEquals(5,roleList.size());
    }
}

6.29创建角色Service类(业务逻辑层)

package com.it.service;

import com.it.dao.RoleDAO;
import com.it.entity.Role;

import java.util.List;

public class RoleService {
    private RoleDAO roleDAO=new RoleDAO();
    public List<Role> getRoles(){
        List<Role> roleList = roleDAO.selectRoles();
        return roleList;
    }
}

6.30创建角色Servlet类

package com.it.servlets;

import com.it.entity.Role;
import com.it.service.RoleService;

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;
import java.util.List;

@WebServlet("/RoleListServlet")
public class RoleListServlet extends HttpServlet {
    private RoleService roleService=new RoleService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1、查询所有角色的信息
        List<Role> roleList = roleService.getRoles();
        //2、将角色列表传递到admin_role_list.jsp
        request.setAttribute("roleList",roleList);
        request.getRequestDispatcher("admin_role_list.jsp").forward(request,response);
    }
}

6.31查询一级列表菜单

在MenuService中新增一个方法,由于查询一级列表菜单。
public List<Menu1> listAllMenus(){
        //1.查询到所有的一级菜单(此时的一级菜单中是不包含二级菜单的)
        List<Menu1> menu1List = menuDAO.selectMenu1();

        //2.遍历已经查询到的一级菜单,依次查询每个一级菜单中的二级菜单
        for (int i = 0; i < menu1List.size(); i++) {
            Menu1 menu1 = menu1List.get(i);
            //根据一级菜单的menuCode查询二级菜单
            List<Menu2> menu2List = menuDAO.selectMenu2ByMenu1Code(menu1.getMenuCode());
            //将查询到二级菜单设置到当前一级菜单对象中
            menu1.setChildMenus(menu2List);
        }
        return menu1List;
    }

6.32创建查询菜单Servlet类

package com.it.servlets;
/*
角色管理-添加新角色-查询菜单列表
 */
import com.it.entity.Menu1;
import com.it.service.MenuService;

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;
import java.util.List;

@WebServlet("/MenuListAllServlet")
public class MenuListAllServlet extends HttpServlet {
    private MenuService menuService=new MenuService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、查询所有的系统菜单
        List<Menu1> menu1List = menuService.listAllMenus();
        //2、将查询到的系统菜单集合直接传递到admin_list_add.jsp页面中
        request.setAttribute("menu1List",menu1List);
        request.getRequestDispatcher("admin_list_add.jsp").forward(request,response);
    }
}

6.33添加角色信息DAO

public int insertRole(Role role){
  int i = 0;
  try {
  String sql = "insert into tb_roles(role_name,role_desc) values(?,?)";
  QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
            //返回的生成的主键存储在一个BigInterger对象中
Long  object = queryRunner.insert(sql, new ScalarHandler<>(), role.getRoleName(), role.getRoleDesc());
            //将BigInteger转换成int类型,赋值给i
    i = object.intValue();
    } catch (SQLException e) {
   e.printStackTrace();
    }
   return i;
    }

6.34添加角色和菜单关联关系DAO类

 public int insertRoleAndMenu(int roleId,int menuId){
  int i=0;
  try {
     String sql="insert into tb_role_menu(role_id,menu_id) values(?,?)";
  QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
       i=queryRunner.update(sql,roleId,menuId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return i;
    }

6.35添加角色Service类

public class RoleService {
    private RoleDAO roleDAO=new RoleDAO();
    public List<Role> getRoles(){
        List<Role> roleList = roleDAO.selectRoles();
        return roleList;
    }
    //menuIds为所勾选的复选框的个数
    public boolean addRole(Role role,String[] menuIds)
    {
        boolean b=true;
        //1、保存角色信息,获取自动生成的角色ID
        int roleId=roleDAO.insertRole(role);
        //2、保存角色和菜单之间的关联
        if(menuIds != null) {
            for (int i = 0; i < menuIds.length; i++) {
                int menuId = Integer.parseInt(menuIds[i]);
                int j = roleDAO.insertRoleAndMenu(roleId, menuId);
                b = b && j > 0;
            }
        }
        return b;
    }
}

6.36添加角色Servlet类

public class RoleAddServlet extends HttpServlet {
    private RoleService roleService=new RoleService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1、接收角色名称和角色描述
        request.setCharacterEncoding("utf-8");
        String roleName=request.getParameter("roleName");
        String roleDesc=request.getParameter("roleDesc");
        Role role=new Role(0,roleName,roleDesc);
        //2、获取选择的菜单权限的Id
        String[] menuIds = request.getParameterValues("menuId");
        //String[] menu2Ids = request.getParameterValues("menu2Id");
        //3、保存角色信息
        boolean b = roleService.addRole(role, menuIds);
        //4、角色添加成功之后,调到提示页面prompt.jsp,并提示操作结果
        String tips=b?"<label style='color:green'>添加角色信息成功</label>":"<label style='color:red'>添加角色信息失败</label>";
        request.setAttribute("tips",tips);
        request.getRequestDispatcher("prompt.jsp").forward(request,response);


    }
}

        6.37删除角色DAO

public int deleteRoleAndMenuByRoleId(int roleId){
        int i=0;
        try {
            String sql="delete from tb_role_menu where role_id=?";
            QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
            i = queryRunner.update(sql, roleId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return i;
    }
    /**
     * 根据角色ID删除角色信息
     */
    public int deleteRoleByRoleId(int roleId){
        int i=0;
        try {
            String sql="delete from tb_roles where role_id=?";
            QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
            i = queryRunner.update(sql, roleId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return i;
    }

6.39删除角色DAO类的测试类

public void testDeleteRoleAndMenu(){
        int i = roleDAO.deleteRoleAndMenuByRoleId(51);
        System.out.println(i);
    }
    @Test
    public void testDeleteRole(){
        int i = roleDAO.deleteRoleByRoleId(51);
        System.out.println(i);
    }

6.40删除角色Service类

public boolean deleteRole(int roleId){
        int i = roleDAO.deleteRoleAndMenuByRoleId(roleId);
        int j = roleDAO.deleteRoleByRoleId(roleId);
        boolean b=j>0;
        return b;
    }

6.41删除角色Servlet类

@WebServlet("/RoleDeleteServlet")
public class RoleDeleteServlet extends HttpServlet {
    private RoleService roleService=new RoleService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //接受角色ID
        int roleId = Integer.parseInt(request.getParameter("roleId"));
        //调用RoleService执行删除
        boolean b = roleService.deleteRole(roleId);
        //删除成功后,响应前端的Ajax请求
        String str=b?"{\"code\":1000,\"msgs\":\"success\"}":"{\"code\":1001,\"msgs\":\"fail\"}";
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        out.println(str);
        out.flush();
        out.close();
    }
}

6.42批量删除Servlet类

public class RoleMutilDeleteServlet extends HttpServlet {
    private RoleService roleService=new RoleService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //1、接收点击批量删除的角色ID
        String[] roleIds = request.getParameterValues("roleId");
        //2、遍历roleIds,执行依次删除
        //failIds存储的是删除失败的角色ID
        List<Integer> failIds=new ArrayList<>();
        for(int i=0;i<roleIds.length;i++){
            int roleId=Integer.parseInt(roleIds[i]);
            boolean b = roleService.deleteRole(roleId);
            if(b==false){
                failIds.add(roleId);
            }
        }
        //提示信息
        String ids="";
        for (Integer id:failIds) {
            ids+=","+id;
        }
        String tips=failIds.size()==0?"多个角色删除成功!":ids+"删除失败!";
        request.setAttribute("tips",tips);
        //查询删除后的角色列表
        List<Role> roleList = roleService.getRoles();
        request.setAttribute("roleList",roleList);
        request.getRequestDispatcher("admin_role_list.jsp").forward(request,response);
    }
}

6.43修改角色DAO类(数据回显)

/**
     * 根据角色ID查询角色信息
     */
    public Role selectRoleById(int roleId){
        //先定义一个role对象
        Role role=null;
        //query(1、SQL语句 2、返回类型 3、SQL参数)
        try {
            String sql="select role_id roleId,role_name roleName,role_desc roleDesc from tb_roles where role_id=?";
            QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
            role=queryRunner.query(sql,new BeanHandler<Role>(Role.class),roleId);
        } catch (SQLException e){
            e.printStackTrace();
        }
        return role;
    }
    /**
     * 根据角色ID查询当前角色所拥有的的权限ID
     */
    public List<Integer> selectMenuIdsByRoleId(int roleId){
        List<Integer> mids=new ArrayList<>();
        try {
            String sql="select menu_id from tb_role_menu where role_Id=?";
            QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
            //自定义结果集处理器,使用while循环menuid
            ResultSetHandler<List<Integer>> resultSetHandler = new ResultSetHandler<List<Integer>>() {
                @Override
                public List<Integer> handle(ResultSet resultSet) throws SQLException {
                    List<Integer>list=new ArrayList<>();
                    while(resultSet.next()){
                        int mid=resultSet.getInt("menu_id");
                        list.add(mid);
                    }
                    return list;
                }
            };
           mids =queryRunner.query(sql,resultSetHandler,roleId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return mids;
    }

6.44修改角色DAO测试类

 @Test
    public void testSelectRoleById(){
        Role role = roleDAO.selectRoleById(1);
        System.out.println(role);
    }
    @Test
    public void testSelectMenuIdsByRoleId(){
        List<Integer> list = roleDAO.selectMenuIdsByRoleId(1);
        System.out.println(list);
    }

6.45修改角色Service类(数据回显)

 /**
     * 根据角色ID查询角色信息
     */
    public Role getRoleById(int roleId){
        return roleDAO.selectRoleById(roleId);
    }
    /**
     * 根据角色ID查询角色所拥有的权限ID
     */
    public List<Integer> getMenuIdsByRole(int roleId){
        return roleDAO.selectMenuIdsByRoleId(roleId);
    }

6.46修改角色Servlet类(数据回显)

public class RoleQueryServlet extends HttpServlet {
    private RoleService roleService=new RoleService();
    private MenuService menuService=new MenuService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、接受传递过来的角色ID
        String rid = request.getParameter("roleId");
        int roleId=rid==null?0:Integer.parseInt(rid);
        //2、根据角色ID查询角色原始信息
        Role role = roleService.getRoleById(roleId);
        //3、查询系统中的角色菜单列表
        //a、查询所有的菜单
        List<Menu1> menu1List = menuService.listAllMenus();
        //b、查询当前角色所拥有的的菜单Id
        List<Integer> menuIds = roleService.getMenuIdsByRole(roleId);
        //c、判断所有菜单中,那些菜单是该角色所拥有的
        for (int i = 0; i <menu1List.size() ; i++) {
            //每循环一次会生成一个一级菜单
            Menu1 menu1 = menu1List.get(i);
            //如果menuIds中包含该菜单的Id,则说明该角色拥有该权限。
            if(menuIds.contains(menu1.getMenuId())){
                menu1.setHaveMenu(true);
            }
            //判断二级权限
            for (int j = 0; j <menu1.getChildMenus().size() ; j++) {
                Menu2 menu2 = menu1.getChildMenus().get(j);
                if(menuIds.contains(menu2.getMenuId())){
                    menu2.setHaveMenu(true);
                }
            }

        }
        //4、将角色信息 及菜单集合传递到admin_role_modify.jsp页面
        request.setAttribute("role",role);
        request.setAttribute("menu1List",menu1List);
        request.getRequestDispatcher("admin_role_modify.jsp").forward(request,response);
    }
}

6.47修改角色视图层(数据回显关键代码)

<c:forEach items="${menu1List}" var="menu1">
                    <c:if test="${menu1.childMenus !=[] }">
                        <dl class="cl permission-list2">
                            <dt>
                                <label class="middle">
                                    <c:choose>
                                        <c:when test="${menu1.haveMenu}">
                                    <input type="checkbox" value="" class="ace"  name="user-Character-0-0" id="id-disable-check" checked>
                                        </c:when>
                                    <c:otherwise>
                                        <input type="checkbox" value="" class="ace"  name="user-Character-0-0" id="id-disable-check">
                                    </c:otherwise>
                                    </c:choose>
                                    <span class="lbl">${menu1.menuName}</span>
                                </label>
                            </dt>
                            <dd>
                                <c:forEach items="${menu1.childMenus }" var="menu2">
                                <label class="middle">
                                   <c:choose>
                                       <c:when test="${menu2.haveMenu}">
                                           <input type="checkbox" value="" class="ace" name="user-Character-0-0-0" id="user-Character-0-0-0" checked>
                                       </c:when>
                                       <c:otherwise>
                                           <input type="checkbox" value="" class="ace" name="user-Character-0-0-0" id="user-Character-0-0-0">
                                       </c:otherwise>
                                   </c:choose>
                                    <span class="lbl">${menu2.menuName}</span>
                                </label>
                                </c:forEach>

6.48修改角色DAO

public int updateRole(Role role){
        int i=0;
        try {
            String sql="update from tb_roles set role_name=?,role_desc=? where role_id=?";
            QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
            Object[] params={role.getRoleName(),role.getRoleDesc(),role.getRoleId()};
            i=queryRunner.update(sql,params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return i;
    }
    /**
     * 根据角色ID删除当前角色对应的角色菜单关联
     */
    public int deleteRoleAndMenu(int roleId){
        int i=0;
        try {
            String sql="delete from tb_role_menu where role_id=?";
            QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
            i = queryRunner.update(sql, roleId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return i;
    }

6.49修改角色Service类

public boolean updateRole(Role role,String[] menuIds){
        //1、修改角色信息
        int i = roleDAO.updateRole(role);
        //2、删除当前角色的原始权限
        int j = roleDAO.deleteRoleAndMenuByRoleId(role.getRoleId());
        //3、新增选择的所有权限
        for(int k=0;k<menuIds.length;k++){
            int menuId =Integer.parseInt(menuIds[k]);
            int m = roleDAO.insertRoleAndMenu(role.getRoleId(), menuId);
        }
        //对于修改角色信息,角色是可以没有权限的,因此只要i>0即角色信息修改成功即可。
        return i>0;
    }

6.50修改角色Servlet类

public class RoleUpdateServlet extends HttpServlet {
    private RoleService roleService=new RoleService();
    private MenuService menuService=new MenuService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //接受修改后角色的信息
        request.setCharacterEncoding("utf-8");
        int roleId =Integer.parseInt( request.getParameter("roleId"));
        String roleName = request.getParameter("roleName");
        String roleDesc= request.getParameter("roleDesc");
        Role role = new Role(roleId, roleName, roleDesc);
        //获取传递过来的菜单ID
        String[] menuIds = request.getParameterValues("menuId");
        //执行修改
        boolean b = roleService.updateRole(role, menuIds);
        //跳转到提示页面进行提示
        String tips=b?"<label style='color:green'>角色信息修改成功</label>":"<label style='color:red'>角色信息修改失败</label>";
        request.setAttribute("tips",tips);
        request.getRequestDispatcher("prompt.jsp").forward(request,response);
    }
}

后续还有很多代码不再一一展示,编写规范都是一样的,参照以上代码可以做到举一反三。

该开发帮助说明书是在项目开发过程中编写的,编写过程中后面的功能可能会在前面功能的类里面添加代码,但为了的理解开发过程,没有对前面代码进行更新覆盖,该文章中的代码主要作为开发思路,开发规范化指引。整个项目已经上传资源,想要研究的可以自行免费下载。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做一道光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值