精华内容
下载资源
问答
  • Java用户管理系统 千次阅读 多人点赞
    2020-07-29 14:36:35

    Java用户管理系统

    对一个网站用户的信息管理,对用户的信息进行增删改查,使得用户的信息管理工作更加方便快捷,从而提高工作效率,降低管理成本。

    1.系统设计背景和目的

    当今时代信息量不断增加,已经以几何级别的增长。信息量增长的速度远比人类理解的速度要快,并以海浪式四面八方涌入人类的生活。对于一个平台而言,管理庞大的用户数据,仅仅是依靠传统的纸质文档进行记录,就显得尤为吃力。因此,对庞大的用户信息来创建一个数据库存储,并使用Java的GUI图像化界面来管理用户信息的这一需求十分迫切。

    本系统的目的是实现对一个网站用户的信息管理,对用户的信息进行增删改查,使得用户的信息管理工作更加方便快捷,从而提高工作效率,降低管理成本。

    2.需求分析

    1. 查询所有用户信息
    2. 查询某一位用户信息
    3. 修改某一位用户信息
    4. 新增一条用户信息
    5. 删除某一位用户信息

    3.使用工具

    Eclipse、MySQL、Navicat
    

    4.系统设计图

    功能模块图
    数据流程图
    E-R图

    5.数据库设计

    1.关系模式(带*表示主键)

       管理员(*账号*,密码)
    
       用户(*用户编号*,用户名,手机号,性别,住址,邮箱)
    

    2.数据字典
    数据字典

    5.系统实现的效果图

    1.用户登陆
    登陆
    2.用户信息录入

    (1)录入成功!录入信息

    (2)录入失败
    在这里插入图片描述

    3.查询所有用户信息
    所有用户信息

    4.还有一些图片和完整的代码,由于太多了,暂时先不放了。。
    如果有需要代码或完整文档,可以关注我并留言,私聊发。

    更多相关内容
  • java+MySQL用户管理系统

    热门讨论 2013-04-25 16:32:35
    此代码主要是用JDBC和MySQL数据库完成一个简单的用户管理系统,系统的设计模式采用工场模 式和代 理模式,此代码很适合初学Java者。 运行方法: 1.运行需要启动MySQL数据库 2.创建数据库名为zhaochao和表名为...
  • Java用户管理系统【完整版】

    千次阅读 多人点赞 2022-03-19 11:27:11
    JavaWeb项目用户管理系统
    • 💂 个人主页: 陶然同学
    • 🤟 版权: 本文由【陶然同学】原创、在CSDN首发、需要转载请联系博主
    • 💬 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦
    • 💅 想寻找共同成长的小伙伴,请点击【Java全栈开发社区
    •  💬推荐一款模拟面试、刷题神器👉点击跳转此网站

    项目介绍

            名称:UMS

    UMS : User Manager System , 用户管理系统

            整体需求

    1)查询所有【阶段 1】 
    2)添加【阶段 1】 
    3)删除【阶段 1】 
    4)查询详情【阶段 1】 
    5)条件查询【阶段 1】 
    6)修改【阶段 2】

            搭建环境

    步骤 1:创建 web 项目 
    步骤 2:导入 jar 包 
    步骤 3:创建 package 包及 JavaBean 

    public class User { 
     private String id; //唯一标识 
     private String loginName; //登录名 
     private String loginPwd; //登录密码 
     private String userName; //用户名(昵称) 
     private String sex; //性别 
     private String education; //学历 
     private String birthday; //生日 
     private String telephone; //电话 
     private String[] interest; //兴趣爱好 
     private String remark; //备注 
     private String utype; //权限: 管理员/普通用户 
    }

    查询所有

            需求说明

            需求分析

            代码实现

    /login/left.jsp 

    UserServlet

    UserService

    UserDao

    /user/list.jsp 

    添加用户

            需求说明

            需求分析

            代码实现

    /user/add.jsp

    UserServlet 

     UserService 

    UserDao  

     

    查询制定用户信息

            需求说明

            需求分析

            代码实现

    /user/list.jsp

    UserServlet

      UserService 

            思考

    查询条件如何保存并展示在 JSP 页面上

    删除指定用户信息

            需求说明

            需求分析

            代码实现

    /user/list.jsp

    UserServlet 

    UserService 

    UserDao 

            思考

    删除前弹出确认框 

    查询详情

            需求说明

            需求分析

            代码实现

    /user/list.jsp

    UserServlet

    UserService

    /user/view.jsp  

    编辑用户

            需求说明

    遇到这样的复杂需求,我们需要拆分成两步来做: 
    1、 用户数据查询展示:点击编辑,查询某个用户数据,在 JSP 页面展示 
    2、 用户数据修改:编辑页面,点击“确定”,将数据写入硬盘文件,并返回列表展示  

            用户数据查询展示

                    需求分析

                    代码实现

    /user/list.jsp

    UserServlet 

    /user/edit.jsp

            用户数据修改

                    需求分析

                    代码实现

    /user/edit.jsp

    UserServle

     UserService 

    UserDao

    用户登录

            需求说明

            需求分析

            代码实现

    /login/login.jsp

    UserServlet 

    UserService 

     Index.jsp

    /login/login.jsp 

    验证码校验

            需求说明

            点击切换验证码

                    需求分析

                    代码实现

    /login/login.jsp

    UtilsServlet

            验证码校验

                    需求分析

                    代码实现

    /login/login.jsp

     UserServlet 

    记住用户名

            需求说明

            需求分析

            代码实现

    /login/login.jsp 

    UserServlet

    /login/login.jsp(回显展示) 

    自动登录

            需求说明

            需求分析

            代码实现

     /login/login.jsp 

    UserServlet 

      

    权限校验

            需求说明

            需求分析

    改用户管理的超链接为/adminUser?method=list,方便一会的拦截  

            代码实现

    PowerFilter

    展开全文
  • 本项目是个java开发的简单的用户管理系统,因为能力有限,我做的界面丑陋了些,大家见谅 实现的功能:登录、添加用户、修改用户(修改的时候用户原始数据显示到界面上、单个删除用户和多个删除用户、数据的分页和...

    1.简介

            本项目是个java开发的简单的用户管理系统,因为能力有限,我做的界面丑陋了些,大家见谅

            实现的功能:登录、添加用户、修改用户(修改的时候用户原始数据显示到界面上、单个删除用户和多个删除用户、数据的分页和跳转、url过滤器

            因为我写的时候是开了两个tomcat服务器 将图片存储到另一个服务器上进行访问 大家这里有疑问的也欢迎咨询哈 同时如果有小伙伴想要项目源文件的欢迎加qq群

    2.准备工作

            1.1开发工具

                    IDEA2019、SQLYog  、HBuilder

            1.2使用语言

                    SQL、Java、HTML、JSP

            1.3前端框架

                    BootStrap     

            1.4导入的jar包

    3.项目文件结构

     

     4.代码

    sql

    /*
    SQLyog Ultimate v13.1.1 (64 bit)
    MySQL - 5.7.29 : Database - contact_sys
    *********************************************************************
    */
    
    /*!40101 SET NAMES utf8 */;
    
    /*!40101 SET SQL_MODE=''*/;
    
    /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
    /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
    /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
    /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
    CREATE DATABASE /*!32312 IF NOT EXISTS*/`contact_sys` /*!40100 DEFAULT CHARACTER SET utf8 */;
    
    USE `contact_sys`;
    
    /*Table structure for table `client` */
    
    DROP TABLE IF EXISTS `client`;
    
    CREATE TABLE `client` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(32) DEFAULT NULL,
      `password` varchar(32) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
    
    /*Data for the table `client` */
    
    insert  into `client`(`id`,`username`,`password`) values 
    (1,'张三','123456');
    
    /*Table structure for table `contact` */
    
    DROP TABLE IF EXISTS `contact`;
    
    CREATE TABLE `contact` (
      `cid` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL,
      `gender` varchar(4) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `phone` varchar(11) DEFAULT NULL,
      `email` varchar(255) DEFAULT NULL,
      `qq` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`cid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8;
    
    /*Data for the table `contact` */
    
    insert  into `contact`(`cid`,`name`,`gender`,`age`,`phone`,`email`,`qq`) values 
    (28,'科比','男',34,'1231','1346888','ce88029a735b44d3b553a917911b13f30d6583f95051415da21b8fcdbcae8a8d4.png'),
    (29,'户','男',34,'1516152','14561113@qq.com','4083a5d95fdb4442ae937bc0da1904102bafe2f833de4744878e3142d2ce488e74eacec67ede492f88c9be61c2602adfea21bcc015944f3091c270736d52c3ec5.png'),
    (30,'张三','男',7848,'1551674585','1346888','9e1ae3313c5e4793ae94be0f4be69d96b59d1750411a46ff88ad3b716cf632c23.png'),
    (31,'打','男',24,'1551674585','sdada13@162','53b1005dbd6a4923b782a067cdf48e0150b979f34c214911b6bf6c07035c560659cd76a4281f46eda598540a91cd50272.png');
    
    /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
    /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
    /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
    /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
    

     pojo

    package com.javacoffee.pojo;
    
    public class Client {
        //创建Client类 和数据库中的client表对应好
        private Integer id;
        private String username;
        private String password;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    

    package com.javacoffee.pojo;
    
    public class Contact {
        //创建Contact类 和数据库中的字段名对应好
        private Integer cid;
        private String name;
        private String gender;
        private Integer age;
        private String phone;
        private String email;
        private String qq;
    
        public Contact() {
        }
    
        public Integer getCid() {
            return cid;
        }
    
        public void setCid(Integer cid) {
            this.cid = cid;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public String getQq() {
            return qq;
        }
    
        public void setQq(String qq) {
            this.qq = qq;
        }
    
        @Override
        public String toString() {
            return "Contact{" +
                    "cid=" + cid +
                    ", name='" + name + '\'' +
                    ", gender='" + gender + '\'' +
                    ", age=" + age +
                    ", phone='" + phone + '\'' +
                    ", email='" + email + '\'' +
                    ", qq='" + qq + '\'' +
                    '}';
        }
    }
    

     dao

    package com.javacoffee.dao;
    
    import com.javacoffee.pojo.Client;
    
    public interface ClientDao {
        Client login(String username, String password);
    }
    

    package com.javacoffee.dao;
    
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.util.PageBean;
    
    import java.util.List;
    
    public interface ContactDao {
        //面向接口编程
        public void addContact(Contact contact);//添加联系人
        public void updateContact(Contact contact);//修改联系人
        public void deleteContact(Integer cid);//删除联系人
        public List<Contact> findAll();  //查询所有联系人
        public Contact findById(Integer cid);//根据编号查询联系人
        public PageBean findByPage(PageBean pageBean);//分页
        public void deleteAll(String[] cids);//删除全选
    
        Contact selectPhone(String phone);
    
    }
    

    dao实现类

    package com.javacoffee.dao.impl;
    
    import com.javacoffee.dao.ClientDao;
    import com.javacoffee.pojo.Client;
    import com.javacoffee.util.JdbcUtil;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    
    import java.sql.SQLException;
    
    public class ClientDaoImpl implements ClientDao {
        @Override
        public Client login(String username, String password) {
            //登陆的查询语句
            String sql = "select * from client where username = ? and password = ?";
            Object[] objects = {username,password};
            try {
                return  JdbcUtil.getQueryRunner().query(sql, new BeanHandler<Client>(Client.class), objects);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throw new RuntimeException("sql语句异常");
        }
    
    }
    
    package com.javacoffee.dao.impl;
    
    import com.javacoffee.dao.ContactDao;
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.util.JdbcUtil;
    import com.javacoffee.util.PageBean;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.apache.commons.dbutils.handlers.ScalarHandler;
    
    import java.sql.SQLException;
    import java.util.List;
    
    public class ContactDaoImpl implements ContactDao {
    
        //添加联系人的方法
        @Override
        public void addContact(Contact contact) {
            //sql语句 后面加上参数
            String sql = "insert into contact(name,gender,age,phone,email,qq) values(?,?,?,?,?,?)";
            //创建一个object数组,并把需要传的参数放入数组中
            Object[] objects = {contact.getName(),contact.getGender(),contact.getAge(),contact.getPhone(),contact.getEmail(),contact.getQq()};
            try {
                //执行sql语句 我导入了dbUtil包,所以直接得到queryRunner对象执行sql语句
                JdbcUtil.getQueryRunner().update(sql,objects);
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public void updateContact(Contact contact) {
            //修改的sql语句
            String sql = "update contact set name = ?,gender = ?,age=  ?,phone = ?,email = ?,qq = ? where cid = ?";
            //和增加很一样,先赋值到数组 再执行sql语句
            Object[] objects = {contact.getName(),contact.getGender(),contact.getAge(),contact.getPhone(),contact.getEmail(),contact.getQq(),contact.getCid()};
            try {
                JdbcUtil.getQueryRunner().update(sql,objects);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void deleteContact(Integer cid) {
            //删除sql语句
            String sql = "delete from contact where cid = ?";
            try {
                //传参可以直接传入sql语句和 cid形式参数
                JdbcUtil.getQueryRunner().update(sql,cid);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public List<Contact> findAll() {
            //返回值为List集合 sql语句如下
            String sql = "select * from contact";
            try {
                //也是通过dbUtil工具类来执行sql语句,因为输出的为List集合,所以第一个参数为sql语句 第二个如下
                return JdbcUtil.getQueryRunner().query(sql, new BeanListHandler<Contact>(Contact.class));
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throw new RuntimeException("列表无数据");
        }
    
        @Override
        public Contact findById(Integer cid) {
            //这个是通过id来进行查找
            String sql = "select * from contact where cid = ?";
            try {
                //返回值为一个对象 所以第二个参数也变成如下了,第三个参数放入cid
                return JdbcUtil.getQueryRunner().query(sql, new BeanHandler<Contact>(Contact.class), cid);
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
            throw new RuntimeException("没有这个id");
        }
        @Override
        public PageBean findByPage(PageBean pageBean) {
            //分页 这里是通过sql语句分的 比较基础
            String sql = "select * from contact limit ?,?";
            //传入的是PageBean对象,来获取当前页号和每页的记录数
            //大家可一思考一下 select * from contact limit 0,3 是查找第一个到第三个的数据
            // select * from contact limit 3,3 是查找第四个到第六个的 以此类推
            Object[] objects = {(pageBean.getPageNum()-1)*pageBean.getPageSize(),pageBean.getPageSize()};
            try {
                //传入每页的数据
                List<Contact> query = JdbcUtil.getQueryRunner().query(sql, new BeanListHandler<Contact>(Contact.class), objects);
                pageBean.setPageData(query);
    
                //查找数据总数
                String sql1 = "select count(cid) from contact";
                //强转为Long类型数据
                Long query1 = (Long)JdbcUtil.getQueryRunner().query(sql1, new ScalarHandler<>());
                //将查找出来的数据再转化为int类型数据存入pageBean中
                pageBean.setTotalData(query1.intValue());
                //可以在控制台打印一下看看是不是存入
    //            System.out.println(pageBean.getTotalData());
    
                //计算总页数  用了三目运算符
                //当 总数据数除以每页的数据数结果余数为0时候,说明总页数是总数据数除以每页的数据数结果取整
                //反之则需要加一
                Integer totalCount = pageBean.getTotalData()%pageBean.getPageSize()==0 ?
                        pageBean.getTotalData()/pageBean.getPageSize() :
                        pageBean.getTotalData()/pageBean.getPageSize() + 1;
                //然后赋值
                pageBean.setTotalCount(totalCount);
                //返回这个对象
                return pageBean;
    
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throw new RuntimeException("无法获取对象");
        }
    
        @Override
        public void deleteAll(String[] cids) {
            //输入sql语句 通过cid来进行多个删除 可以看到传入的参数为cids是一个String类型的数组
            String sql = "delete from contact where cid = ?";
            //创建一个二维数组,这个数组的长度为cids中的数据数
            Object[][] objects = new Object[cids.length][];
            //通过循环来对二维数组进行赋值
            for (int i = 0; i < objects.length; i++) {
                objects[i] = new Object[]{cids[i]};
            }
            try {
                //执行sql语句
                JdbcUtil.getQueryRunner().batch(sql,objects);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public Contact selectPhone(String phone) {
            String sql = "select * from contact where phone = ?";
            try {
                Contact query = JdbcUtil.getQueryRunner().query(sql, new BeanHandler<Contact>(Contact.class), phone);
                return query;
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throw new RuntimeException("查找异常");
        }
    
    
    }
    

    exception

    package com.javacoffee.exception;
    
    public class MyException extends Exception {
        public MyException(String messege){
            super(messege);
        }
    }
    

    service

    package com.javacoffee.service;
    
    import com.javacoffee.exception.MyException;
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.util.PageBean;
    
    import java.util.List;
    
    public interface ContactService {
        //service层我并没写什么逻辑行为,因为比较简单,就起到了个传值的作用
        public void addContact(Contact contact) throws MyException;//添加联系人
        public void updateContact(Contact contact);//修改联系人
        public void deleteContact(Integer cid);//删除联系人
        public List<Contact> findAll();  //查询所有联系人
        public Contact findById(Integer cid);//根据编号查询联系人
        public  PageBean findByPage(PageBean pageBean);//分页
        public void deleteAll(String[] cids);//删除所选人
    
        Boolean selectPhone(String phone);
    
    }
    
    package com.javacoffee.service;
    
    import com.javacoffee.pojo.Client;
    
    public interface ClientService {
        //获取对象
        Client login(String username, String password);
    }
    

    service实现类

    package com.javacoffee.service.impl;
    
    import com.javacoffee.dao.ClientDao;
    import com.javacoffee.dao.impl.ClientDaoImpl;
    import com.javacoffee.pojo.Client;
    import com.javacoffee.service.ClientService;
    
    public class ClientServiceImpl implements ClientService {
        @Override
        public Client login(String username, String password) {
            ClientDao clientDao = new ClientDaoImpl();
            return clientDao.login(username,password);
        }
    }
    
    package com.javacoffee.service.impl;
    
    import com.javacoffee.dao.ContactDao;
    import com.javacoffee.dao.impl.ContactDaoImpl;
    import com.javacoffee.exception.MyException;
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.service.ContactService;
    import com.javacoffee.util.PageBean;
    
    import java.util.List;
    
    public class ContactServiceImpl implements ContactService {
        //首先创建 多态父类引用指向子类对象 new出来contactDao对象
        private ContactDao contactDao = new ContactDaoImpl();
        //增加联系人的方法
        @Override
        public void addContact(Contact contact) throws MyException {
            Boolean aBoolean = selectPhone(contact.getPhone());
            if (aBoolean){
                contactDao.addContact(contact);
            }else {
                throw new MyException("手机号重复,不能使用!");
            }
    
        }
        //修改联系人的方法
        @Override
        public void updateContact(Contact contact) {
            contactDao.updateContact(contact);
        }
        //删除联系人的方法
        @Override
        public void deleteContact(Integer cid) {
            contactDao.deleteContact(cid);
        }
        //查找全部的方法
        @Override
        public List<Contact> findAll() {
            return contactDao.findAll();
        }
        //通过id查找的方法
        @Override
        public Contact findById(Integer cid) {
            return contactDao.findById(cid);
        }
        //分页
        @Override
        public PageBean findByPage(PageBean pageBean) {
            return contactDao.findByPage(pageBean);
        }
    
        @Override
        //删除所选全部
        public void deleteAll(String[] cids) {
             contactDao.deleteAll(cids);
        }
    
        @Override
        public Boolean selectPhone(String phone) {
            Contact contact = contactDao.selectPhone(phone);
            if (contact == null){
                return true;
            }else {
                return false;
            }
        }
    
    
    }
    

    filter过滤器

    package com.javacoffee.filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebFilter("/*")
    public class ContactFilter implements Filter {
        public void destroy() {
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            //字符集过滤器 过滤所有 将字符集设置成utf-8
           HttpServletRequest request = (HttpServletRequest)req;
           HttpServletResponse response = (HttpServletResponse)resp;
           request.setCharacterEncoding("utf-8");
           response.setContentType("text/html;charset=utf-8");
           chain.doFilter(request,response);
        }
    
        public void init(FilterConfig config) throws ServletException {
    
        }
    
    }
    
    package com.javacoffee.filter;
    
    import com.javacoffee.pojo.Client;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    @WebFilter("/*")
    public class LoginFilter implements Filter {
        public void destroy() {
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            //登陆的过滤器 因为要确保先登录 所以将网址不是登录的重定向到登录界面
            HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse)resp;
            //获取后缀
            String requestURI = request.getRequestURI();
            requestURI = requestURI.substring(requestURI.lastIndexOf("/"));
            //判断如果输入的网址后缀是这两个 则放行
             if ("/loginServlet".equals(requestURI)|| "/login.jsp".equals(requestURI)){
                 chain.doFilter(request,response);
             }else {
                 //如果不是的话 因为我们在登录的时候创建了session 如果session为空
                 //那么一定是没有登录的 所以不放行重定向到登陆界面
                 HttpSession session = request.getSession(false);
                 if (session == null){
                     response.sendRedirect(request.getContextPath()+"/loginServlet");
                 }else {
                     //如果存在session 对象 不过有可能session对象里是在别的地方创建好的
                     //所以我们要判断session里是否存储了我们登陆时存进去的client对象
                     //如果没有的话那还是没登陆 就重定向到登陆界面
                     Client client = (Client)session.getAttribute("client");
                     if (client == null){
                         response.sendRedirect(request.getContextPath()+"/loginServlet");
                     }else {
                         //反之 就是登录过的 就可以放行
                         chain.doFilter(request,response);
                     }
                 }
             }
    
        }
    
        public void init(FilterConfig config) throws ServletException {
    
        }
    
    }
    

    util工具类

    package com.javacoffee.util;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    import org.apache.commons.dbutils.QueryRunner;
    
    import javax.sql.DataSource;
    import java.io.InputStream;
    import java.util.Properties;
    
    //使用DBUtils的工具类
    public class JdbcUtil {
    
        //声明DataSource对象
        private static DataSource dataSource;
    
        //静态代码块
        static {
    
            try {
                //读取db.properties文件
                InputStream resourceAsStream = JdbcUtil.class.getResourceAsStream("/druid.properties");
                //创建Properties对象
                Properties properties = new Properties();
                //加载流对象
                properties.load(resourceAsStream);
                //创建数据源对象
                dataSource = DruidDataSourceFactory.createDataSource(properties);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    
        //获取DButils中核心类对象QueryRunner对象
        public static QueryRunner getQueryRunner(){
            return new QueryRunner(dataSource);//此时已经连接上数据库了
        }
    
    }
    
    package com.javacoffee.util;
    
    public class PageBean {
        //这是分页的工具类,一共需要获得五个属性
        private Integer pageNum;//当前页码号 通过前端获取
        private Integer pageSize;//一页的记录数 自己设置的
        private Object pageData;//一页的数据 可以看到返回值是对象
        private Integer totalCount;//总页数 需要二次计算
        private Integer totalData;//数据的总记录数 用来计算总页数用的
    
    
        public Integer getPageNum() {
            return pageNum;
        }
    
        public void setPageNum(Integer pageNum) {
            this.pageNum = pageNum;
        }
    
        public Integer getPageSize() {
            return pageSize;
        }
    
        public void setPageSize(Integer pageSize) {
            this.pageSize = pageSize;
        }
    
        public Object getPageData() {
            return pageData;
        }
    
        public void setPageData(Object pageData) {
            this.pageData = pageData;
        }
    
        public Integer getTotalCount() {
            return totalCount;
        }
    
        public void setTotalCount(Integer totalCount) {
            this.totalCount = totalCount;
        }
    
        public Integer getTotalData() {
            return totalData;
        }
    
        public void setTotalData(Integer totalData) {
            this.totalData = totalData;
        }
    
        @Override
        public String toString() {
            return "PageBean{" +
                    "pageNum=" + pageNum +
                    ", pageSize=" + pageSize +
                    ", pageData=" + pageData +
                    ", totalCount=" + totalCount +
                    ", totalData=" + totalData +
                    '}';
        }
    }
    

    druid.properties数据库连接池配置文件

    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/contact_sys?useSSL=false
    #我是使用的mysql 所以端口号为3306 数据库账户密码一定要改成自己的哈
    username=root
    password=1234
    
    initialSize=5
    maxActive=20
    maxWait=2000

    web层

    package com.javacoffee.web;
    
    import com.javacoffee.exception.MyException;
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ContactServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.MultipartConfig;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.Part;
    import java.io.File;
    import java.io.IOException;
    import java.util.UUID;
    //注意这两个注解千万不能省略
    @WebServlet("/addContactServlet")//这个是servlet的注解,可以访问的到
    @MultipartConfig//这个是代表上传文件的注解
    public class AddContactServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //这是增加联系人的servlet 首先设置字符集
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            //新建一个contact对象 用来存储数据库中获取的数据
            Contact contact = new Contact();
            //通过前端所对应的键名来获取相应的值
            String name = request.getParameter("name");
            String gender = request.getParameter("gender");
            String age = request.getParameter("age");
            String phone = request.getParameter("phone");
            String email = request.getParameter("email");
            //这里是上传文件 获取上传的对象
            Part qq = request.getPart("qq");
            //获取所上传文件的名字
            String qqName = qq.getSubmittedFileName();
            //为了避免上传的文件后,文件重复 每次上传文件都会通过UUID 工具类获取一个随机的字符串作为前缀名
            String replace = UUID.randomUUID().toString().replace("-", "");
           //我是把文件上传到另一个tomcat服务器里 所以这里把他的路径给出来了
            String uploadPath = "D:\\apache-tomcat-8.5.31\\webapps\\imgs";
           //通过路径创建一个新的文件对象
            File file = new File(uploadPath);
            //如果没有这个文件的话,就创建
            if (!file.exists()){
                file.mkdirs();
            }
            //最后组成文件的名字
            String uploadFileName = replace+qqName;
            //然后给他上传一下,参数为(路径+文件名) 注意这两个之间要加斜杠
            qq.write(uploadPath+"/"+uploadFileName);
            //接着赋值给对象
            contact.setName(name);
            contact.setAge(Integer.parseInt(age));
            contact.setEmail(email);
            contact.setGender(gender);
            contact.setPhone(phone);
            contact.setQq(uploadFileName);
            //接着调用addContact方法
            ContactService contactService = new ContactServiceImpl();
            try {
                contactService.addContact(contact);
            } catch (MyException e) {
                request.setAttribute("msg",e.getMessage());
                request.getRequestDispatcher("addContact.jsp").forward(request,response);
            }
    
            //因为不需要传值 重定向到首页面
            response.sendRedirect(request.getContextPath()+"/pageServlet");
        }
    }
    
    package com.javacoffee.web;
    
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ContactServiceImpl;
    
    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.Arrays;
    
    @WebServlet("/contactDeleteAllServlet")
    public class ContactDeleteAllServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
    
            String[] cids = request.getParameterValues("cids");
            if (cids != null) {
                ContactService contactService = new ContactServiceImpl();
                contactService.deleteAll(cids);
                response.sendRedirect(request.getContextPath()+"/pageServlet");
            }else {
                response.sendRedirect(request.getContextPath() + "/pageServlet");
            }
        }
    }
    
    package com.javacoffee.web;
    
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ContactServiceImpl;
    import com.javacoffee.util.PageBean;
    
    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;
    
    @WebServlet("/contactDeleteServlet")
    public class ContactDeleteServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
    
            ContactService contactService = new ContactServiceImpl();
            String cid = request.getParameter("cid");
            contactService.deleteContact(Integer.parseInt(cid));
    
            response.sendRedirect(request.getContextPath()+"/pageServlet");
        }
    }
    
    package com.javacoffee.web;
    
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ContactServiceImpl;
    
    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("/contactFindAllServlet")
    public class ContactFindAllServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            ContactService contactService = new ContactServiceImpl();
            List<Contact> contactList = contactService.findAll();
            request.setAttribute("contactList",contactList);
            request.getRequestDispatcher("findAll.jsp").forward(request,response);
        }
    }
    
    package com.javacoffee.web;
    
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ContactServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/findByIdServlet")
    public class FindByIdServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            ContactService contactService = new ContactServiceImpl();
            String cid = request.getParameter("cid");
            Contact contact = contactService.findById(Integer.parseInt(cid));
            request.setAttribute("contact",contact);
            request.getRequestDispatcher("update.jsp").forward(request,response);
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req, resp);
        }
    }
    
    package com.javacoffee.web;
    
    import com.javacoffee.pojo.Client;
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.service.ClientService;
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ClientServiceImpl;
    import com.javacoffee.service.impl.ContactServiceImpl;
    
    import javax.servlet.RequestDispatcher;
    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;
    
    @WebServlet("/loginServlet")
    public class LoginServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ClientService clientService = new ClientServiceImpl();
            //获取前端输入框的数据
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            //调用login方法 并返回client对象
            Client client = clientService.login(username,password);
            //如果client不为空的话也就是有这个账号密码  就 将client存入session 转发到主界面 也就是登录成功跳转
            if (client != null){
                HttpSession session = request.getSession();
                session.setAttribute("client",client);
                request.getRequestDispatcher("pageServlet").forward(request,response);
            }else {
                //如果为空就代表没有这个代码 就重定向到登陆界面
                response.sendRedirect(request.getContextPath()+"/login.jsp");
            }
        }
    }
    
    package com.javacoffee.web;
    
    import com.javacoffee.pojo.Client;
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ContactServiceImpl;
    import com.javacoffee.util.PageBean;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    import java.io.IOException;
    
    @WebServlet("/pageServlet")
    public class PageServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
    
            String pageNum = request.getParameter("pageNum");
            if (pageNum==null){
                pageNum="1";
            }
            Integer pageSize = 4;
            PageBean pageBean1 = new PageBean();
            pageBean1.setPageNum(Integer.parseInt(pageNum));
            pageBean1.setPageSize(pageSize);
            ContactService contactService = new ContactServiceImpl();
            PageBean pageBean = contactService.findByPage(pageBean1);
            request.setAttribute("pageBean",pageBean);
            HttpSession session = request.getSession(false);
            Client client = (Client)session.getAttribute("client");
            request.setAttribute("client",client);
            request.getRequestDispatcher("findAll.jsp").forward(request,response);
        }
    }
    
    package com.javacoffee.web;
    
    
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ContactServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/selectPhoneServlet")
    public class SelectPhoneServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
    
            String phone = request.getParameter("phone");
            ContactService contactService = new ContactServiceImpl();
            Boolean statement = contactService.selectPhone(phone);
            if (statement){
                response.getWriter().write("noExist");
            }else {
                response.getWriter().write("exist");
            }
        }
    }
    
    package com.javacoffee.web;
    
    import com.javacoffee.pojo.Contact;
    import com.javacoffee.service.ContactService;
    import com.javacoffee.service.impl.ContactServiceImpl;
    import com.javacoffee.util.PageBean;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.MultipartConfig;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    import java.io.File;
    import java.io.IOException;
    import java.util.UUID;
    
    @WebServlet("/updateServlet")
    @MultipartConfig
    public class UpdateServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            String cid = request.getParameter("cid");
            String name = request.getParameter("name");
            String gender = request.getParameter("gender");
            String age = request.getParameter("age");
            String phone = request.getParameter("phone");
            String email = request.getParameter("email");
            Part qq = request.getPart("qq");
    
            String updateFilePath = "D:\\apache-tomcat-8.5.31\\webapps\\imgs";
            File file = new File(updateFilePath);
            if (file.exists()) {
                file.mkdirs();
            }
            String submittedFileName = qq.getSubmittedFileName();
    
            String updateFileName = UUID.randomUUID().toString().replace("-", "") + submittedFileName;
            qq.write(updateFilePath + "\\" + updateFileName);
    
            ContactService contactService = new ContactServiceImpl();
            Contact contact = new Contact();
            contact.setCid(Integer.parseInt(cid));
            contact.setName(name);
            contact.setAge(Integer.parseInt(age));
            contact.setEmail(email);
            contact.setGender(gender);
            contact.setPhone(phone);
            contact.setQq(updateFileName);
            contactService.updateContact(contact);
            response.sendRedirect(request.getContextPath() + "/pageServlet");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req, resp);
        }
    }
    
    

    前端代码

    <%--
      Created by IntelliJ IDEA.
      User: 86156
      Date: 2021/9/30
      Time: 15:10
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录界面</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    
    </head>
    <body style="background-color:burlywood">
    <center><h1>用户登陆页面</h1></center>
    <div style="background-color: beige;width: 500px;height: 300px;position: absolute;top: 100px;left:520px;border-radius: 10px">
    <form class="form-horizontal" action="loginServlet" method="post">
        <div style="position: absolute;top: 50px;left: 100px">
        <div class="form-group">
            <label for="inputEmail3" class="col-sm-2 control-label">UserName:</label>
            <div class="col-sm-10" style="position: absolute;left: 100px;width: 200px">
                <input type="text" name="username" class="form-control" id="inputEmail3" placeholder="Email" >
            </div>
        </div>
        <div class="form-group">
            <label for="inputPassword3" class="col-sm-2 control-label">PassWord:</label>
            <div class="col-sm-10" style="position: absolute;left: 100px;width: 200px">
                <input type="password" name="password" class="form-control" id="inputPassword3" placeholder="Password" >
            </div>
        </div>
            <br>
        <div class="form-group" style="position: absolute;left: 170px">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" class="btn btn-default" style="width: 90px">登录</button>
            </div>
        </div>
        </div>
    </form>
    </div>
    </body>
    </html>
    
    <%--
      Created by IntelliJ IDEA.
      User: 86156
      Date: 2021/9/28
      Time: 11:14
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>Title</title>
        <style>
           table{
               text-align: center;
               vertical-align: middle;
           }
    
        </style>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    </head>
    <body bgcolor="#6495ed">
    <font color="#deb887" size="6" style="background-color: beige">欢迎:${client.username}&nbsp;登录!</font>
    <form action="contactDeleteAllServlet" method="post" >
    <table class="table table-hover table-bordered" style="width: 80%" align="center">
        <tr class="success" style="font-weight: bold">
            <td><input type="checkbox"  id="cids" onclick="selectAll()">全选</td>
            <td>编号</td>
            <td>姓名</td>
            <td>性别</td>
            <td>年龄</td>
            <td>电话</td>
            <td>邮箱</td>
            <td>QQ</td>
            <td>操作</td>
        </tr>
    <%--    <c:forEach items="${contactList}" var="contactList" varStatus="c">--%>
        <c:forEach items="${pageBean.pageData}" var="contactList" varStatus="c">
        <tr class="active" style="vertical-align: center">
            <td align="center"><input type="checkbox" class="checkbox" name="cids" value="${contactList.cid}"></td>
            <td>${c.count}</td>
            <td>${contactList.name}</td>
            <td>${contactList.gender}</td>
            <td>${contactList.age}</td>
            <td>${contactList.phone}</td>
            <td>${contactList.email}</td>
    <%--        //图片显示的路径 我的是自己又开了一个tomcat端口号为9999--%>
            <td><img src="http://10.8.159.4:9999/imgs/${contactList.qq}" width="60" height="60"></td>
            <td><a href="${pageContext.request.contextPath}/findByIdServlet?cid=${contactList.cid}">修改</a>&nbsp;
    
                <a href="${pageContext.request.contextPath}/contactDeleteServlet?cid=${contactList.cid}">删除</a>
    
                <c:if test="${pageBean.pageData==null}">
                    ${pageBean.pageNum=pageBean.pageNum-1}
                </c:if>
            </td>
        </tr>
        </c:forEach>
        <tr class="warning" >
            <td colspan="9" align="center"><a href="addContact.jsp">[添加联系人]</a></td>
        </tr>
    
        <tr class="warning" >
            <td colspan="9" align="center"><input type="submit" value="全部删除"></td>
        </tr>
    
    
        <tr class="warning" >
            <td colspan="9" align="center">
                &nbsp;&nbsp;第${pageBean.pageNum}页&nbsp;&nbsp;${pageBean.pageNum}/${pageBean.totalCount}页&nbsp;&nbsp;
                <a href="${pageContext.request.contextPath}/pageServlet?pageNum=1">首页</a>
    
                <c:if test="${pageBean.pageNum == 1}">
                    <a>上一页</a>
                </c:if>
    
                <c:if test="${pageBean.pageNum > 1}">
                    <a href="${pageContext.request.contextPath}/pageServlet?pageNum=${pageBean.pageNum-1}">上一页</a>
                </c:if>
    
                <c:if test="${pageBean.pageNum == pageBean.totalCount}">
                    <a>下一页</a>
                </c:if>
    
                <c:if test="${pageBean.pageNum < pageBean.totalCount}">
                    <a href="${pageContext.request.contextPath}/pageServlet?pageNum=${pageBean.pageNum+1}">下一页</a>
                </c:if>
    
                <a href="${pageContext.request.contextPath}/pageServlet?pageNum=${pageBean.totalCount}">尾页</a>
            </td>
        </tr>
    </table>
    </form>
    </body>
    <script type="application/javascript">
        function selectAll() {
            var cids = document.getElementById("cids");
            var elementsByClassName = document.getElementsByClassName("checkbox");
            for (var i = 0; i < elementsByClassName.length; i++) {
                elementsByClassName[i].checked = cids.checked;
            }
        }
    </script>
    </html>
    <%--
      Created by IntelliJ IDEA.
      User: 86156
      Date: 2021/9/28
      Time: 15:08
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>添加联系人</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>
    
    </head>
    
    <body>
    <center><h3>添加联系人</h3></center>
    
    <form action="addContactServlet" method="post" enctype="multipart/form-data">
        <table align="center" border="1" width="300px" class="table table-bordered table-hover">
            <tr class="warning"><td colspan="2"><font color="red" size="5">${msg}</font></td></tr>
            <tr class="success">
                <th>姓名</th>
                <td><input type="text" name="name"/></td>
            </tr>
            <tr class="warning">
                <th >性别</th>
                <td>
                    <input type="radio" name="gender" value="男" checked="checked" />男
                    <input type="radio" name="gender" value="女"/>女
                </td>
            </tr>
            <tr class="active">
                <th>年龄</th>
                <td><input type="text" name="age"/></td>
            </tr>
            <tr class="danger">
                <th>电话</th>
                <td><input type="text" name="phone" id="phone" onfocus="waring()" onblur="findPhone()"/>
                <span id="phoneSpan"></span></td>
            </tr>
            <tr class="info">
                <th>邮箱</th>
                <td><input type="text" name="email"/></td>
            </tr>
            <tr>
                <th>QQ</th>
                <td><input type="file" name="qq"/></td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <input type="submit" value="保存"/>&nbsp;
                    <input type="reset" value="重置"/></td>
            </tr>
        </table>
    </form>
    </body>
    <script type="application/javascript">
        function waring() {
            var elementById = document.getElementById("phoneSpan");
            elementById.innerHTML="手机号为11位".fontcolor("red");
        }
        function findPhone() {
            var elementById = document.getElementById("phoneSpan");
            var selectPhone = document.getElementById("phone").value;
    
            $.get("selectPhoneServlet",{phone:selectPhone},
            function (backdata) {
                if (backdata=="exist"){
                    elementById.innerHTML="手机号已存在".fontcolor("red");
                }else if (backdata=="noExist") {
                    elementById.innerHTML="手机号可以使用".fontcolor("green");
                }
            },"text")
        }
    </script>
    </html>
    
    <%--
      Created by IntelliJ IDEA.
      User: 86156
      Date: 2021/9/28
      Time: 19:12
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>修改联系人</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    </head>
    
    <body>
    <center><h3>修改联系人</h3></center>
    <form action="updateServlet" method="post" enctype="multipart/form-data">
        <input type="hidden" name="cid" value="${contact.cid}">
        <table align="center" border="1" width="300px" class="table table-hover table-bordered">
            <tr class="active">
                <th>姓名</th>
                <td><input type="text" name="name" value="${contact.name}"/></td>
            </tr>
            <tr class="success">
                <th>性别</th>
                <c:if test="${contact.gender=='男'}">
                <td>
                    <input type="radio" name="gender" value="男" checked="checked"/>男
                    <input type="radio" name="gender" value="女"/>女
                </td>
                </c:if>
                <c:if test="${contact.gender=='女'}">
                    <td>
                        <input type="radio" name="gender" value="男"/>男
                        <input type="radio" name="gender" value="女" checked="checked"/>女
                    </td>
                </c:if>
            </tr>
            <tr class="warning">
                <th>年龄</th>
                <td><input type="text" name="age" value="${contact.age}"/></td>
            </tr>
            <tr class="info">
                <th>电话</th>
                <td><input type="text" name="phone" value="${contact.phone}"/></td>
            </tr>
            <tr class="success">
                <th>邮箱</th>
                <td><input type="text" name="email" value="${contact.email}"/></td>
            </tr>
            <tr class="danger">
                <th>QQ</th>
                <td><img src="http://localhost:9999/imgs/${contact.qq}" width="60" height="60"><input type="file" name="qq"/></td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <input type="submit" value="保存"/>&nbsp;
                    <input type="reset" value="重置"/></td>
            </tr>
        </table>
    </form>
    </body>
    </html>
    
    

    5.显示效果

      5.1登录界面

    5.2主界面

     5.3添加界面

     5.4修改界面

    展开全文
  • java项目——CRM客户管理系统(SpringBoot+MyBatis)

    万次阅读 多人点赞 2021-06-01 20:23:31
    用户管理模块<1>.表结构分析<2>.用户登录<3>全局统一的异常处理及非法请求的拦截(1)统一的异常处理(2)非法请求拦截<3>记住我功能2.营销管理模块(CRUD操作,见源码)<1>功能开发及

    CRM客户管理系统

    本人负责后端的开发(Java)

    一.对CRM的项目的简单描述

    1.什么是CRM

    CRM系统即客户关系管理系统,是指企业用CRM技术来管理与客户之间的关系。他的目标是缩减销售周期和销售成本,增加收入,寻找扩展业务所需的新的市场和渠道以及提高客户的价值,满意度,营利性和忠实度。CRM项目的实施可以分为3步,即应用业务集成。业务诗句分析和决策执行。

    2.CRM开发环境和技术

    <1> 项目业务介绍

    客户关系管理是指企业为提高核心竞争力,利用相应的技术信息以及互联网技术协调企业与顾客间在消费,营销和服务上的交互,从而提升其管理方式,向客户提供创新式的个性化的客户交互和服务的过程,其最终目标是吸引新客户,保留老客户以及将已有客户转为忠实客户,增加市场

    <2>开发环境

    项目名称:CRM客户管理系统
    系统作用:公司客户关系管理,潜在客户开发及订单合同管理
    开发环境:IDEA Windows10 jdk1.8 Maven Mysql8
    需要的工具:postman fiddler抓包工具或浏览器开发者工具

    <3>开发技术

    前端:LayUI freeMaker
    后端:Spring SpringMVC SpringBoot MyBatis Maven MySQL8 Linux CentOS ECharts(折线和饼状图)权限管理 定时任务调度(quartz)CentOS Lombok

    二.项目准备及模块分析

    1.模块分析总览

    1.基础模块:包含系统基本的用户登录,退出,记住我,密码修改等基本操作。

    2.营销管理:
    营销机会管理:企业客户的质询需求所建立的信息录入功能
    客户开发计划:开发计划是根据营销机会而来,对于企业质询的客户,会有相应的销售人员对于该客户
    进行具体的沟通交流,此时对于整个 Crm 系统而言,通过营销开发计划来进行相应的信息管理,提高
    客户的购买企业产品的可能性。

    3.客户管理:
    客户信息管理 :Crm 系统中完整记录客户信息来源的数据、企业与客户交往、客户订单查询等信息录
    入功能,方便企业与客户进行相应的信息交流与后续合作。
    客户流失管理 :Crm 通过一定规则机制所定义的流失客户(无效客户),通过该规则可以有效管理客
    户信息资源,提高营销开发的效率。

    4.服务管理:服务管理是针对客户而开发的功能,针对客户要求,Crm 提供客户相应的信息质询,反馈与投诉功能,
    提高企业对于客户的服务质量。

    5.数据报表:
    Crm 提供的数据报表功能能够帮助企业了解客户整体分布,了解客户开发结果整体信息,从而帮助企业
    整体调整客户开发计划,提高企业的在市场中的竞争力度。

    6.系统管理:系统管理包含常量字典维护工作,以及权限管理模块,Crm 权限管理是基于角色的一种权限控制,基于
    RBAC 实现基于角色的权限控制,通过不同角色的用户登录该系统后展示系统不同的操作功能,从而达
    到对不同角色完成不同操作功能。

    在这里插入图片描述

    2.项目前期环境的搭建

    1.创建SpringBoot项目,导入依赖(见源代码)
    2.在src/main/resources 目录下新建 application.yml 配置文件

    ## 端口号  上下文路径
    server:
      port: 8080
      servlet:
        context-path: /crm
    
    ## 数据源配置
    spring:
      datasource:
        type: com.mchange.v2.c3p0.ComboPooledDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/crm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
        username: 
        password: 
    
    
      ## freemarker
      freemarker:
        suffix: .ftl
        content-type: text/html
        charset: UTF-8
        template-loader-path: classpath:/views/
    
    
      ## 启用热部署
      devtools:
        restart:
          enabled: true
          additional-paths: src/main/java
    
    ## mybatis 配置
    mybatis:
      mapper-locations: classpath:/mappers/*.xml
      type-aliases-package: org.example.crm.vo;org.example.crm.query;org.example.crm.dto
      configuration:
        map-underscore-to-camel-case: true
    
    ## pageHelper 分页
    pagehelper:
      helper-dialect: mysql
    
    ## 设置 dao 日志打印级别
    logging:
      level:
        org:
          example:
            crm:
              dao: debug
    
    

    3.新建 org.example.crm.controller 包,添加系统登录,主页面转发代码 。
    4.添加静态资源:在 src/main/resources 目录下新建 public 目录,存放系统相关静态资源文件,拷贝静态文件内容到
    public 目录。
    5.添加视图模板:在 src/main/resources 目录下新建 views 目录,添加 index.ftl、main.ftl 等文件。 (具体视图文件详见
    相关目录)
    6.添加启动类:在 org.example.crm 包下新建 Starter.java ,添加启动项目相关代码如下:

    package org.example.crm;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @SpringBootApplication
    @MapperScan("org.example.crm.dao")
    //启用定时任务
    @EnableScheduling
    public class Starter {
        public static void main(String[] args) {
            SpringApplication.run(Starter.class);
        }
    }
    

    7.添加Base包:主要用户对Controller,Service Dao层的统一控制,BaseQuery用于控制按条件搜索的对象,ResultInfo是后端返回的对象的统一封装

    项目搭建结构:
    在这里插入图片描述
    8.准备MyBatis代码统一生成工具(generatorConfig.xml)
    这里注意:工具有点缺陷,每次需要改工具作用的表名

    使用mybatis-generator生成Mybatis代码。能够生成 vo 类、能生成 mapper 映射文件(其中包括基本
    的增删改查功能)、能生成 mapper 接口。
    命令: mybatis-generator:generate -e

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
            PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
    <generatorConfiguration>
    
        <!--
            数据库驱动
                在左侧project边栏的External Libraries中找到mysql的驱动,右键选择copy path
        -->
        <classPathEntry  location="D:\Repository\Maven\mysql\mysql-connector-java\5.1.49\mysql-connector-java-5.1.49.jar"/>
        <context id="DB2Tables" targetRuntime="MyBatis3">
    
            <commentGenerator>
                <!-- 是否去除日期那行注释 -->
                <property name="suppressDate" value="false"/>
                <!-- 是否去除自动生成的注释 true:是 : false:-->
                <property name="suppressAllComments" value="false"/>
            </commentGenerator>
    
            <!-- 数据库链接地址账号密码 -->
            <jdbcConnection
                    driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/crm?serverTimezone=GMT%2B8"
                    userId="root"
                    password="sn20000904">
            </jdbcConnection>
    
            <!--
                 java类型处理器
                    用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl;
                    注意一点,默认会先尝试使用IntegerLongShort等来对应DECIMAL和NUMERIC数据类型;
                    true:使用 BigDecimal对应DECIMAL和NUMERIC数据类型
                    false:默认,把JDBC DECIMAL和NUMERIC类型解析为Integer
            -->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false"/>
            </javaTypeResolver>
    
    
    
            <!-- 生成Model类存放位置 -->
            <javaModelGenerator targetPackage="org.example.crm.model" targetProject="src/main/java">
                <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
                <property name="enableSubPackages" value="true"/>
                <!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
                <property name="trimStrings" value="true"/>
            </javaModelGenerator>
    
    
            <!--生成映射文件存放位置-->
            <sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources">
                <property name="enableSubPackages" value="true"/>
            </sqlMapGenerator>
    
    
            <!--生成Dao类存放位置-->
            <javaClientGenerator type="XMLMAPPER" targetPackage="org.example.crm.dao" targetProject="src/main/java">
                <property name="enableSubPackages" value="true"/>
            </javaClientGenerator>
    
    
    
           <!--改表名 -->
            <table tableName="t_customer_serve" domainObjectName="CustomerServe"
                   enableCountByExample="false" enableUpdateByExample="false"
                   enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    
        </context>
    </generatorConfiguration>
    

    9.导入工具类,主要有:根据Cookie获取作用域,登录成功返回userIdStr加密,Md5协议加密,判断电话号码的格式,userID加解密等
    在这里插入图片描述

    三.项目的正式开发

    主要讲解核心模块的核心代码

    1.用户管理模块

    <1>.表结构分析

    在这里插入图片描述

    <2>.用户登录

    定义UserModel类,用于用户登录成功返回的用户信息,用来设置前端的Cookie

    @Getter
    @Setter
    public class UserVo {
        //private Integer userId;
        //存放在前端cookie中加密后的Id
        private String userIdStr;
        private String userName;
        private String trueName;
    }
    

    设置cookie

    layer.msg("登录成功!", function () {
                            // 判断用户是否选择记住密码(判断复选框是否被选中,如果选中,则设置cookie对象7天生效)
                            if ($("#rememberMe").prop("checked")) {
                                // 选中,则设置cookie对象7天生效
                                // 将用户信息设置到cookie中
                                $.cookie("userIdStr", result.result.userIdStr, {expires: 7});
                                $.cookie("userName", result.result.userName, {expires: 7});
                                $.cookie("trueName", result.result.trueName, {expires: 7});
                            } else {
                                // 将用户信息设置到cookie中
                                $.cookie("userIdStr", result.result.userIdStr);
                                $.cookie("userName", result.result.userName);
                                $.cookie("trueName", result.result.trueName);
                            }
    

    退出登录时,删除前端Cookie即可

    <3>全局统一的异常处理及非法请求的拦截

    (1)统一的异常处理

    全局异常实现思路:
    控制层的方法返回的内容两种情况

    1. 视图:视图异常
    2. Json:方法执行错误 返回错误json信息

    全局异常拦截器的实现,简化了try-catch代码
    实现 HandlerExceptionResolver 接口 ,处理应用程序异常信息

    (2)非法请求拦截

    对于后端菜单资源,这里要求用户必须进行登录来保护 web 资源的安全性,此时引入非法请求拦截功
    能。
    实现思路:
    判断用户是否是登录状态
    获取Cookie对象,解析用户ID的值
    如果用户ID不为空,且在数据库中存在对应的用户记录,表示请求合法
    否则,请求不合法,进行拦截,重定向到登录页面

    定义拦截器:在新建 interceptors 包,创建 NoLoginInterceptor 类,并继承 HandlerInterceptorAdapter 适配器,
    实现拦截器功能。

    /**
     * 非法访问拦截
     * 继承HandlerInterceptorAdapter适配器
     */
    
    public class NoLoginInterceptor extends HandlerInterceptorAdapter {
        @Autowired
        private UserMapper userMapper;
    
        /**
         * 拦截用户是否是登录状态
         * 在目标方法(资源)执行前执行的方法
         * 返回boolean
         * 如果为true,表示目标方法可用被执行
         * 如果为false,表示阻止目标方法执行
         *
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //获取cookie中的用户Id
            Integer userId = LoginUserUtil.releaseUserIdFromCookie(request);
            //判断用户Id是否为空,且数据库中是否存在改userId的记录
            if (userId == null || userMapper.selectByPrimaryKey(userId) == null) {
                //抛出未登录异常
                throw new NoLoginException();
            }
            return true;
        }
    }
    

    全局异常类配置:在全局异常处理类中引入未登录异常判断

    /**
     * 全局异常统一处理
     */
    @Component
    public class GlobalExceptionResolver implements HandlerExceptionResolver {
        /**
         * 异常处理方法
         * 方法的返回值:
         * 1. 返回视图
         * 2. 返回数据(JSON数据)
         * <p>
         * 如何判断方法的返回值?
         * 通过方法上是否声明@ResponseBody注解
         * 如果未声明,则表示返回视图
         * 如果声明了,则表示返回数据
         *
         * @param request  request请求对象
         * @param response response响应对象
         * @param handler  方法对象
         * @param ex       异常对象
         * @return org.springframework.web.servlet.ModelAndView
         */
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    
            /**
             * 非法请求拦截
             *  判断是否抛出未登录异常
             *      如果抛出该异常,则要求用户登录,重定向跳转到登录页面
             */
            if (ex instanceof NoLoginException) {
                // 重定向到登录页面
                ModelAndView mv = new ModelAndView("redirect:/index");
                return mv;
            }
    
    
            /**
             * 设置默认异常处理(返回视图)
             */
            ModelAndView modelAndView = new ModelAndView("error");
            // 设置异常信息
            modelAndView.addObject("code", 500);
            modelAndView.addObject("msg", "系统异常,请重试...");
    
    
            // 判断HandlerMethod
            if (handler instanceof HandlerMethod) {
                // 类型转换
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                // 获取方法上声明的@ResponseBody注解对象
                ResponseBody responseBody = handlerMethod.getMethod().getDeclaredAnnotation(ResponseBody.class);
    
                // 判断ResponseBody对象是否为空 (如果对象为空,则表示返回的事视图;如果不为空,则表示返回的事数据)
                if (responseBody == null) {
                    /**
                     * 方法返回视图
                     */
                    // 判断异常类型
                    if (ex instanceof ParamsException) {
                        ParamsException p = (ParamsException) ex;
                        // 设置异常信息
                        modelAndView.addObject("code", p.getCode());
                        modelAndView.addObject("msg", p.getMsg());
    
                    } else if (ex instanceof AuthException) { // 认证异常
                        AuthException a = (AuthException) ex;
                        // 设置异常信息
                        modelAndView.addObject("code", a.getCode());
                        modelAndView.addObject("msg", a.getMsg());
                    }
    
                    return modelAndView;
    
                } else {
                    /**
                     * 方法返回数据
                     */
                    // 设置默认的异常处理
                    ResultInfo resultInfo = new ResultInfo();
                    resultInfo.setCode(500);
                    resultInfo.setMsg("异常异常,请重试!");
    
                    // 判断异常类型是否是自定义异常
                    if (ex instanceof ParamsException) {
                        ParamsException p = (ParamsException) ex;
                        resultInfo.setCode(p.getCode());
                        resultInfo.setMsg(p.getMsg());
    
                    } else if (ex instanceof AuthException) { // 认证异常
                        AuthException a = (AuthException) ex;
                        resultInfo.setCode(a.getCode());
                        resultInfo.setMsg(a.getMsg());
                    }
    
                    // 设置响应类型及编码格式(响应JSON格式的数据)
                    response.setContentType("application/json;charset=UTF-8");
                    // 得到字符输出流
                    PrintWriter out = null;
                    try {
                        // 得到输出流
                        out = response.getWriter();
                        // 将需要返回的对象转换成JOSN格式的字符
                        String json = JSON.toJSONString(resultInfo);
                        // 输出数据
                        out.write(json);
    
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        // 如果对象不为空,则关闭
                        if (out != null) {
                            out.close();
                        }
                    }
    
                    return null;
    
                }
            }
            return modelAndView;
        }
    }
    

    拦截器生效配置:

    @Configuration//配置类
    public class MvcConfig extends WebMvcConfigurerAdapter {
        @Bean//将方法的返回值交给IOC
        public NoLoginInterceptor noLoginInterceptor() {
            return new NoLoginInterceptor();
        }
    
        /**
         * 添加拦截器
         *
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //需要实现了拦截器功能的实例对象 NoLoginInterceptor
            registry.addInterceptor(noLoginInterceptor())
                    //设置需要被拦截的资源
                    .addPathPatterns("/**")
                    // 设置不需要被拦截的资源
                    .excludePathPatterns("/css/**", "/images/**", "/js/**", "/lib/**")
                    .excludePathPatterns("/index", "/user/login");
        }
    }
    

    测试拦截效果:
    当 Cookie 中的用户ID不存在时,访问 main 页面,会自动跳转到登录页面

    <3>记住我功能

    记住我功能核心在于当用户上次登录时如果点击了记住我,下次在重新打开浏览器时可以不用选择登
    录,此时可以借助拦截器 + cookie 来实现,当用户在登录时,如果用户点击了记住我功能,默认设置
    cookie存储时间为7天即可。

    2.营销管理模块(CRUD操作,见源码)

    <1>功能开发及表结构分析

    功能开发:
    在这里插入图片描述
    表结构:
    在这里插入图片描述
    这里注意:时间格式化:

     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        @DateTimeFormat(pattern = "yyyy-MM-dd") // 如果传递的参数是Date类型,要求传入的时间字符串的格式
        private Date planDate;
    

    3.权限管理模块(CRUD操作见源码)

    基本概念:RBAC是基于角色的访问控制( Role-Based Access Control )在RBAC中,权限与角色相关联,用户
    通过扮演适当的角色从而得到这些角色的权限。这样管理都是层级相互依赖的,权限赋予给角色,角色
    又赋予用户,这样的权限设计很清楚,管理起来很方便。

    <1>.模块功能及表的结构设计

    功能模块:
    在这里插入图片描述

    表结构设计:
    从上面实体对应关系分析,权限表设计分为以下基本的五张表结构:用户表(t_user)、角色表(t_role)、
    t_user_role(用户角色表)、资源表(t_module)、权限表(t_permission)
    用户和角色间一对一关系,角色和权限间一对一关系,建立t_user_role和t_permission中间表
    表结构关系如下:

    在这里插入图片描述
    在这里插入图片描述

    <2>角色权限功能

    当完成角色权限添加功能后,下一步就是对角色操作的资源进行认证操作,这里对于认证包含两块:

    1. 菜单级别显示控制
    2. 后端方法访问控制

    查询出改用户所拥有的角色,然后根据角色查询出拥有的权限码,具体实现如下:

     @RequestMapping("main")
        public String main(HttpServletRequest request) {
            //通过获取cookie用户ID
            Integer userId = LoginUserUtil.releaseUserIdFromCookie(request);
            //查询用户对象,设置session作用域
            User user = userService.selectByPrimaryKey(userId);
            request.getSession().setAttribute("user", user);
    
            //通过当前登录用户ID,查询当前登录用户拥有的资源列表(查询对应的资源授权码)
            List<String> permissions = null;
            permissions = permissionService.queryUserHasRoleHasPermissionByUserId(userId);
            //将集合设置作用域中(Session作用域)
            request.getSession().setAttribute("permissions", permissions);
    
            return "main";
        }
    

    (1).菜单级别显示控制

    系统根据登录用户扮演的不同角色来对登录用户操作的菜单进行动态控制显示操作,这里显示的控制使
    用freemarker指令+内建函数实现
    例如:
    在这里插入图片描述
    会根据权限码,来显示菜单内容:
    在这里插入图片描述

    (2).后端方法级别访问控制(AOP+注解实现)

    实现了菜单级别显示控制,但最终客户端有可能会通过浏览器来输入资源地址从而越过ui界面来访问后
    端资源,所以接下来加入控制方法级别资源的访问控制操作,这里使用aop+自定义注解实现

    自定义注解类:表示资源所需的权限码

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    /**
     * 定义方法需要的对应资源的权限码
     */
    public @interface RequiredPermission {
        //权限码
        String code() default "";
    }
    
    

    方法级别使用注解:
    例如:
    在这里插入图片描述
    定义aop切面类 拦截指定注解标注的方法:

    @Component
    @Aspect
    public class PermissionProxy {
    
        @Resource
        private HttpSession session;
    
        /**
         * 切面会拦截指定包下的指定注解
         * 拦截com.xxxx.crm.annoation的RequiredPermission注解
         *
         * @param pjp
         * @return java.lang.Object
         */
        @Around(value = "@annotation(org.example.crm.annotation.RequiredPermission)")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            Object result = null;
            // 得到当前登录用户拥有的权限 (session作用域)
            List<String> permissions = (List<String>) session.getAttribute("permissions");
            // 判断用户是否拥有权限
            if (null == permissions || permissions.size() < 1) {
                // 抛出认证异常
                throw new AuthException();
            }
    
            // 得到对应的目标
            MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
            // 得到方法上的注解
            RequiredPermission requiredPermission = methodSignature.getMethod().getDeclaredAnnotation(RequiredPermission.class);
            // 判断注解上对应的状态码
            if (!(permissions.contains(requiredPermission.code()))) {
                // 如果权限中不包含当前方法上注解指定的权限码,则抛出异常
                throw new AuthException();
            }
    
            result = pjp.proceed();
            return result;
        }
    }
    

    4.客户管理模块(CRUD操作见源码)

    <1>.模块功能及表结构设计

    模块功能:
    在这里插入图片描述
    表结构设计:
    t_customer 客户表、t_customer_contact 客户交往记录表、t_customer_linkman 客户联系人表、t_customer_order 客户订单表、t_order_details 订单详情表
    在这里插入图片描述
    在这里插入图片描述

    <2>.定时器

    当实现了客户数据转移业务逻辑代码后,这里需要思考一个问题:客户数据量的问题随着时间的积累,流失的客户数据可能就比较大,如果数据的获取在用户查询时进行,此时后端对于数据的查询就会变得很慢,此时可以使用我们之前讲到的定时任务来处理,后台通过定时器来对流失客户数据定时进行转移处理,从而当前端用户查询时只需到客户流失表查询流失数据即可。

    增加定时器服务:

    /**
     * 定时任务的执行
     */
    @Component
    public class JobTask {
        @Autowired
        private CustomerService customerService;
    
        //cron表达式
        //每两秒执行一次
        //@Scheduled(cron = "0/2 * * * * ?")
    
        //从六月开始,每个月执行一次
        @Scheduled(cron = "* * * * 6/1 ? ")
        public void job() {
            //调用需要被执行的方法
            //开始执行定时任务
            System.out.println("开始执行定时器任务");
            customerService.updateCustomerState();
            System.out.println("定时器任务执行完成");
        }
    }
    

    Starter开启定时任务环境配置:

    @SpringBootApplication
    @MapperScan("org.example.crm.dao")
    //启用定时任务
    @EnableScheduling
    public class Starter {
        public static void main(String[] args) {
            SpringApplication.run(Starter.class);
        }
    }
    

    5.服务管理(CRUD操作见源码)

    <1>功能实现及表结构设计

    功能实现:
    在这里插入图片描述
    表结构设计:
    在这里插入图片描述

    <2>服务实现

    这里对于服务管理服务的创建,分配,处理与反馈后端代码实现放在同一个方法中进行处理,同时方便对于服务状态值统一处理,这里定义 CustomerServeStatus 枚举类来实现。

    /**
     * 客户服务状态枚举类
     */
    public enum CustomerServeStatus {
        // 创建
        CREATED("fw_001"),
        // 分配
        ASSIGNED("fw_002"),
        // 处理
        PROCED("fw_003"),
        // 反馈
        FEED_BACK("fw_004"),
        // 归档
        ARCHIVED("fw_005");
    
        private String state;
    
        CustomerServeStatus(String state) {
            this.state = state;
        }
    
        public String getState() {
            return state;
        }
    }
    
    

    6.统计报表管理(CRUD见源码)

    <1>.功能实现

    功能实现:
    在这里插入图片描述

    <2>.使用ECharts对数据进行分析

    ECharts官网:添加链接描述

    折线图数据返回实现:

     /**
         * 查询客户构成 (折线图)
         * @return
         */
        public Map<String, Object> countCustomerMake() {
            Map<String, Object> map = new HashMap<>();
            // 查询客户构成数据的列表
            List<Map<String, Object>> dataList = customerMapper.countCustomerMake();
            // 折线图X轴数据  数组
            List<String> data1 = new ArrayList<>();
            // 折线图Y轴数据  数组
            List<Integer> data2 = new ArrayList<>();
    
            // 判断数据列表 循环设置数据
            if (dataList != null && dataList.size() > 0) {
                for (int i = 0; i < dataList.size(); i++) {
                    data1.add(dataList.get(i).get("level").toString());
                    data2.add(Integer.parseInt(dataList.get(i).get("total").toString()));
                }
            }
            // 将X轴的数据集合与Y轴的数据集合,设置到map中
            map.put("data1", data1);
            map.put("data2", data2);
    
            return map;
        }
    

    在这里插入图片描述
    饼状图数据返回实现:

    
        public Map<String, Object> countCustomerMake02() {
            Map<String, Object> map = new HashMap<>();
            // 查询客户构成数据的列表
            List<Map<String, Object>> dataList = customerMapper.countCustomerMake();
            // 饼状图数据   数组(数组中是字符串)
            List<String> data1 = new ArrayList<>();
            // 饼状图的数据  数组(数组中是对象)
            List<Map<String, Object>> data2 = new ArrayList<>();
    
            // 判断数据列表 循环设置数据
            if (dataList != null && dataList.size() > 0) {
                // 遍历集合
                for (int i = 0; i < dataList.size(); i++) {
                    //饼状图数据, 数组(数组中是字符串
                    data1.add(dataList.get(i).get("level").toString());
                    //饼状图数据 数组(数组中是对象)
                    Map<String, Object> dataMap = new HashMap<>();
                    dataMap.put("name", dataList.get(i).get("level"));
                    dataMap.put("value", dataList.get(i).get("total"));
                    data2.add(dataMap);
                }
            }
    
            // 将X轴的数据集合与Y轴的数据集合,设置到map中
            map.put("data1", data1);
            map.put("data2", data2);
    
            return map;
        }
    

    在这里插入图片描述

    欢迎Star CRM客户管理系统

    展开全文
  • JAVA版通讯录管理系统课程设计源码

    热门讨论 2015-01-08 17:23:09
    源码实现了如下功能: 1.2 系统功能分析 ...支持一键收藏联系人,联系人加星标后更加方便于用户查找与管理。 【系统设计文档】、【系统需求分析文档】、【系统实验报告】、【答辩展示PPT】另见我的资源……
  • Java图形界面开发—学生信息管理系统 完整源码

    千次下载 热门讨论 2017-02-28 21:36:13
    学生信息管理系统,使用Java开发。 1、登录界面可以进行登录操作。有俩种权限选择。分别跳转到不同的界面。 2、使用了事件监听、Java操作SQLserver数据库等知识。 3、图形化界面中使用了JTable等组件,将查询结果...
  • JAVA学生宿舍管理系统

    万次阅读 多人点赞 2019-01-22 21:28:14
    system.java (系统管理界面) sql.java (数据库操作,包括连接、断开、增删改查等操作) 一、登陆界面及代码 主要代码: 登陆按钮事件 public void actionPerformed(ActionEvent e) { // TODO Auto-...
  • JAVA小项目-银行管理系统(图形界面&&文件读写+源文件)
  • 分为三类用户角色学生用户:修改个人信息、课程...管理用户:学生管理、教师管理、课程管理、选课管理、成绩管理、院系设置、奖惩信息管理管理员操作 用的java+MySQL数据库,cs架构。附带设计报告,建表合理规范。
  • java实现通讯录管理系统

    千次阅读 2021-02-27 10:12:07
    本文实例为大家分享了java实现通讯录管理系统的具体代码,供大家参考,具体内容如下完成项目的流程:1.根据需求,确定大体方向2.功能模块分析3.界面实现4.功能模块设计5.coding6.代码测试下面是源代码:import java....
  • Java 图书管理系统

    千次阅读 多人点赞 2022-04-14 14:20:08
    使用JavaSE的语法来写一个图书管理系统的小项目。
  • Java Web(九) 用户管理系统

    千次阅读 2021-03-08 16:12:12
    四、总结 这个小的用户管理,花了我一天的时间,完全自己独立写的,其实如果熟悉业务流程,根本花不了那么长的时间,估计只需要2个小时不到就可以写出来了,虽然只有增删改查几个功能,但是对于新手来说,通过这个...
  • Java酒店管理系统

    热门讨论 2008-09-09 11:03:49
    Jsp酒店管理系统/Java酒店管理系统 本系统是WEB模式的宾馆酒店管理系统(Jsp酒店管理系统/Java酒店管理系统) 运行环境:Tomact+JDK1.5 编程模式:Ajax+JSP+JavaBean+JavaServlet 后台数据库:MS-Access/MSSQL 系统...
  • 这次有个任务,需要用java的图形用户界面来实现一个后台管理系统。我大概在网上随便找了一个类似于这个后台管理的框架(真的只是框架,一个登陆的窗口,一个用户管理的非常简单的页面),然后内部的事务逻辑均属原创...
  • 基于java springboot博客管理系统设计和实现

    千次阅读 多人点赞 2021-08-19 10:54:34
    博客,又译为网络日志、 部落格或部落阁等,是一种通常由个人管理、不定期张贴新的文章的网站。 博客上的文章通常根据张贴时间, 以倒序方式由新到旧排列。 许多博客专注在特定的课题上提供评论或新闻, 其他则被...
  • 基于JavaSwing+mysql的酒店管理系统设计和实现

    千次阅读 多人点赞 2021-08-18 19:41:49
    项目是使用Java swing开发,可实现基础数据维护用户登录、系统首页酒店信息管理、主要模块是开房管理、退房管理、房间信息管理、顾客信息管理等功能。界面设计比较简介、适合作为Java课设设计以及学习技术使用。 ...
  • java 仓库管理系统源码

    万次阅读 多人点赞 2020-02-03 21:57:13
    系统提供基本的登入登出功能,同时系统包含两个角色:系统超级管理员和普通管理员,超级管理员具有最高的操作权限,而普通管理员仅具有最基本的操作权限,而且仅能操作自己被指派的仓库。 请求URL鉴权。对于系统...
  • 这个系统的主要有三个角色权限,管理员、老师、学生,系统功能模块包括用户管理、班级信息管理、教师信息管理、学生信息管理、科目信息管理、成绩信息管理。 根据本系统的研究现状和发展趋势,系统从需求分析、结构...
  • 学生成绩管理系统java实现)

    万次阅读 2021-03-10 03:02:35
    最近在看基础的java教程,发现java很多与c++类似,但也有不少差异,有很多要注意的地方,做了这个成绩管理系统,还没用到类,只是多维数组的应用。期间遇到很多问题,也都经过一一百度解决了。实现的功能: 输入学生...
  • Java实现文件管理系统(附带源码)

    千次阅读 2021-04-19 19:46:51
    文件管理越来越受到企业的重视,最近自己也做了个简单的文件管理系统,现与大家分析交流。 一.系统演示
  • 教务管理系统javaweb项目 运行环境:window系统,Apache Tomcat v7.0.84、JDK1.8 开发环境:J2EE eclipse、navicat for mysql 运用的技术:MVC设计模式、DAO模式、Servlet、JSP、Filter、MySQL数据库 该项目主要分为...
  • java开源的文件管理系统

    热门讨论 2011-05-20 18:15:38
    java开源的文件管理系统,可以学习学习
  • 基于JavaSwing+Mysql的酒店管理系统设计和实现

    千次阅读 多人点赞 2021-08-16 13:48:31
    本项目是使用Java swing开发,可实现酒店管理系统登陆/重置、酒店信息查询、入驻管理和退房管理、收银管理以及修改密码等几大模块。界面设计比较简介、适合作为Java课设设计以及学习技术使用。
  • Java课程设计-校园卡管理系统

    万次阅读 2021-10-13 11:01:13
    校园卡管理系统1.介绍相关技术2.项目地址3.数据库4.所需环境5.安装教程6.运行截图7.相关博客 慢慢开始整理自己曾经写过的项目了, 这个是大二的Java课程设计, 原型参考的是学校里面的”校园卡自助机“ 整个设计...
  • JAVA后台管理系统

    千次阅读 2020-08-17 13:20:47
    一款 Java 语言基于 SpringBoot2.x、Layui、Thymeleaf、MybatisPlus、Shiro、MySQL等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可用于快速搭建前后端分离后台管理系统,本着简化开发...
  • java学生信息管理系统(附源码)

    千次阅读 2021-02-12 10:29:07
    3:连接SQL server 2008 数据库用到的软件及环境SQLserver2008,eclipse,sqljdbc4.jar(数据库驱动包)java的JDK环境 (自行安装配置)切记:另外要新建数据库wtf 和新建学生表student(也可以用你自己创建的数据库及表...
  • Java快递物流运输管理系统源码

    千次阅读 2022-04-23 14:27:32
    Java快递物流运输管理系统源码 运行环境:jdk8+tomcat8+mysql5.7+IntelliJIDEA+maven 项目技术:spring+springmvc+Hibernat+bootstrap+jquery
  • 酒店管理系统JAVA源代码

    千次下载 热门讨论 2009-03-15 14:39:51
    用户在使用《酒店管理系统》之前,应注意以下事项: (1)管理员用户名和密码为:mr、mrsoft。 (2)当鼠标经过主界面右下角时,会弹出菜单,在这里可以对本系统的信息进行管理。 业务流程 要想运行本系统,请按照...
  • java 实现图书管理系统

    千次阅读 多人点赞 2021-03-04 22:39:55
    选择了图书管理系统,会用到的javaSE知识有:变量、包、继承、类、接口、循环结构等。是一个很综合的典例。 二、核心需求 1.用户可以登录到系统上 分为 管理员、普通用户两种角色,这两种不同的角色根据自己的身份...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 811,970
精华内容 324,788
关键字:

用户管理系统java

java 订阅