Servlet项目教学(附实例代码)

news2024/11/15 4:26:46

【员工信息管理】

1.员工信息管理

在这里插入图片描述

1.1 介绍
用户进行登录后,可以对员工信息进行管理(增删查改),等操作.如果用户没有登录,不能访问员工操作页面.并且员工操作页面显示当前登录用户信息.

1.2 技术点
使用Vue+ElementUI充当前端界面,使用Servlet+JDBC+Mysql提供数据管理控制.后端统一向前端返回JSON格式的数据.

2. 项目搭建

在这里插入图片描述

2.1 统一前置处理
2.1.1 过滤器
由于所有的请求都是servlet进行处理,但是存在一些共性问题,例如:编码格式,跨域响应头.基于这样的情况,早期web设计者,定义一个对所有请求进行过滤的组件,这个组件叫过滤器.通过实现过滤器的规范,将过滤器注册到服务器,过滤器就会对相应的项目中所有的请求进行干预处理.
在这里插入图片描述

基于过滤器机制,可以将一些共性问题由过滤器处理.JavaWeb中提供接口:Filter,通过实现Filter接口,重写相关方法,再进行注册,就可以使用.

2.1.2 过滤器的实现

  1. 实现Filter接口

  2. 重写相关方法:doFilter方法

  3. 注册过滤器

(1) xml注册

<!-- 声明过滤器 -->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>com.powernode.filter.EncodingFilter</filter-class>
</filter>
<!-- 配置过滤器的规则 -->
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <!-- 所有 .do 后缀结尾的请求 进行编码处理 -->
    <url-pattern>*.do</url-pattern>
</filter-mapping>

(2) 注解注册

@WebFilter("*.do")
//@WebFilter(value="*.do")
//@WebFilter(urlPatterns="*.do")
public class EncodingFilter implements Filter {}

2.1.3 编码字符集处理

package com.powernode.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 *  编码过滤
 *  在进入servlet之前就进行编码设置
 */
@WebFilter(urlPatterns = "*.do")
public class EncodingFilter implements Filter {

    /**
     *  Filter 初始化方法  只会执行一次  项目启动就执行
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter 中 init 方法");
    }

    /**
     *  进行具体的过滤方法
     * @param servletRequest  当前请求对象
     * @param servletResponse  当前响应对象
     * @param filterChain  过滤器链 项目中可以存在多个过滤器
     *                     过滤器的注册方式有2种 :
     *                      xml配置
     *                      注解
     *                    过滤存在先后执行问题: 过滤使用责任链模式
     *                    最先执行的最后执行完.如果XML配置方式,配置在最上方的最先执行
     *                    如果是注解的方式,按照文件名顺序(类加载器是按照文件名称顺序加载的)
     *                   filterChain.doFilter(servletRequest,servletResponse); // 将请求对象和响应对象向下传递  调用下一个方法
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println(" 进行具体的过滤操作 doFilter..... ");
        // xxxxx
        System.out.println("在调用下一个方法之前干点啥......");
        // 调用下一个方法
        // 在进入servlet 之前 就已经设置好了编码格式
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setCharacterEncoding("UTF-8");
        filterChain.doFilter(servletRequest,servletResponse);
        // xxxxx
        System.out.println("在调用完成也干点啥......");
    }

    @Override
    public void destroy() {
        System.out.println("过滤器 销毁前调用的方法");
    }
}

2.1.4 跨域处理

package com.powernode.filter;

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

/**
 * 跨域过滤器
 */
@WebFilter("*.do")
public class CrossFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        // 所有的请求源 允许跨域
        resp.addHeader("Access-Control-Allow-Origin","*");
        // 放行
        chain.doFilter(req,response);
    }
}

2.2 数据库脚本

DROP TABLE IF EXISTS `dept`;

CREATE TABLE `dept`  (

  `dept_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门编号',

  `dept_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门名称',

  `dept_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门备注',

  PRIMARY KEY (`dept_id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;



-- ----------------------------

-- Records of dept

-- ----------------------------

INSERT INTO `dept` VALUES (1, '开发一部', '开发一部');

INSERT INTO `dept` VALUES (2, '开发二部', '开发二部');

INSERT INTO `dept` VALUES (3, '开发三部', '开发三部');



-- ----------------------------

-- Table structure for emp

-- ----------------------------

DROP TABLE IF EXISTS `emp`;

CREATE TABLE `emp`  (

  `emp_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '员工编号',

  `emp_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '员工姓名',

  `emp_sex` int(11) NULL DEFAULT NULL COMMENT '员工性别',

  `emp_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '员工地址',

  `emp_age` int(11) NULL DEFAULT NULL COMMENT '员工年龄',

  `emp_salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '员工工资',

  `emp_birth` datetime(0) NULL DEFAULT NULL COMMENT '员工生日',

  `dept_id` int(11) NULL DEFAULT NULL COMMENT '所属部门ID',

  PRIMARY KEY (`emp_id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;



-- ----------------------------

-- Table structure for user

-- ----------------------------

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user`  (

  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',

  `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',

  `password` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',

  `realname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',

  `img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像',

  PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

2.3 postman安装

接口测试工具,模拟HTTP请求.使用postman模拟常规用户请求操作,可以看到服务器返回的数据,进行接口测试.
在这里插入图片描述

2.4 核心代码
2.4.1 统一业务结果包装类-Result

package com.powernode.common;

/**
 *  统一业务结果 包装类
 */
public class Result {
    /**
     *  统一的业务码  0 标识正常
     */
    private Integer code = 0;
    /**
     *  统一业务消息 默认是 操作成功
     */
    private String msg = "操作成功!";
    /**
     *  业务结果数据 所有操作的数据 放入data 属性中
     */
    private Object data;

    /**
     *  成功 但是没有返回业务数据
     */
    public Result(){}

    /**
     *  成功 但是 存在 返回业务数据
     * @param data
     */
    public Result(Object data){
        this();
        this.data = data;
    }

    /**
     *  异常结果
     * @param code  异常码
     * @param msg 异常消息
     */
    public Result(int code,String msg){
        this.code = code;
        this.msg = msg;
    }


    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

2.4.2 数据库连接配置文件

# 数据库连接配置文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/emp?useUnicode=true&useSSL=false&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456

2.4.3 数据库连接工具类

package com.powernode.util;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * 自定义JDBC工具类:1)提供获取链接Connection的方法   2)关闭资源的方法  3)实现jdbc配置软编码
 */
public final class DBUtils {
    /**
     * 驱动名称
     */
    private static String driverClassName;
    /**
     * 链接信息
     */
    private static String url;
    /**
     * 用户名
     */
    private static String username;
    /**
     * 用户密码
     */
    private static String password;

    static {
        try {
            //关联.properties配置文件
            Properties prop = new Properties();
            InputStream ins = DBUtils.class.getClassLoader().getResourceAsStream("db.properties");
            prop.load(ins);
            //读取.properties配置文件的属性值
            driverClassName = prop.getProperty("jdbc.driverClassName");
            url = prop.getProperty("jdbc.url");
            username = prop.getProperty("jdbc.username");
            password = prop.getProperty("jdbc.password");
            Class.forName(driverClassName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     *
     * @return
     */
    public static Connection getConn() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭资源
     *
     * @param acs
     */
    public static void close(AutoCloseable acs) {
        try {
            if (acs != null) {
                acs.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭资源
     *
     * @param rs
     * @param st
     * @param conn
     */
    public static void close(ResultSet rs, Statement st, Connection conn) {
        try {
            if (rs != null)
                rs.close();
            if (st != null)
                st.close();
            if (conn != null)
                conn.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}
 

2.4.4 通用数据库操作类

package com.powernode.dao;

import com.powernode.util.DBUtils;
import com.powernode.util.PageInfo;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * JDBC工具类:旨在为客户提供更加便捷的操作数据库的方式
 */
public class BaseDao {
    /**
     * 修改:可以执行添加、删除、修改单条操作
     * @param sql
     * @param params
     * @return
     */
    public int executeUpdate(String sql,Object...params){
        Connection conn = null;
        PreparedStatement st = null;
        int i=0;
        try {
            //参数校验
            if(sql==null || "".equals(sql.trim())){
                return 0;
            }
            //获取连接
            conn = DBUtils.getConn();
            //创建Statement对象
            st = conn.prepareStatement(sql);
            //给sql赋值参数
            for (int n=0;params!=null && params.length>=1 &&n<params.length;n++){
                st.setObject(n+1,params[n]);
            }
            //向mysql发送sql语句,接受结果
            i = st.executeUpdate();
        } catch (Exception throwables) {
            throwables.printStackTrace();
        }finally {
            //释放资源
            DBUtils.close(null,st,conn);
        }
        return i;
    }

    /**
     * 批量删除
     * @param sql
     * @param params
     * @return
     */
    public int executeBatchDel(String sql,Object...params){
        Connection conn = null;
        PreparedStatement st = null;
        int[] arr = null;
        try {
            //基本参数校验
            if(sql==null || "".equals(sql.trim())){
                return 0;
            }
            //获取连接
            conn = DBUtils.getConn();
            //在同一个事务中执行
            conn.setAutoCommit(false);
            st = conn.prepareStatement(sql);
            //给参数赋值
            for (int i = 0;params!=null && params.length>=1 && i < params.length; i++) {
                st.setObject(1,params[i]);
                st.addBatch();
            }
            //执行sql
            arr = st.executeBatch();//[0,0,0,0]
        } catch (Exception throwables) {
            throwables.printStackTrace();
        } finally {
            try {
                conn.setAutoCommit(true);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            //释放资源
            DBUtils.close(null,st,conn);
        }
        return arr.length;
    }

    /**
     * 查询多条记录
     * @param sql
     * @param c
     * @param params
     * @param <T>
     * @return
     */
    public <T> List<T> executeQueryList(String sql, Class<T> c ,Object...params){
        Connection conn= null;
        PreparedStatement st = null;
        ResultSet rs = null;
        List<T> dataList = new ArrayList<>();//{}
        try {
            //参数校验
            if(sql==null || "".equals(sql.trim())){
                return dataList;
            }
            //获取Connection连接
            conn = DBUtils.getConn();
            //创建PrepareStatement对象
            st = conn.prepareStatement(sql);
            for (int i = 0;params!=null && params.length>=1 && i < params.length; i++) {
                st.setObject(i+1,params[i]);
            }
            //发送sql,接受结果
            rs = st.executeQuery();
            //获取查询数据的字段个数
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            for(;rs.next();){//取记录的次数
                //创建一个c字节码的对象,用来装一条记录
                T t = c.newInstance();
                for (int i = 1; i <=columnCount ; i++) {
                    //获取某个字段别名  字段别名默认是和字段名一致
                    String columnName = metaData.getColumnLabel(i);
                    //获取字段对应的值
                    Object value = rs.getObject(columnName);
                    //内部for全部执行完了,则代表一条记录取出来了
                    Field field = c.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t,value);
                    field.setAccessible(false);
                }
                //将对象装入到List中
                dataList.add(t);
            }
        } catch (Exception throwables) {
            throwables.printStackTrace();
        }finally {
            DBUtils.close(rs,st,conn);
        }
        return dataList;
    }

    /**
     * 查询单条记录
     * @param sql
     * @param c
     * @param param
     * @param <T>
     * @return
     */
    public <T> T executeQueryOne(String sql,Class<T> c,Object...param){
        return executeQueryList(sql,c,param).size()==0?null:executeQueryList(sql,c,param).get(0);
    }

    /**
     * 分页查询
     * @param sql 基本分页sql,不用写limit
     * @param pageNum 页码
     * @param pageSize 每页显示的数据条数
     * @param c   某一条数据的类型
     * @param params  分页太哦建
     * @param <T>
     * @return
     */
    public <T> PageInfo<T> executeQueryPage(String sql,int pageNum,int pageSize,Class<T> c,Object...params){
        Connection conn=null;
        PreparedStatement st = null;
        ResultSet rs = null;
        PageInfo<T> pageInfo = new PageInfo<>();
        try {
            //校验参数
            if(sql==null || "".equals(sql.trim())){
                return pageInfo;
            }
            if(pageNum<=0 || pageSize<=0){
                return pageInfo;
            }
            if(c==null){
                return pageInfo;
            }
            //去除;
            sql = sql.replaceAll(";","");
            //获取数据库连接:Connection对象
            conn = DBUtils.getConn();
            //准备sql语句
            //创建PrepareStatement对象  (此处有个;的小bug)
            String newSql = sql + " limit "+(pageNum-1)*pageSize+","+pageSize+"";
            st = conn.prepareStatement(newSql);
            //给sql占位符?赋值
            for (int i = 0;params!=null && params.length>=1 && i < params.length; i++) {
                st.setObject(i+1,params[i]);
            }
            //执行sql,处理结果
            rs = st.executeQuery();
            //数据表头信息
            ResultSetMetaData metaData = rs.getMetaData();
            //获取查询sql语句中字段的个数
            int columnCount = metaData.getColumnCount();
            for (;rs.next();){
                //创建一个对象,用于接收一条记录
                T t = c.newInstance();
                for (int i = 1; i <=columnCount ; i++) {
                    //获取字段名
                    String columnName = metaData.getColumnLabel(i);
                    //获取字段值
                    Object columnValue = rs.getObject(columnName);
                    //将对应字段的值装入到实体类对象中去
                    Field field = c.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t,columnValue);
                    field.setAccessible(false);
                }
                //将某一条记录放入到List集合中去
                //往pageInfo对象中添加分页数据
                pageInfo.getData().add(t);
            }
            //往pageInfo对象中添加总记录数
            long total = executeQueryCount(sql);
            pageInfo.setTotal(total);
            //往pageInfo对象中添加总页数
            long temp = total % pageSize;//3%2=1
            int pages = temp==0? (int)(total/pageSize): (int)Math.ceil((double)total/(double)pageSize);
            pageInfo.setPages(pages);
        } catch (Exception throwables) {
            throwables.printStackTrace();
        } finally {
            //释放资源
            DBUtils.close(rs,st,conn);
        }
        return pageInfo;
    }

    /**
     * 统计满足sql条件的总记录数
     * @param sql
     * @return
     */
    private long executeQueryCount(String sql){
        long total = 0;
        Connection conn=null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = DBUtils.getConn();
            String newSql = "select count(*) from ("+sql+") t";
            st = conn.prepareStatement(newSql);
            rs = st.executeQuery();
            for (;rs.next();){
               total = rs.getLong("count(*)");
            }
            return total;
        } catch (Exception throwables) {
            throwables.printStackTrace();
        } finally {
            DBUtils.close(rs,st,conn);
        }
        return total;
    }
}
 

2.4.5 通用分页结果包装类

package com.powernode.util;

import java.util.ArrayList;
import java.util.List;

/**
 * 此实体类对象中封装的是分页相关数据信息: 分页数据、总记录数、页码等
 */
public class PageInfo<T> {

    /**
     * 分页数据
     */
    private List<T> data = new ArrayList<>();

    /**
     * 满足sql条件的总记录数
     */
    private long total;

    /**
     * 总页数
     */
    private int pages;

    public PageInfo() {
    }

    public PageInfo(List<T> data, long total, int pages) {
        this.data = data;
        this.total = total;
        this.pages = pages;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    @Override
    public String toString() {
        return "PageInfo{" +
                "data=" + data +
                ", total=" + total +
                ", pages=" + pages +
                '}';
    }
}
 

3.登录功能

在这里插入图片描述

3.1 servlet三大作用域
servlet三大作用域就是三个用于存储数据的容器,根据其范围划分分为以下三类(小到大):

  1. 当前请求作用域

  2. 当前会话作用域

  3. 当前应用作用域

3.1.1 当前请求作用域
是指存储的数据只能在同一个请求中访问,因为tomcat将每一个请求封装成了HttpServletRequest对象,该对象中存在Map集合

private final Map<String, Object> attributes = new ConcurrentHashMap<>();

只要request对象相同,存储数据Map就相同.当在程序中,使用内部转发时,将一个请求对象传给多个servlet的service中,此时多个servlet使用的同一个请求级别的作用域.因为虽然经历多个servlet程序,但是请求只有一次,并且请求对象和响应对象在传递.

3.1.2 当前应用作用域
当前应用作用域对象,也被称之为servlet容器对象,当项目启动时,tomcat服务器会为每一个应用程序创建且只创建一个(有且只有一个)servlet容器对象,该对象可以在当前应用程序中任何地方进行访问(也就是在servlet中访问),该容器对象也存在Map容器.

获取Servlet容器对象:this.getServletContext()

/**

  * The context attributes for this context.

  */

 protected Map<String,Object> attributes = new ConcurrentHashMap<>();

3.1.3 当前会话作用域

当前会话是指从客户端请求服务器开始,建立一个会话,会话中包含多次请求和响应.使用session对象表示.服务器如何知道多个请求是同一次会话?原理很简单,当第一次请求时,服务器默默的在响应头中添加了一个唯一标识,以后的请求如果带上了这个唯一标识.则服务器就将这批唯一标识一致的请求当做同一次会话中的请求.默认会话默认是30分钟或者一次浏览器的开启和关闭.

因为这个唯一标识,本质上服务器通过浏览器的Cookie机制.将唯一标识通过响应头,告诉浏览器将这个数据存在cookie中,然后浏览器每次请求时默认将有效的cookie带给服务器.所以服务器就会检查从请求头中带过来的数据JSESSIONID的,如果一致说明是同一个会话.

/**

     * The collection of user data attributes associated with this Session.

     */

protected ConcurrentMap<String,Object> attributes = new ConcurrentHashMap<>();
 

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

3.2 三大作用域的API
3.2.1 获取作用域对象

// 当前请求作用域对象
// 由于当前请求作用域对象本身就是request对象本身,所以无需获取
//当前会话作用域对象
HttpSession session = req.getSession();
//当前应用作用域对象
ServletContext applicationContext = req.getServletContext();

3.2.2 作用域存储数据

// 存放数据
// 向当前请求作用域中存放了数据
req.setAttribute("reqKey","reqValue");
session.setAttribute("sessionKey","sessionValue");
applicationContext.setAttribute("appKey","appValue");

3.2.3 获取数据

// 从作用域中获取数据
Object reqKey = req.getAttribute("reqKey");
// 新的请求 所以获取的值 是 null
System.out.println("request作用域数据:"+reqKey);

Object sessionKey = req.getSession().getAttribute("sessionKey");
System.out.println("session作用域数据:"+sessionKey);

Object appKey = req.getServletContext().getAttribute("appKey");

System.out.println("application作用域数据:"+appKey);

3.2.4 删除数据

// 删除作用域中的数据
applicationContext.removeAttribute("appKey");
// 由于作用域底层是 Map结构
// 同样的key 就会覆盖

3.3 会话技术-Session

session技术被称之为会话技术,当今已经不适用了.session技术本质上,在服务器中开辟一块内存,将找到这块数据存储的标识返回给了浏览器,每次浏览器的请求,服务器进行解析时,会进行一个检查,检测session有效性.由于当今,应用需要提高稳定性和可用性.一般服务器多台.session本质上JVM内存中一块数据,多台服务器运行了多个JVM程序,每个JVM内存都有自己独立管理空间,相互无法共享.如果用户访问时,访问的是A服务器,第二次访问时访问的B服务器,就会出现永远不会有第二次访问.市面上,一般使用一些中间件存储会话唯一标识.

3.3.1 session相关API

// 获取当前关联的session 对象
HttpSession session = req.getSession();
// session的唯一标识
String id = session.getId();
// session 有效时间
int maxInactiveInterval = session.getMaxInactiveInterval();
// 设置session 最大有效时间  如果设置为 0 或者负数 则表示一直有效
// session.setMaxInactiveInterval();
// 作用域api

3.4 会话技术Cookie
cookie这个技术,也被称之为客户端缓存技术.cookie技术本质上浏览器的一个机制.是和HTTP协议的一个约定.每次浏览器在请求时,如果发现响应头中存在Set-Cookie的头,则会将相关数据存储在浏览器的缓存中(默认存储在浏览器内存中),如果Set-Cookie这个响应头的数据设置了有效时间,浏览器还会将数据存储在本地磁盘.

每次浏览器在请求时,会去检查存放cookie数据空间,看是否有需要带给服务器的cookie数据.如果有,则使用请求头:cookie带给服务器.

浏览器会从时间,域名,资源路径等多个方面进行检查.

当前cookie也不太适用,因为cookie的本质是数据存在客户端,首先可能存在安全问题,其次,当今是多终端时代(手机/平板/电脑/手表),如果数据存在客户端,很难实现数据共享.

3.4.1 Cookie的Api

Cookie中数据key=value形式,可以通过构造器创建Cookie对象,通过响应头将cookie添加到响应中.

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 获取请求中cookie
    // 获取所有的cookie
    Cookie[] cookies = req.getCookies();
    // 通过for循环 遍历cookie
    // 只能通过对比 具体的 cookie的name值 找到自己想要cookie
    if (ObjectUtil.isNotEmpty(cookies)){
        for (Cookie cookie : cookies) {
            // cookie的名称
            String name = cookie.getName();
            // cookie的值
            String value = cookie.getValue();
            // cookie 有效的域名 域名分为多级域名 : www.baidu.com   www.baike.baidu.com  www.map.baidu.com
            // 一级域名: baidu.com
            // 二级域名 : baike.baidu.com  map.baidu.com
            String domain = cookie.getDomain();
            // cookie 有效的资源路径  默认是当前项目根目录
            String path = cookie.getPath();
            // cookie是否只能被HTTP协议 访问
            boolean httpOnly = cookie.isHttpOnly();
            // 获取 cookie 最大有效期  ( 默认是 内存中  浏览器关闭就没了)
            int maxAge = cookie.getMaxAge();

            System.out.println("name : " + name);
            System.out.println("value : " + value);
        }
    }

    // 创建 cookie
    Cookie cookie = new Cookie("myCookie","myCookieValue");
    // 设置 cookie 最大有效期  单位是秒  如果是 0 则表示删除
    cookie.setMaxAge(60*60);
    // 将cookie 返回给浏览器
    resp.addCookie(cookie);
    // 如果多个cookie  则需要 new 多个cookie 对象
    // 并且 多次调用addCookie

    resp.sendRedirect("index.html");
}

3.5 session和cookie比较
首先session和cookie都能够存储数据,但是session存储在服务器内存中,cookie是存储在浏览器中,相对而言session存储数据的安全性高于cookie.

但是session是依赖cookie实现的.因为查找session的唯一标识存储在cookie中的,session基于cookie.

3.6 应用
3.6.1 验证码功能

ackage com.powernode.servlet;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.GifCaptcha;

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;

/**
 * 验证码 servlet
 */
@WebServlet("/code.do")
public class CheckCodeServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //生成验证图像
        GifCaptcha gifCaptcha = CaptchaUtil.createGifCaptcha(116, 44, 4);
        // 获取验证码字符串
        String code = gifCaptcha.getCode();
        // 获取会话作用域
        HttpSession session = req.getSession();
        // 将验证码 放入session中
        session.setAttribute("code",code);
        // 将验证码返回给浏览器
        gifCaptcha.write(resp.getOutputStream());
    }
}

3.6.2 用户登录功能

package com.powernode.servlet;

import cn.hutool.core.util.StrUtil;
import com.powernode.common.Result;
import com.powernode.listener.AppListener;
import com.powernode.service.UserService;
import com.powernode.service.impl.UserServiceImpl;
import com.powernode.util.RespUtil;

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("/user.do")
public class UserServlet extends HttpServlet {
    UserService userService = AppListener.getInstance(UserService.class);

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String service = req.getParameter("service");
        if(StrUtil.equals(service,"login")){
            login(req,resp);
        }
    }

    /**
     * 处理具体的登录请求
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    private void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String code = req.getParameter("code");
        // 校验验证码
        HttpSession session = req.getSession();
        Object sessionCode = session.getAttribute("code");
        // 判断验证码是否一致
        if (sessionCode == null || !StrUtil.equals(code,sessionCode.toString())){
            RespUtil.writer(new Result(400,"验证码错误"),resp);
            return;
        }
        // 根据用户名和密码查询用户
        Result result = userService.login(username, password);
        if (result.getCode().equals(0)){
            // 将当前登录用户 存储在服务端内存
            session.setAttribute("user",result.getData());
        }
        RespUtil.writer(result,resp);
    }
}

4.员工信息管理

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

4.1 后端数据接口
所有的后端数据接口开发完成后,每开发一个必须使用postman进行一次测试.这样的做的目的,确保后端程序没有问题.

4.1.1 部门列表接口
4.1.1.1 servlet

package com.powernode.servlet;

import cn.hutool.core.util.StrUtil;
import com.powernode.common.Result;
import com.powernode.service.DeptService;
import com.powernode.service.impl.DeptServiceImpl;
import com.powernode.util.RespUtil;

import javax.servlet.ServletContext;
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.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@WebServlet("/dept.do")
public class DeptServlet extends HttpServlet {

    DeptService deptService = new DeptServiceImpl();


    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        *   根据 service 值 调用相关方法
        *       service = login   --> login
        *       service = update --> update
        *   利用反射机制
        *       将service的值当做 方法名  根据 service 查找方法
        *       进行方法调用
        *       无序 各种 service 判断
        * */
        String service = req.getParameter("service");
 /*       try {
            Method method = this.getClass().getDeclaredMethod(service, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this,req,resp);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
*/
        if(StrUtil.equals(service,"all")){
            all(req,resp);
        }
    }

    /**
     *  返回所有的部门信息
     * @param req
     * @param resp
     * @throws IOException
     */
    private void all(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Result result = deptService.queryAll();
        RespUtil.writer(result,resp);
    }
}

4.1.1.2 Service

package com.powernode.service;

import com.powernode.common.Result;

/**
 *  部门相关业务类
 *      业务层  基于具体业务需要 进行调用数据访问层的程序
 *      用户注册:
 *          1. 数据格式校验
 *              长度校验  非空校验    在 controller  层校验  servlet   c层
 *          2. 数据业务校验
 *              用户名是否存在 ?  身份证是否有效
 *              查询数据
 *          3. 插入数据库
 */
public interface DeptService {
    /**
     * 查询所有的部门信息
     * @return
     */
    Result queryAll();
}



package com.powernode.service.impl;

import com.powernode.common.Result;
import com.powernode.dao.DeptDao;
import com.powernode.domain.Dept;
import com.powernode.service.DeptService;

import java.util.List;

public class DeptServiceImpl implements DeptService {
    DeptDao deptDao = new DeptDao();

    @Override
    public Result queryAll() {
        // 查询部门信息
        List<Dept> depts = deptDao.selectAll();
        // 将部门信息数据包装
        return new Result(depts);
    }
}

4.1.1.3 Dao

package com.powernode.dao;

import com.powernode.domain.Dept;

import java.util.List;

/**
 *  数据访问层  只做最基本的数据 增删查改
 */
public class DeptDao extends BaseDao{

    /**
     * 查询所有的部门信息
     * @return
     */
    public List<Dept> selectAll(){
        String sql = "select dept_id as deptId,dept_name as deptName,dept_remark as deptRemark from dept";
        List<Dept> depts = super.executeQueryList(sql, Dept.class);
        return depts;
    }
}

4.1.2 员工分页接口
4.1.2.1 查询实体类

package com.powernode.query;

/**
 * 查询参数
 */
public class EmpPageQuery {
    /**
     * 页码  默认 1
     */
    private Integer page = 1;
    /**
     * 每页条数  默认10
     */
    private Integer limit = 10;
    /**
     *  部门ID
     */
    private Integer  deptId;
    /**
     *  员工名称
     */
    private String  empName;
    /**
     * 员工地址
     */
    private String  empAddress;
    /**
     * 员工性别
     */
    private Integer  empSex;


    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }

    public Integer getDeptId() {
        return deptId;
    }

    public void setDeptId(Integer deptId) {
        this.deptId = deptId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public String getEmpAddress() {
        return empAddress;
    }

    public void setEmpAddress(String empAddress) {
        this.empAddress = empAddress;
    }

    public Integer getEmpSex() {
        return empSex;
    }

    public void setEmpSex(Integer empSex) {
        this.empSex = empSex;
    }
}

4.1.2.2 servlet

package com.powernode.servlet;

import cn.hutool.core.util.StrUtil;
import com.powernode.common.Result;
import com.powernode.query.EmpPageQuery;
import com.powernode.service.EmpService;
import com.powernode.service.impl.EmpServiceImpl;
import com.powernode.util.RespUtil;

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("/emp.do")
public class EmpServlet extends HttpServlet {


    EmpService empService = new EmpServiceImpl();


    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String service = req.getParameter("service");
        if (StrUtil.equals(service,"page")){
            page(req,resp);
        }else if(StrUtil.equals(service,"add")){
            //TODO
        }else if(StrUtil.equals(service,"update")){
            //TODO
        }else if(StrUtil.equals(service,"delete")){
            //TODO
        }
    }

    /**
     *  获取员工的分页信息
     * @param req
     * @param resp
     */
    private void page(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获取请求参数
        // 页码
        String page = req.getParameter("page");
        // 每页条数
        String limit = req.getParameter("limit");
        //部门ID
        String deptId = req.getParameter("deptId");
        //姓名
        String empName = req.getParameter("empName");
        //地址
        String empAddress = req.getParameter("empAddress");
        //性别
        String empSex = req.getParameter("empSex");

        EmpPageQuery query = new EmpPageQuery();
        if (StrUtil.isNotBlank(page)){
            query.setPage(Integer.parseInt(page));
        }
        if (StrUtil.isNotBlank(limit)){
            query.setLimit(Integer.parseInt(limit));
        }
        if (StrUtil.isNotBlank(deptId)){
            query.setDeptId(Integer.parseInt(deptId));
        }

        if (StrUtil.isNotBlank(empName)){
            query.setEmpName(empName);
        }
        if (StrUtil.isNotBlank(empAddress)){
            query.setEmpAddress(empAddress);
        }
        if (StrUtil.isNotBlank(empSex)){
            query.setEmpSex(Integer.parseInt(empSex));
        }
        Result result = empService.queryPage(query);
        // 将数据使用JSON返回
        RespUtil.writer(result,resp);
    }
}

4.1.2.3 service

package com.powernode.service;

import com.powernode.common.Result;
import com.powernode.query.EmpPageQuery;

/**
 * 员工的业务类
 */
public interface EmpService {


    /**
     * 分页查询员工信息
     * @param query
     * @return
     */
    Result queryPage(EmpPageQuery query);
}



package com.powernode.service.impl;

import com.powernode.common.Result;
import com.powernode.dao.EmpDao;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.service.EmpService;
import com.powernode.util.PageInfo;

public class EmpServiceImpl implements EmpService {
    EmpDao empDao = new EmpDao();


    @Override
    public Result queryPage(EmpPageQuery query) {
        PageInfo<Emp> empPageInfo = empDao.selectPage(query);
        return new Result(empPageInfo);
    }
}

4.1.2.4 dao

package com.powernode.dao;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.util.PageInfo;

public class EmpDao  extends  BaseDao{
    /**
     * 分页查询员工信息
     * @param query
     * @return
     */
    public PageInfo<Emp>  selectPage(EmpPageQuery  query){
        String sql = "select emp_id as empId,emp_name as empName,emp_sex as empSex,emp_address as empAddress,emp_age as empAge,emp_salary as empSalary,`emp_birth` as empBirth, `dept_id` as deptId from emp where 1=1 ";
        if(ObjectUtil.isNotNull(query.getDeptId())){
            sql = sql + "  and dept_id =  "+query.getDeptId();
        }
        if(StrUtil.isNotBlank(query.getEmpName())){
            sql = sql + "  and emp_name like '%"+ query.getEmpName() +"%'";
        }
        if(StrUtil.isNotBlank(query.getEmpAddress())){
            sql = sql + "  and emp_addresss like '%"+ query.getEmpAddress() +"%'";
        }
        if(ObjectUtil.isNotNull(query.getEmpSex())){
            sql = sql + "  and emp_sex =  "+query.getEmpSex();
        }
        PageInfo<Emp> empPageInfo = super.executeQueryPage(sql, query.getPage(), query.getLimit(), Emp.class);
        return empPageInfo;

    }
}
 

4.1.3 新增员工接口
4.1.3.0.1 servlet

package com.powernode.servlet;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.powernode.common.Result;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.service.EmpService;
import com.powernode.service.impl.EmpServiceImpl;
import com.powernode.util.RespUtil;

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("/emp.do")
public class EmpServlet extends HttpServlet {


    EmpService empService = new EmpServiceImpl();


    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String service = req.getParameter("service");
        if (StrUtil.equals(service,"page")){
            page(req,resp);
        }else if(StrUtil.equals(service,"add")){
            add(req,resp);
        }
    }

    /**
     *  添加员工信息
     * @param req
     * @param resp
     */
    private void add(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //姓名
        String empName = req.getParameter("empName");
        //性别
        String empSex = req.getParameter("empSex");
        //地址
        String empAddress = req.getParameter("empAddress");
        //年龄
        String empAge = req.getParameter("empAge");
        //工资
        String empSalary = req.getParameter("empSalary");
        //生日
        String empBirth = req.getParameter("empBirth");
        //部门ID
        String deptId = req.getParameter("deptId");

        // empBirth : 2022-04-22
        DateTime birth = DateUtil.parse(empBirth, DatePattern.NORM_DATE_PATTERN);
        Emp emp = new Emp(empName,Integer.parseInt(empSex),empAddress,Integer.parseInt(empAge),Integer.parseInt(empSalary),birth,Integer.parseInt(deptId));
        Result rs = empService.add(emp);
        RespUtil.writer(rs,resp);

    }

4.1.3.0.2 service

package com.powernode.service;

import com.powernode.common.Result;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;

/**
 * 员工的业务类
 */
public interface EmpService {


    /**
     * 分页查询员工信息
     * @param query
     * @return
     */
    Result queryPage(EmpPageQuery query);

    Result add(Emp emp);
}



package com.powernode.service.impl;

import com.powernode.common.Result;
import com.powernode.dao.EmpDao;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.service.EmpService;
import com.powernode.util.PageInfo;

public class EmpServiceImpl implements EmpService {
    EmpDao empDao = new EmpDao();


    @Override
    public Result queryPage(EmpPageQuery query) {
        PageInfo<Emp> empPageInfo = empDao.selectPage(query);
        return new Result(empPageInfo);
    }

    @Override
    public Result add(Emp emp) {
        int m = empDao.insert(emp);
        if (m == 1){
            return new Result();
        }
        return new Result(400,"数据添加失败");
    }


}

4.1.3.0.3 dao

package com.powernode.dao;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.util.PageInfo;

public class EmpDao  extends  BaseDao{


    /**
     * 分页查询员工信息
     * @param query
     * @return
     */
    public PageInfo<Emp>  selectPage(EmpPageQuery  query){
        String sql = "select emp_id as empId,emp_name as empName,emp_sex as empSex,emp_address as empAddress,emp_age as empAge,emp_salary as empSalary,`emp_birth` as empBirth, `dept_id` as deptId from emp where 1=1 ";
        if(ObjectUtil.isNotNull(query.getDeptId())){
            sql = sql + "  and dept_id =  "+query.getDeptId();
        }
        if(StrUtil.isNotBlank(query.getEmpName())){
            sql = sql + "  and emp_name like '%"+ query.getEmpName() +"%'";
        }
        if(StrUtil.isNotBlank(query.getEmpAddress())){
            sql = sql + "  and emp_addresss like '%"+ query.getEmpAddress() +"%'";
        }
        if(ObjectUtil.isNotNull(query.getEmpSex())){
            sql = sql + "  and emp_sex =  "+query.getEmpSex();
        }
        PageInfo<Emp> empPageInfo = super.executeQueryPage(sql, query.getPage(), query.getLimit(), Emp.class);
        return empPageInfo;

    }


    public int insert(Emp emp) {
        String sql = "INSERT INTO emp(`emp_name`, `emp_sex`, `emp_address`, `emp_age`, `emp_salary`, `emp_birth`, `dept_id`) VALUES (?, ?, ?, ?, ?,?, ?)";
        return super.executeUpdate(sql,emp.getEmpName(),emp.getEmpSex(),emp.getEmpAddress(),emp.getEmpAge(),emp.getEmpSalary(),emp.getEmpBirth(),emp.getDeptId());
    }

}

4.1.3.1 修改员工接口
4.1.3.1.1 servlet

package com.powernode.servlet;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.powernode.common.Result;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.service.EmpService;
import com.powernode.service.impl.EmpServiceImpl;
import com.powernode.util.RespUtil;

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("/emp.do")
public class EmpServlet extends HttpServlet {


    EmpService empService = new EmpServiceImpl();


    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String service = req.getParameter("service");
        if (StrUtil.equals(service,"page")){
            page(req,resp);
        }else if(StrUtil.equals(service,"add")){
            add(req,resp);
        }else if(StrUtil.equals(service,"update")){
            update(req,resp);
        }
    }



    /**
     * 修改员工信息
     * @param req
     * @param resp
     * @throws IOException
     */
    private void update(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //员工ID
        String empId = req.getParameter("empId");
        //姓名
        String empName = req.getParameter("empName");
        //性别
        String empSex = req.getParameter("empSex");
        //地址
        String empAddress = req.getParameter("empAddress");
        //年龄
        String empAge = req.getParameter("empAge");
        //工资
        String empSalary = req.getParameter("empSalary");
        //生日
        String empBirth = req.getParameter("empBirth");
        //部门ID
        String deptId = req.getParameter("deptId");

        // empBirth : 2022-04-22
        DateTime birth = DateUtil.parse(empBirth, DatePattern.NORM_DATE_PATTERN);
        Emp emp = new Emp(Integer.parseInt(empId),empName,Integer.parseInt(empSex),empAddress,Integer.parseInt(empAge),Integer.parseInt(empSalary),birth,Integer.parseInt(deptId));
        Result rs = empService.update(emp);
        RespUtil.writer(rs,resp);

    }

    /**
     *  添加员工信息
     * @param req
     * @param resp
     */
    private void add(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //姓名
        String empName = req.getParameter("empName");
        //性别
        String empSex = req.getParameter("empSex");
        //地址
        String empAddress = req.getParameter("empAddress");
        //年龄
        String empAge = req.getParameter("empAge");
        //工资
        String empSalary = req.getParameter("empSalary");
        //生日
        String empBirth = req.getParameter("empBirth");
        //部门ID
        String deptId = req.getParameter("deptId");

        // empBirth : 2022-04-22
        DateTime birth = DateUtil.parse(empBirth, DatePattern.NORM_DATE_PATTERN);
        Emp emp = new Emp(empName,Integer.parseInt(empSex),empAddress,Integer.parseInt(empAge),Integer.parseInt(empSalary),birth,Integer.parseInt(deptId));
        Result rs = empService.add(emp);
        RespUtil.writer(rs,resp);

    }

    /**
     *  获取员工的分页信息
     * @param req
     * @param resp
     */
    private void page(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获取请求参数
        // 页码
        String page = req.getParameter("page");
        // 每页条数
        String limit = req.getParameter("limit");
        //部门ID
        String deptId = req.getParameter("deptId");
        //姓名
        String empName = req.getParameter("empName");
        //地址
        String empAddress = req.getParameter("empAddress");
        //性别
        String empSex = req.getParameter("empSex");

        EmpPageQuery query = new EmpPageQuery();
        if (StrUtil.isNotBlank(page)){
            query.setPage(Integer.parseInt(page));
        }
        if (StrUtil.isNotBlank(limit)){
            query.setLimit(Integer.parseInt(limit));
        }
        if (StrUtil.isNotBlank(deptId)){
            query.setDeptId(Integer.parseInt(deptId));
        }

        if (StrUtil.isNotBlank(empName)){
            query.setEmpName(empName);
        }
        if (StrUtil.isNotBlank(empAddress)){
            query.setEmpAddress(empAddress);
        }
        if (StrUtil.isNotBlank(empSex)){
            query.setEmpSex(Integer.parseInt(empSex));
        }
        Result result = empService.queryPage(query);
        // 将数据使用JSON返回
        RespUtil.writer(result,resp);
    }
}

4.1.3.1.2 service

package com.powernode.service;

import com.powernode.common.Result;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;

/**
 * 员工的业务类
 */
public interface EmpService {


    /**
     * 分页查询员工信息
     * @param query
     * @return
     */
    Result queryPage(EmpPageQuery query);

    Result add(Emp emp);

    Result update(Emp emp);
}



package com.powernode.service.impl;

import com.powernode.common.Result;
import com.powernode.dao.EmpDao;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.service.EmpService;
import com.powernode.util.PageInfo;

public class EmpServiceImpl implements EmpService {
    EmpDao empDao = new EmpDao();


    @Override
    public Result queryPage(EmpPageQuery query) {
        PageInfo<Emp> empPageInfo = empDao.selectPage(query);
        return new Result(empPageInfo);
    }

    @Override
    public Result add(Emp emp) {
        int m = empDao.insert(emp);
        if (m == 1){
            return new Result();
        }
        return new Result(400,"数据添加失败");
    }

    @Override
    public Result update(Emp emp) {
        int m = empDao.updateById(emp);
        if (m == 1){
            return new Result();
        }
        return new Result(400,"数据修改失败");
    }
}
 

4.1.3.1.3 dao

package com.powernode.dao;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.util.PageInfo;

public class EmpDao  extends  BaseDao{


    /**
     * 分页查询员工信息
     * @param query
     * @return
     */
    public PageInfo<Emp>  selectPage(EmpPageQuery  query){
        String sql = "select emp_id as empId,emp_name as empName,emp_sex as empSex,emp_address as empAddress,emp_age as empAge,emp_salary as empSalary,`emp_birth` as empBirth, `dept_id` as deptId from emp where 1=1 ";
        if(ObjectUtil.isNotNull(query.getDeptId())){
            sql = sql + "  and dept_id =  "+query.getDeptId();
        }
        if(StrUtil.isNotBlank(query.getEmpName())){
            sql = sql + "  and emp_name like '%"+ query.getEmpName() +"%'";
        }
        if(StrUtil.isNotBlank(query.getEmpAddress())){
            sql = sql + "  and emp_addresss like '%"+ query.getEmpAddress() +"%'";
        }
        if(ObjectUtil.isNotNull(query.getEmpSex())){
            sql = sql + "  and emp_sex =  "+query.getEmpSex();
        }
        PageInfo<Emp> empPageInfo = super.executeQueryPage(sql, query.getPage(), query.getLimit(), Emp.class);
        return empPageInfo;

    }


    public int insert(Emp emp) {
        String sql = "INSERT INTO emp(`emp_name`, `emp_sex`, `emp_address`, `emp_age`, `emp_salary`, `emp_birth`, `dept_id`) VALUES (?, ?, ?, ?, ?,?, ?)";
        return super.executeUpdate(sql,emp.getEmpName(),emp.getEmpSex(),emp.getEmpAddress(),emp.getEmpAge(),emp.getEmpSalary(),emp.getEmpBirth(),emp.getDeptId());
    }

    public int updateById(Emp emp) {
        String sql = "UPDATE `emp` SET `emp_name` = ?, `emp_sex` = ?, `emp_address` = ?, `emp_age` = ?, `emp_salary` = ?, `emp_birth` = ? , `dept_id` = ? WHERE `emp_id` = ?";
        return  super.executeUpdate(sql,emp.getEmpName(),emp.getEmpSex(),emp.getEmpAddress(),emp.getEmpAge(),emp.getEmpSalary(),emp.getEmpBirth(),emp.getDeptId(),emp.getEmpId());
    }
}

4.1.3.2 删除员工信息接口
4.1.3.2.1 servlet

package com.powernode.servlet;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.powernode.common.Result;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.service.EmpService;
import com.powernode.service.impl.EmpServiceImpl;
import com.powernode.util.RespUtil;

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("/emp.do")
public class EmpServlet extends HttpServlet {


    EmpService empService = new EmpServiceImpl();


    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String service = req.getParameter("service");
        if (StrUtil.equals(service,"page")){
            page(req,resp);
        }else if(StrUtil.equals(service,"add")){
            add(req,resp);
        }else if(StrUtil.equals(service,"update")){
            update(req,resp);
        }else if(StrUtil.equals(service,"delete")){
            delete(req,resp);
        }
    }

    /**
     * 删除员工信息
     * @param req
     * @param resp
     */
    private void delete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String empId = req.getParameter("empId");
        Result rs = empService.delete(empId);
        RespUtil.writer(rs,resp);
    }

    /**
     * 修改员工信息
     * @param req
     * @param resp
     * @throws IOException
     */
    private void update(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //员工ID
        String empId = req.getParameter("empId");
        //姓名
        String empName = req.getParameter("empName");
        //性别
        String empSex = req.getParameter("empSex");
        //地址
        String empAddress = req.getParameter("empAddress");
        //年龄
        String empAge = req.getParameter("empAge");
        //工资
        String empSalary = req.getParameter("empSalary");
        //生日
        String empBirth = req.getParameter("empBirth");
        //部门ID
        String deptId = req.getParameter("deptId");

        // empBirth : 2022-04-22
        DateTime birth = DateUtil.parse(empBirth, DatePattern.NORM_DATE_PATTERN);
        Emp emp = new Emp(Integer.parseInt(empId),empName,Integer.parseInt(empSex),empAddress,Integer.parseInt(empAge),Integer.parseInt(empSalary),birth,Integer.parseInt(deptId));
        Result rs = empService.update(emp);
        RespUtil.writer(rs,resp);

    }

    /**
     *  添加员工信息
     * @param req
     * @param resp
     */
    private void add(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //姓名
        String empName = req.getParameter("empName");
        //性别
        String empSex = req.getParameter("empSex");
        //地址
        String empAddress = req.getParameter("empAddress");
        //年龄
        String empAge = req.getParameter("empAge");
        //工资
        String empSalary = req.getParameter("empSalary");
        //生日
        String empBirth = req.getParameter("empBirth");
        //部门ID
        String deptId = req.getParameter("deptId");

        // empBirth : 2022-04-22
        DateTime birth = DateUtil.parse(empBirth, DatePattern.NORM_DATE_PATTERN);
        Emp emp = new Emp(empName,Integer.parseInt(empSex),empAddress,Integer.parseInt(empAge),Integer.parseInt(empSalary),birth,Integer.parseInt(deptId));
        Result rs = empService.add(emp);
        RespUtil.writer(rs,resp);

    }

    /**
     *  获取员工的分页信息
     * @param req
     * @param resp
     */
    private void page(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获取请求参数
        // 页码
        String page = req.getParameter("page");
        // 每页条数
        String limit = req.getParameter("limit");
        //部门ID
        String deptId = req.getParameter("deptId");
        //姓名
        String empName = req.getParameter("empName");
        //地址
        String empAddress = req.getParameter("empAddress");
        //性别
        String empSex = req.getParameter("empSex");

        EmpPageQuery query = new EmpPageQuery();
        if (StrUtil.isNotBlank(page)){
            query.setPage(Integer.parseInt(page));
        }
        if (StrUtil.isNotBlank(limit)){
            query.setLimit(Integer.parseInt(limit));
        }
        if (StrUtil.isNotBlank(deptId)){
            query.setDeptId(Integer.parseInt(deptId));
        }

        if (StrUtil.isNotBlank(empName)){
            query.setEmpName(empName);
        }
        if (StrUtil.isNotBlank(empAddress)){
            query.setEmpAddress(empAddress);
        }
        if (StrUtil.isNotBlank(empSex)){
            query.setEmpSex(Integer.parseInt(empSex));
        }
        Result result = empService.queryPage(query);
        // 将数据使用JSON返回
        RespUtil.writer(result,resp);
    }
}
 

4.1.3.2.2 service

package com.powernode.service;

import com.powernode.common.Result;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;

/**
 * 员工的业务类
 */
public interface EmpService {


    /**
     * 分页查询员工信息
     * @param query
     * @return
     */
    Result queryPage(EmpPageQuery query);

    Result add(Emp emp);

    Result update(Emp emp);

    Result delete(String empId);
}



package com.powernode.service.impl;

import com.powernode.common.Result;
import com.powernode.dao.EmpDao;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.service.EmpService;
import com.powernode.util.PageInfo;

public class EmpServiceImpl implements EmpService {
    EmpDao empDao = new EmpDao();


    @Override
    public Result queryPage(EmpPageQuery query) {
        PageInfo<Emp> empPageInfo = empDao.selectPage(query);
        return new Result(empPageInfo);
    }

    @Override
    public Result add(Emp emp) {
        int m = empDao.insert(emp);
        if (m == 1){
            return new Result();
        }
        return new Result(400,"数据添加失败");
    }

    @Override
    public Result update(Emp emp) {
        int m = empDao.updateById(emp);
        if (m == 1){
            return new Result();
        }
        return new Result(400,"数据修改失败");
    }

    @Override
    public Result delete(String empId) {
        int m = empDao.deleteById(empId);
        if (m == 1){
            return new Result();
        }
        return new Result(400,"数据删除失败");
    }
}
 

4.1.3.2.3 dao

package com.powernode.dao;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.powernode.domain.Emp;
import com.powernode.query.EmpPageQuery;
import com.powernode.util.PageInfo;

public class EmpDao  extends  BaseDao{


    /**
     * 分页查询员工信息
     * @param query
     * @return
     */
    public PageInfo<Emp>  selectPage(EmpPageQuery  query){
        String sql = "select emp_id as empId,emp_name as empName,emp_sex as empSex,emp_address as empAddress,emp_age as empAge,emp_salary as empSalary,`emp_birth` as empBirth, `dept_id` as deptId from emp where 1=1 ";
        if(ObjectUtil.isNotNull(query.getDeptId())){
            sql = sql + "  and dept_id =  "+query.getDeptId();
        }
        if(StrUtil.isNotBlank(query.getEmpName())){
            sql = sql + "  and emp_name like '%"+ query.getEmpName() +"%'";
        }
        if(StrUtil.isNotBlank(query.getEmpAddress())){
            sql = sql + "  and emp_addresss like '%"+ query.getEmpAddress() +"%'";
        }
        if(ObjectUtil.isNotNull(query.getEmpSex())){
            sql = sql + "  and emp_sex =  "+query.getEmpSex();
        }
        PageInfo<Emp> empPageInfo = super.executeQueryPage(sql, query.getPage(), query.getLimit(), Emp.class);
        return empPageInfo;

    }


    public int insert(Emp emp) {
        String sql = "INSERT INTO emp(`emp_name`, `emp_sex`, `emp_address`, `emp_age`, `emp_salary`, `emp_birth`, `dept_id`) VALUES (?, ?, ?, ?, ?,?, ?)";
        return super.executeUpdate(sql,emp.getEmpName(),emp.getEmpSex(),emp.getEmpAddress(),emp.getEmpAge(),emp.getEmpSalary(),emp.getEmpBirth(),emp.getDeptId());
    }

    public int updateById(Emp emp) {
        String sql = "UPDATE `emp` SET `emp_name` = ?, `emp_sex` = ?, `emp_address` = ?, `emp_age` = ?, `emp_salary` = ?, `emp_birth` = ? , `dept_id` = ? WHERE `emp_id` = ?";
        return  super.executeUpdate(sql,emp.getEmpName(),emp.getEmpSex(),emp.getEmpAddress(),emp.getEmpAge(),emp.getEmpSalary(),emp.getEmpBirth(),emp.getDeptId(),emp.getEmpId());
    }

    public int deleteById(String empId) {
        String sql = "delete from emp where emp_id = "+empId;
        return  super.executeUpdate(sql);
    }
}

4.2 前端界面
4.2.1 登录界面

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Login Page</title>
    <!-- 样 式 文 件 -->
   <link rel="stylesheet" href="resources/css/pear.css" />
    <link rel="stylesheet" href="resources/css/login.css" />
    <link rel="stylesheet" href="resources/element/index.css" />
    <script src="resources/js/vue.js"></script>
    <script src="resources/js/axios.js"></script>
    <script src="resources/element/index.js"></script>
</head>
<!-- 代 码 结 构 -->
<body background="resources/images/background.svg" style="background-size: cover;">
<form class="layui-form" action="javascript:void(0);" id="app">
    <div class="layui-form-item">
        <img class="logo" src="resources/images/logo.png" />
        <div class="title">E M P</div>
        <div class="desc">
            江 夏 区 最 靓 的 仔!
        </div>
    </div>
    <div class="layui-form-item">
        <input placeholder="账 户 : admin " v-model="form.username"  hover class="layui-input"  />
    </div>
    <div class="layui-form-item">
        <input placeholder="密 码 : admin "  v-model="form.password"   hover class="layui-input"  />
    </div>
    <div class="layui-form-item">
        <input placeholder="验证码 : " v-model="form.code"  hover  lay-verify="required" class="code layui-input layui-input-inline"  />
        <img :src="codeUrl" class="codeImage" @click="getCheckCode" />
    </div>

    <div class="layui-form-item">
        <button type="button" @click="login" class="pear-btn pear-btn-success login" lay-submit lay-filter="login">
            登 入
        </button>
    </div>
</form>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            form:{
                username:'',
                password:'',
                code:''
            },
            codeUrl:"code.do"
        },
        methods:{
            login(){
                console.log(this.form)
                axios.post("user.do?service=login",this.form,{
                    transformRequest:[function (data,headers) {
                        let arr = [];
                        for (let key in data) {
                            let value = data[key];
                            arr.push(key+"="+value);
                        }
                        return arr.join("&");
                    }]
                }).then(res=>{
                    //打印 服务端返回的数据
                    console.log(res.data);
                    let result = res.data;
                    if (result.code != 0){
                        //将错误信息展示
                        this.$message.error(result.msg);
                        return false;
                    }
                    // 登录成功情况
                    // 将当前用户 存储到 sessionStorage 便于 其他页面 获取当前用户信息
                    sessionStorage.setItem("user",JSON.stringify(result.data))
                    // 页面跳转
                    location.href = "main.html";
                });
            },
            getCheckCode(){
                this.codeUrl = "code.do?"+new Date();
            }
        }

    });



</script>

</body>
</html>

4.2.2 数据页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="resources/element/index.css"/>
    <script src="resources/js/vue.js"></script>
    <script src="resources/js/axios.js"></script>
    <script src="resources/element/index.js"></script>
</head>
<body>
<div id="app">
    <!--  上面编写搜索条件   -->
    <el-row>
        <el-col :span="20" :offset="2">
            <el-form :inline="true">
                <el-form-item label="部门" label-width="80px">
                    <el-select v-model="search.deptId" clearable placeholder="请选择">
                        <el-option v-for="item in depts" :label="item.deptName" :value="item.deptId"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="姓名" label-width="80px">
                    <el-input placeholder="姓名" v-model="search.empName"></el-input>
                </el-form-item>
                <el-form-item label="地址" label-width="80px">
                    <el-input placeholder="地址" v-model="search.empAddress"></el-input>
                </el-form-item>
                <el-form-item label="性别" label-width="80px">
                    <el-select v-model="search.empSex" clearable placeholder="请选择">
                        <el-option label="男" value="1"></el-option>
                        <el-option label="女" value="2"></el-option>
                    </el-select>
                </el-form-item>
                <el-button native-type="button" icon="el-icon-search" type="primary" @click="handlerSearch">查询
                </el-button>
                <el-button native-type="reset" icon="el-icon-refresh" type="danger">重置</el-button>
            </el-form>
        </el-col>
    </el-row>
    <el-divider></el-divider>
    <!-- 数据表格 -->
    <el-row>
        <el-col :span="20" :offset="2">
            <el-button type="primary" icon="el-icon-add" style="margin-bottom: 15px" size="small" @click="toAdd">添加
            </el-button>
            <el-table
                    :data="empPageInfo.data"
                    style="width: 100%">
                <el-table-column
                        label="编号"
                        prop="empId"
                        width="180">
                </el-table-column>
                <el-table-column
                        label="姓名"
                        prop="empName"
                        width="180">
                </el-table-column>
                <el-table-column
                        label="性别"
                        prop="empSex"
                        width="180">
                    <template slot-scope="scope">
                        {{scope.row.empSex == 1 ? '男' : '女'}}
                        <!-- <el-tag :type="scope.row.empSex == 1 ? 'success':'primary'"> {{scope.row.empSex == 1 ? '男':'女'}}</el-tag>-->
                    </template>
                </el-table-column>
                <el-table-column
                        label="地址"
                        prop="empAddress"
                        width="180">
                </el-table-column>
                <el-table-column
                        label="年龄"
                        prop="empAge"
                        width="180">
                </el-table-column>
                <el-table-column
                        label="工资"
                        prop="empSalary"
                        width="180">
                </el-table-column>
                <el-table-column
                        label="部门"
                        prop="deptId"
                        width="180">
                    <template slot-scope="scope">
                        {{scope.row.deptId|getDeptName}}
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template slot-scope="scope">
                        <el-button
                                size="mini"
                                @click="toEdit(scope.row)">编辑
                        </el-button>
                        <el-button
                                size="mini"
                                type="danger"
                                @click="handleDelete(scope.row)">删除
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 分页组件 -->
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="currentPage"
                    :page-sizes="[10,20,50,100]"
                    :page-size="pageSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="empPageInfo.total">
            </el-pagination>
        </el-col>
    </el-row>
    <!-- 弹出层 -->
    <el-dialog :title="title" :visible.sync="showed" :close-on-click-modal="false" :before-close="clearFormValidateMsg">
        <el-form ref="empForm" :model="form" :rules="rules">
            <el-form-item label="姓名" label-width="80px" prop="empName">
                <el-input v-model="form.empName" autocomplete="off" placeholder="姓名"></el-input>
            </el-form-item>
            <el-form-item label="性别" label-width="80px" prop="empSex">
                <el-radio-group v-model="form.empSex">
                    <el-radio label="1"></el-radio>
                    <el-radio label="2"></el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item label="地址" label-width="80px" prop="empAddress">
                <el-input v-model="form.empAddress" autocomplete="off" placeholder="地址"></el-input>
            </el-form-item>
            <el-form-item label="年龄" label-width="80px" prop="empAge">
                <el-input v-model="form.empAge" autocomplete="off" placeholder="年龄"></el-input>
            </el-form-item>
            <el-form-item label="工资" label-width="80px" prop="empSalary">
                <el-input v-model="form.empSalary" autocomplete="off" placeholder="工资"></el-input>
            </el-form-item>
            <el-form-item label="生日" label-width="80px" prop="empBirth">
                <el-date-picker
                        v-model="form.empBirth"
                        type="date"
                        value-format="yyyy-MM-dd"
                        placeholder="请选择生日">
                </el-date-picker>
            </el-form-item>
            <el-form-item label="部门" label-width="80px" prop="deptId">
                <el-select v-model="form.deptId" clearable placeholder="请选择部门">
                    <el-option v-for="item in depts" :label="item.deptName" :value="item.deptId"></el-option>
                </el-select>
            </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
            <el-button @click="clearFormValidateMsg">取 消</el-button>
            <el-button type="primary" @click="handlerEdit">确 定</el-button>
        </div>
    </el-dialog>
</div>


<script>
    let that;
    const app = new Vue({
        el: "#app",
        beforeCreate() {
            that = this;
        },
        data: {
            depts: [], // 所有的部门信息
            search: { // 搜索数据
                deptId: undefined,
                empName: undefined,
                empAddress: undefined,
                empSex: undefined
            },
            empPageInfo: { // 分页查询的员工数据
            },
            pageSize: 10,// 每页条数
            currentPage: 1,// 当前页
            title: "添加员工",
            showed: false, // 弹出是否显示
            form: {
                empName: '', //员工名称
                empSex: undefined, //性别
                empAddress: '', //地址
                empAge: '', //年龄
                empSalary: '', //工资
                empBirth: '', //生日
                deptId: '', //部门
            },
            rules: {
                empName: [{required: true, min: 2, max: 10, message: '请输入员工名称2~10位字符', trigger: 'blur'}],
                empSex: [{required: true, type: 'enum', enum: ['1', '2'], message: '请选择员工性别:男或女'}],
                empAddress: [{required: true, min: 2, max: 100, message: '请输入员工地址,最多100字符'}],
                empAge: [{required: true, message: '请输入员工年龄'}],
                empSalary: [{required: true, message: '请输入员工工资'}],
                empBirth: [{required: true, message: '请选择员工生日'}],
                deptId: [{required: true, message: '请选择部门'}],
            }
        },
        created() {
            // 初始化 部门数据
            this.getAllDepts();
            //初始化员工信息表格
            this.getEmpPage();
        },
        methods: {
            clearFormValidateMsg(){
                this.$message("弹层准备关闭!")
                // 清除校验信息
                this.$refs.empForm.clearValidate();
                this.showed = false;
            },
            // 获取所有的部门信息
            getAllDepts() {
                axios.get("dept.do?service=all").then(res => {
                    let rs = res.data;
                    if (rs.code != 0) {
                        this.$message.error(rs.msg);
                        return false;
                    }
                    // 为部门赋值
                    this.depts = rs.data;
                });
            },
            getEmpPage() { // 查询 emp 分页信息
                // 为当前页码赋值
                this.search.page = this.currentPage;
                // 为每页条数赋值
                this.search.limit = this.pageSize;
                axios.get("emp.do?service=page", {
                        params: this.search
                    }
                ).then(res => {
                    let rs = res.data;
                    if (rs.code != 0) {
                        this.$message.error(rs.msg);
                        return false;
                    }
                    // 为员工信息赋值
                    this.empPageInfo = rs.data;
                });
            },
            handlerSearch() {
                this.currentPage = 1;
                // 调用获取员工信息的方法
                this.getEmpPage();
            },
            handleSizeChange(val) { // 每页条数 发生变化是调用的函数
                this.pageSize = val;
                this.currentPage = 1;
                // 调用获取员工信息的方法
                this.getEmpPage();
            },
            handleCurrentChange(val) { // 当前页码发生变化的函数
                this.currentPage = val;
                // 调用获取员工信息的方法
                this.getEmpPage();
            },
            toEdit(emp) { //编辑方法
                // 展示弹出层
                this.title = "编辑员工",
                this.showed = true;
                let data = {};
                Object.assign(data,emp);
                this.form = data;
                this.form.empSex = "" + emp.empSex; //性别
                // 标识添加
                this.form.service = "update";
            },
            toAdd() { // 将弹出层展示
                this.title = "添加员工",
                // 展示弹出层
                this.showed = true;
                // 标识添加
                this.form.service = "add";
            },
            handlerEdit() { // 该方法即是添加 也是修改的方法  service = add 就是添加  update 就是修改
                // 进行数据校验
                let flag = this.$refs.empForm.validate(rs => {
                    // rs 是校验结果
                    if (!rs) {
                        // 阻止提交
                        return false;
                    }
                    axios.post("emp.do", this.form, {
                        transformRequest: [function (data, headers) {
                            let arr = [];
                            for (let key in data) {
                                let value = data[key];
                                arr.push(key + "=" + value);
                            }
                            return arr.join("&");
                        }]
                    }).then(res => {
                        let rs = res.data;
                        let code = rs.code;
                        let msg = rs.msg;
                        if (code != 0) {
                            this.$message.error(msg);
                            return false;
                        }
                        // 将关闭
                        this.showed = false;
                        //重置属性
                        this.$refs.empForm.resetFields();
                        this.$refs.empForm.clearValidate();
                        // 成功则刷新表格
                       this.handlerSearch();
                    })
                    .catch(error => {
                        this.$message.error("数据添加失败!");
                    });
                });
            },
            handleDelete(emp) { //删除方法
                /*
                *  1. 删除二次确认框
                *  2. 获取业务员ID
                *  3. 将业务员ID 传递给后端
                *  4. 处理后端返回结果
                * */
                this.$confirm('确定要删除员工【' + emp.empName + '】吗?', '确认删除', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'danger'
                }).then(() => {
                    axios.get("emp.do?service=delete&empId=" + emp.empId)
                        .then(res => {
                            // 获取返回的数据
                            let rs = res.data;
                            // 将操作结果进行提示
                            this.$message({
                                type: 'info',
                                message: rs.msg
                            })
                            // 操作成功  刷新表格
                            if (rs.code == 0) {
                                //点击查询按钮
                                this.handlerSearch();
                            }
                        });
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });


            }
        },
        filters: { // 数据转发
            getDeptName(id) {
                //循环所有的部门 对比 ID  如果一致 则返回 部门名称
                for (let dept of that.depts) {
                    let deptId = dept.deptId;
                    if (deptId == id) {
                        return dept.deptName;
                    }
                }
                return '未知';
            }

        }
    });

</script>
</body>
</html>

5.监听器

5.1 ServletContext监听器

在Javaweb中监听器是只对Java的三大作用域进行监视的组件,监视3大作用域的生命周期和属性变化。

监视作用域对象的创建和销毁,监视作用域对象中的容器的数据的变化.JavaWeb分别提供2类接口:

  1. 生命周期监听接口

  2. 属性变化监听接口

生命周期监听接口:

ServletContextListener : 监听ServletContext的生命周期

HttpSessionListener : 监听HttpSession的生命周期

ServletRequestListener :监听每个HttpServletRequest对象的生命周期

在生命周期变化中,只有2个方法:创建和销毁

属性变化监听接口:

ServletContextAttributeListener : 监听ServletContext属性变化

HttpSessionAttributeListener : 监听HttpSession的属性变化

ServletRequestAttributeListener : 监听HttpServletRequest的属性变化

在属性变化中,只有3个方法:新增/删除/修改

5.1.1 生命周期监听器
5.1.1.1 ServletContextListener
ServletContext对象生命周期监听器,初始化方法,在应用程序启动时调用.因为ServletContext是全局作用域,全局有些只有一个.其中销毁方法在应用程序停止时调用.

5.1.1.2 HttpSessionListener
在创建Session对象时调用初始化方法,当session销毁时调用销毁方法

5.1.1.3 ServletRequestListener
在HttpServletRequst对象创建时调用初始化方法,service结束时,就会调用销毁方法.

5.1.2 属性变化监听器
当作用域的Map容器中,有新增的属性值时,触发新增的方法,如果有属性值被删除时,触发删除的方法,如果添加了一个属性值,覆盖了之前的属性值则触发修改方法.

5.2 应用
5.2.1 实现相关监听器接口

package com.powernode.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * ServletContextListener : 生命周期监听器
 */
public class AppListener implements ServletContextListener {

    /**
     * ServletContext 初始化完成的监听器
     * @param sce Information about the ServletContext that was initialized
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext 要初始化完成了!");
        ServletContext servletContext = sce.getServletContext();
        String value1 = servletContext.getInitParameter("key1");
        System.out.println(value1);
    }

    /**
     * ServletContext 要被销毁的监听器
     * @param sce Information about the ServletContext that was destroyed
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext 要被销毁了");
        System.out.println(sce.getServletContext());
    }
}

5.2.2 监听器注册

5.2.2.1 xml配置

<!-- 注册监听器 -->
<listener>
    <listener-class>com.powernode.listener.AppListener</listener-class>
</listener>
<!-- ServletContext 初始化参数 -->
<context-param>
    <param-name>key1</param-name>
    <param-value>value1</param-value>
</context-param>
<context-param>
    <param-name>key2</param-name>
    <param-value>value2</param-value>
</context-param>

5.2.2.2 注解

@WebListener
public class AppListener implements ServletContextListener {}

5.3 监听器场景

由于ServletContextListener在项目启动时就可以调用初始化方法,将一些耗时的操作进行全局化初始化,例如:初始化连接池.将比较大复杂对象初始化,可以使用ServletContextListener在项目启动时进行完成,具体的业务中只需要实际使用即可.

package com.powernode.listener;

import com.powernode.dao.UserDao;
import com.powernode.domain.User;
import com.powernode.service.UserService;
import com.powernode.service.impl.UserServiceImpl;
import com.powernode.util.DBUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * ServletContextListener : 生命周期监听器
 */
@WebListener
public class AppListener implements ServletContextListener, ServletContextAttributeListener {
    /**
     * 存储所有业务对象
     */
    final static Map<Class,Object> context = new ConcurrentHashMap<>();

    /**
     * ServletContext 初始化完成的监听器
     * @param sce Information about the ServletContext that was initialized
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        context.put(UserDao.class,new UserDao());
        context.put(UserService.class,new UserServiceImpl());

        System.out.println("ServletContext 要初始化完成了!");
        ServletContext servletContext = sce.getServletContext();
        String value1 = servletContext.getInitParameter("key1");
        System.out.println(value1);

        try {
            //关联.properties配置文件
            Properties prop = new Properties();
            InputStream ins = DBUtils.class.getClassLoader().getResourceAsStream("db.properties");
            prop.load(ins);
            //读取.properties配置文件的属性值
            DBUtils.driverClassName = prop.getProperty("jdbc.driverClassName");
            DBUtils.url = prop.getProperty("jdbc.url");
            DBUtils.username = prop.getProperty("jdbc.username");
            DBUtils.password = prop.getProperty("jdbc.password");
            Class.forName(DBUtils.driverClassName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Connection conn = DBUtils.getConn();
        DBUtils.close(conn);
    }

    /**
     * ServletContext 要被销毁的监听器
     * @param sce Information about the ServletContext that was destroyed
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext 要被销毁了");
        System.out.println(sce.getServletContext());
    }


    public static <T> T getInstance(Class<T> cls){
        return (T) context.get(cls);
    }

    //===============================以下是属性监听==========================================


    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("新增了属性值时  调用");
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("删除了属性值时  调用");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("修改了属性值时  调用");

    }
} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1391274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式学习-网络编程-Day3

思维导图 多进程并发服务器通信模型如下 void handler(int signo) {while(waitpid()>0); //以非阻塞配合信号完成僵尸进程的回收 } int main() {//将信号与信号处理函数绑定signal(SIGCHLD, handler);socket(); //创建用于连接的套接字bind(); //绑定IP…

Python和Java代码实现:切线法求解一维最优化问题

Python和Java代码实现&#xff1a;切线法求解一维最优化问题 代码实现Python代码Java代码 求解实例 根据概念查询&#xff0c;切线法定义如下&#xff1a; 切线法&#xff08;Tangent Method&#xff09;是一种用于求解非线性方程的数值方法。它也被称为牛顿法&#xff08;Newt…

C++ 程序文档生成器(doxygen)使用说明

程序文档&#xff0c;是每个程序员必看文档&#xff0c;在日常业务开发中&#xff0c;难免会封装一些组件。没有很好的组件文档&#xff0c;再好的组件都是废物&#xff0c;。因此大型业务中&#xff0c;文档和思维导图&#xff0c;两个都是必备&#xff01; 一、注释风格 …

IPv6隧道--GRE隧道

GRE隧道 通用路由封装协议GRE(Generic Routing Encapsulation)可以对某些网络层协议(如IPX、ATM、IPv6、AppleTalk等)的数据报文进行封装,使这些被封装的数据报文能够在另一个网络层协议(如IPv4)中传输。 GRE提供了将一种协议的报文封装在另一种协议报文中的机制,是一…

各种设备上恢复已删除的文件和文件夹的数据恢复软件清单

最好的数据恢复软件可以简单轻松地恢复计算机、移动设备或存储介质上已删除的文件和文件夹。 询问任何经历过数据丢失的人这是否是一种有趣的经历&#xff0c;他们会告诉您数据丢失&#xff0c;无论是由于硬件或软件故障、意外删除还是网络犯罪&#xff0c;都会带来极大的压力…

美国 SEC 批准比特币现货 ETF 上市,SEC 告诉我们的风险包含哪些?

撰文&#xff1a;Will 阿望 查看原文&#xff1a;美国 SEC 批准比特币现货 ETF 上市&#xff0c;SEC 告诉我们的风险包含哪些&#xff1f; 历经十年的 BTC ETF 艰辛审批之路终于迎来了胜利的曙光&#xff0c;2024 年 1 月 11 日凌晨 4 时&#xff0c;美国证监会&#xff08;S…

AIGC实战——像素卷积神经网络(PixelCNN)

AIGC实战——像素卷积神经网络 0. 前言1. PixelCNN 工作原理1.1 掩码卷积层 1.2 残差块2. 训练 PixelCNN3. PixelCNN 分析4. 使用混合分布改进 PixelCNN小结系列链接 0. 前言 像素卷积神经网络 (Pixel Convolutional Neural Network, PixelCNN) 是于 2016 年提出的一种图像生成…

礼贺新春,徐坊大曲新品【中国红】

梁山徐坊大曲新推出中国风礼盒&#xff0c;以中国红为主题&#xff0c;为即将到来的新春佳节增添了浓厚的节日气氛。为您呈现一场视觉与味觉的盛宴。从礼盒的颜色到图案设计&#xff0c;无不体现出中国红的热情与活力&#xff0c;象征着吉祥、喜庆与团圆。梁山徐坊大曲&#xf…

ubuntu qt 运行命令行

文章目录 1.C实现2.python实现 1.C实现 下面是封装好的C头文件&#xff0c;直接调用run_cmd_fun()即可。 #ifndef GET_CMD_H #define GET_CMD_H#endif // GET_CMD_H #include <iostream> #include<QString> using namespace std;//system("gnome-terminal -…

USB8814动态信号采集卡——声音振动类信号处理的理想之选!

背景介绍&#xff1a; 科技的发展在一定程度上依赖于对信号的处理&#xff0c;信号处理技术的先进性在很大程度上决定了科技发展的速度和方向。数字信号处理技术的崛起&#xff0c;彻底改变了传统的信息与信号处理方式&#xff0c;使得数据采集这一前期工作在数字系统中发挥着…

FTP文件传输协议 、多种方式安装yum仓库

一、网络文件共享服务 1.存储类型分三种&#xff1a; 直连式存储&#xff1a;Direct-Attached Storage&#xff0c;简称DAS 存储区域网络&#xff1a;Storage Area Network&#xff0c;简称SAN&#xff08;可以使用空间&#xff0c;管理也是你来管理&#xff09; 网络附加存储…

ImageNet Classification with Deep Convolutional 论文笔记

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

Leetcode23-数组能形成多少数对(2341)

1、题目 给你一个下标从 0 开始的整数数组 nums 。在一步操作中&#xff0c;你可以执行以下步骤&#xff1a; 从 nums 选出 两个 相等的 整数 从 nums 中移除这两个整数&#xff0c;形成一个 数对 请你在 nums 上多次执行此操作直到无法继续执行。 返回一个下标从 0 开始、长…

SpringMVC参数接收见解4

# 4.参数接收Springmvc中&#xff0c;接收页面提交的数据是通过方法形参来接收&#xff1a; 处理器适配器调用springmvc使用反射将前端提交的参数传递给controller方法的形参 springmvc接收的参数都是String类型&#xff0c;所以spirngmvc提供了很多converter&#xff08;转换…

第二证券:大盘探底回升走出底部还看成交量配合

持续震动数日后&#xff0c;大盘再现探底上升走势。 上证指数周二小幅低开后窄幅震动&#xff0c;午后快速回落改写本轮回调新低后&#xff0c;有资金开始出手介入&#xff0c;尾盘指数翻红。深证成指同样是在午后呈现探底上升走势&#xff0c;最终重回5日均线上方。截至收盘&…

mysql 下载和安装和修改MYSQL8.0 数据库存储文件的路径

一、第一步:下载步骤 下载链接&#xff1a;MySQL :: Download MySQL Installer 选择版本8.0.35&#xff0c;社区版&#xff0c; 点击 Download 下载 安装包 二、第二步:安装步骤 添加环境变量&#xff0c;C:\Program Files\MySQL\MySQL Server 8.0\bin 可以点开MySQL 8.0 Co…

如何用AI提高论文阅读效率?

已经2024年了&#xff0c;该出现一个写论文解读AI Agent了。 大家肯定也在经常刷论文吧。 但真正尝试过用GPT去刷论文、写论文解读的小伙伴&#xff0c;一定深有体验——费劲。其他agents也没有能搞定的&#xff0c;今天我发现了一个超级厉害的写论文解读的agent &#xff0c…

HNU-模式识别-作业2-面向应用分类系统

模式识别-作业2 计科210X 甘晴void 202108010XXX 【具体实现思路是按照去年数学建模国赛题来做的&#xff0c;就放个思路&#xff0c;完整不放全了】 题目&#xff1a; 查阅文献资料&#xff0c;构建一个面向应用的分类系统。 要求&#xff1a; 至少3页A4纸&#xff0c;文…

机器人制作开源方案 | AI校园服务机器人

作者&#xff1a;李强、李振宁、毛维雷、李文文、张奥 单位&#xff1a;山西能源学院 指导老师&#xff1a;姚志广、程晟 在这个科技飞速发展的时代&#xff0c;在工业智造、人工智能的飞速发展中&#xff0c;出现了越来越多的智能化机械装置&#xff0c;也有许多创新类的比赛…

STM32F103标准外设库—— 新建工程与库函数(四)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…