8_文件上传与下载

一. 引言

1.1 场景

  • 在项目中, 文件的上传和下载是常见的功能, 很多程序或者软件中都经常使用到文件的上传和下载
  • 邮箱中有附件的上传和下载
  • OA办公系统中有附件材料的上传

二. 文件上传

2.1 概念

  • 当用户在前端页面点击文件上传后, 用户上传的文件数据提交给服务器端, 实现保存

2.2 文件上传实现步骤

2.2.1 提交方式
  • 提供form表单, method必须是post, 因为post请求无数据限制
<form method="post">
    
</form>
2.2.2 提交数据格式
  • 表单的enctype属性值必须为multipart/form-data
  • 以多段的形式进行拼接提交, 以二进制流的方式来处理表单数据, 会把指定的文件内容封装进请求参数中
<form enctype="multipart/form-data" method="post">
    
</form>
2.2.3 提供组件
  • 提供file表单组件, 提供给用户上传文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传页面</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
        <p>用户名:
            <input type="text" name="username">
        </p>
        <p>密码:&nbsp;&nbsp;&nbsp;
            <input type="file" name="file1">
        </p>
        <p>
            <input type="submit" value="上传">
        </p>
    </form>
</body>
</html>

2.2.4 Controller编写
  • 在Servlet 3.0 及其以上版本的容器中进行服务器端文件上传的编程, 是围绕着注解类型MultipartConfigjavax.servlet.http.Part 接口进行的, 处理已上传文件的Servlet必须以@MultipartConfig进行注解
package com.dz.servlet;

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;

@WebServlet(name = "uploadController",value = "/upload")
@MultipartConfig(maxFileSize = 1024*1024*100,maxRequestSize = 1024*1024*200)
public class uploadController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //实现文件上传

        //1. 设置乱码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        //2. 获取请求的数据
        String username = request.getParameter("username");
        Part part = request.getPart("file1");

        //3. 获取上传文件的路径(将上传的文件存到此路径下)  真实路径
        String uploadPath = request.getServletContext().getRealPath("/WEB-INF/upload");
        File file = new File(uploadPath);
        if (!file.exists()) {
            file.mkdirs();//新建文件夹
        }

        //4. 文件上传
        part.write(uploadPath+"\"+part.getSubmittedFileName());

        //5. 响应客户端 上传成功
        response.getWriter().println(part.getSubmittedFileName()+"上传成功!");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

2.3 文件上传细节注意

  • 上述代码虽然可以成功将文件上传到服务器的指定目录当中, 但是文件上传功能有许多需要注意的小细节问题
2.3.1 安全问题
  • 为保证服务器安全, 上传的文件应该放在外界无法直接访问的目录下, 比如放于WEB-INF目录下
String uploadPath = request.getServletContext().getRealPath("/WEB-INF/upload");
2.3.2 文件覆盖
  • 当上传重名的文件时, 为防止文件覆盖的现象发生, 要为上传文件产生一个唯一的文件名
package com.dz.utils;

import java.util.UUID;

public class UploadUtils {
    //使用UUID生成唯一标识码, 并拼接上图片的名称
    public static String newFileName(String filename) {
        return UUID.randomUUID().toString().replaceAll("-","") + "_" + filename;
    }
}

//4. 文件上传
// 生成唯一文件名
//String oldName = part.getSubmittedFileName();
//String newName = UploadUtils.newFileName(oldName);
//part.write(uploadPath+"\"+newName);
2.3.3 散列存储
  • 为防止一个目录下面出现太多文件, 要使用hash算法生成二级, 三级目录, 散列存储上传的文件
public class UploadUtils {
    //使用UUID生成唯一标识码, 并拼接上图片的名称
    public static String newFileName(String filename) {
        return UUID.randomUUID().toString().replaceAll("-","") + "_" + filename;
    }

    //生成二三级目录,进行散列存储
    public static String newFilePath(String basePath, String fileName) {
        int hashcode = fileName.hashCode();
        int path1 = hashcode & 15;//二级目录  与运算 0~15
        int path2 = (hashcode>>4) & 15;//三级目录   与运算 0~15
        String newPath = basePath + "\" + path1 + "\" + path2;//一二三级目录拼接在一起
        File file = new File(newPath);//创建文件夹对象
        if (!file.exists()) {//不存在则创建
            file.mkdirs();
        }
        return newPath;//返回新路径
    }
}
//4. 文件上传
// 生成唯一文件名
//String oldName = part.getSubmittedFileName();
//String newName = UploadUtils.newFileName(oldName);
//生成二级三级目录, 实现散列存储
//String newPath = UploadUtils.newFilePath(uploadPath, oldName);
//part.write(newPath+"\"+newName);

2.3.4 文件类型限制
  • 要限制上传文件的类型, 在收到上传文件名时, 判断后缀名是否合法
//创建一个集合存放允许上传的文件类型(后缀名)
//判断集合中是否包含上传文件的后缀名
List<String> nameList = new ArrayList<>();
nameList.add(".png");
nameList.add(".jpg");
nameList.add(".jpeg");

String extName = oldName.substring(oldName.lastIndexOf("."));//从每个上传文件名中的最后出现点的位置开始截取, 也就是截取 后缀名(包括.)
if (!nameList.contains(extName)) {
    response.getWriter().println(oldName + "的文件类型不支持上传!");
    return;
}

2.4 多文件上传

package com.dz.servlet;

import com.dz.utils.UploadUtils;

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

/**
 * @belongsProject: FileUpload
 * @belongsPackage: ${PACKAGE_NAME}
 * @author: zheng
 * @description: ${Description}
 * @createTime: 2021-04-17 18:24
 * @since v1.0.0
 */

@WebServlet(name = "MoreUploadController",value = "/moreUpload")
@MultipartConfig(maxFileSize = 1024*1024*100, maxRequestSize = 1024*1024*200)
public class MoreUploadController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //实现多文件上传
        //1. 设置乱码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        //2. 获取上传文件的保存路径, 将上传的文件存放于WEB-INF目录下, 不允许外界直接访问, 保证上传文件的安全
        String basePath = request.getServletContext().getRealPath("/WEB-INF/upload");
        File file = new File(basePath);
        if (!file.exists()) {
            file.mkdirs();//WEB-INF下新建upload文件夹
        }
        //3. 获得表单提交的所有数据,放在集合里
        Collection<Part> parts = request.getParts();

        //4. 遍历集合
        if (parts != null) {
            for (Part part : parts) {
                //4.1 获取上传文件的文件名
                String fileName = part.getSubmittedFileName();
                if (fileName != null) {//文件名不为空后我们认为是 文件数据
                    //二次判断(看文件名是否为空字符串),避免用户传入空数据
                    if (fileName.trim().equals("")) {
                        continue;
                    }
                    //4.1.1 调用上传工具类中的newFileName方法生成新的唯一文件名(使用UUID生成唯一标识码)
                    String newName = UploadUtils.newFileName(fileName);
                    //4.1.2 创建集合, 里面存放文件的后缀名,如果所上传文件的后缀名不在此集合内, 则不允许上传
                    List<String> fileNameList = new ArrayList<>();
                    fileNameList.add(".jpg");
                    fileNameList.add(".png");
                    fileNameList.add(".jpeg");
                    //截取文件后缀名(包括.)  从每个上传文件名中的最后出现点的位置开始截取
                    String extName = fileName.substring(fileName.lastIndexOf("."));
                    if (!fileNameList.contains(extName)) {
                        response.getWriter().println(fileName + "的文件类型不支持上传!");
                        return;
                    }
                    //4.1.3 获取分散后的路径,调用上传工具类中的newFilePath方法生成二级三级目录, 实现散列存储(文件名hashcode的与运算)
                    String newPath = UploadUtils.newFilePath(basePath,fileName);
                    //4.1.4 把新文件路径和新文件名进行拼接, 然后写入文件数据
                    part.write(newPath + "\" + newName);
                    //4.1.5 响应给客户端结果
                    response.getWriter().println(part.getSubmittedFileName()+"上传成功!");
                }else{//没有获取到文件名则证明是 普通表单
                    //获取普通表单数据
                    String username = request.getParameter("username");
                    System.out.println(username);
                }
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

三. 文件下载

3.1 概念

  • 我们要将Web应用系统中的文件资源提供给用户进行下载, 首先我们要有一个页面列出上传文件目录下的所有文件, 当用户点击文件下载超链接时就进行下载操作

3.2 获取文件列表

3.2.1 DownLoadUtils
package com.dz.utils;

import java.io.File;
import java.util.HashMap;

public class DownLoadUtils {
    public static void getFileList(File file, HashMap<String,String> fileMap) {
        //获取当前文件对象下的所有内容(文件,文件夹)
        File[] files = file.listFiles();
        //如果数组不为空, 证明有文件或文件夹
        if (files != null) {
            //每次拿到文件对象(文件,文件夹)
            for (File file1 : files) {
                //如果是文件夹
                if (file1.isDirectory()) {
                    //则递归调用getFileList方法
                    getFileList(file1,fileMap);
                }else {
                    //获得文件名称
                    String fileName = file1.getName();
                    //获取第一个_的下标
                    int index = fileName.indexOf("_");
                    //获取源文件名称(去掉UUID_后的文件名)
                    String realName = fileName.substring(index + 1);
                    //UUID 键   源文件名 值
                    fileMap.put(fileName,realName);
                }
            }
        }
    }
}

3.2.2 FileListController
package com.dz.servlet;

import com.dz.utils.DownLoadUtils;

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.File;
import java.io.IOException;
import java.util.HashMap;

@WebServlet(name = "FileListController",value = "/fileList")
public class FileListController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 解决乱码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //2. 获取文件列表
        //集合,map  key=UUID  value=源文件名称
        HashMap<String,String> fileMap = new HashMap<>();
        String basePath = request.getServletContext().getRealPath("/WEB-INF/upload");
        DownLoadUtils.getFileList(new File(basePath),fileMap);

        //3. 转发 将fileMap存储到request作用域中并转发到fileList.jsp页面
        request.setAttribute("fileMap",fileMap);
        request.getRequestDispatcher("/fileList.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

3.3 下载

3.3.1 fileList.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>文件下载页面</title>
</head>
<body>
    <table>
        <tr>
            <th>文件名</th>
            <th>操作</th>
        </tr>
        <c:forEach var="entry" items="${fileMap}" >
            <tr>
                <td>${entry.value}</td>
                <td><a href="${pageContext.request.contextPath}/downLoad?filename=${entry.key}">下载</a></td>
            </tr>
        </c:forEach>

    </table>
</body>
</html>

3.3.2 DownLoadController
package com.dz.servlet;

import com.dz.utils.UploadUtils;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

@WebServlet(name = "DownLoadController",value = "/downLoad")
public class DownLoadController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");//处理用户名的乱码
        response.setContentType("text/html;charset=UTF-8");
        String basePath = request.getServletContext().getRealPath("/WEB-INF/upload");
        //1. 获取UUID 文件名
        String uuidFilename = request.getParameter("filename");
        //通过_拆分 UUID和源文件名称,_后是源文件名称
        String filename = uuidFilename.split("_")[1];
        //通过上传工具类, 使用源文件名称获得散列存储的路径, 就是要下载的路径
        String downLoadPath = UploadUtils.newFilePath(basePath, filename);
        //设置响应头, 告诉浏览器响应的文件类型和如何处理该文件, 附件下载
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename,"UTF-8"));
        
        //2. 使用流读取
        FileInputStream fis = new FileInputStream(downLoadPath + "\" + uuidFilename);
        ServletOutputStream sos = response.getOutputStream();
        byte[] buffer = new byte[1024*1024*100];
        int len = 0;
        while ((len=fis.read(buffer)) != -1) {
            sos.write(buffer,0,len);
        }
        
        //3. 关闭流
        sos.close();
        fis.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

四. EMS综合项目

4.1 项目需求

  • 将提供好的HTML页面, 修改为JSP
  • 实现管理员登陆功能, 并应用权限验证
  • 对员工实现增删改查
  • 查询员工使用分页查询, 并提供首页, 尾页, 上一页, 下一页

4.2 项目搭建

4.2.1 项目目录搭建
  • com.dz.ems.utils 工具包
  • com.dz.ems.entity 实例类
  • com.dz.ems..dao 数据访问接口
  • com.dz.ems.dao.impl 数据访问实现类
  • com.dz.ems.service 业务逻辑接口
  • com.dz.ems..service.impl 业务逻辑实现类
  • com.dz.ems.controller 控制器
  • com.dz.ems.filter 过滤器
4.2.2 项目资源引入
  • 创建EMS项目, 在web的WEB-IF下创建lib目录并导入相关jar文件
    • commons-dbutils-1.7.jar
    • druid-1.1.5.jar
    • jstl.jar
    • mysql-connector-java-5.1.25-bin.jar
    • standard.jar
    • ValidateCode.jar
4.2.3 数据库创建
#创建ems数据库
CREATE DATABASE ems;
#使用ems数据库
USE ems;
#创建员工表
CREATE TABLE emp(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20) NOT NULL,
	salary DOUBLE NOT NULL,
	age INT NOT NULL
)CHARSET=utf8;
#创建管理员表
CREATE TABLE empManager(
	username VARCHAR(20) NOT NULL,
	PASSWORD VARCHAR(20) NOT NULL
)CHARSET=utf8;
#请自行插入多条数据
INSERT INTO emp(NAME,salary,age) VALUES('DZ1',1000,18);
INSERT INTO empManager(username,PASSWORD) VALUES('admin','admin');
4.3.4 database.properties
#<!-- 连接设置 -->
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ems?useUnicode=true&characterEncoding=UTF-8
username=root
password=root
#<!-- 初始化连接 -->
initialSize=10
#<!-- 最大连接数量 -->
maxActive=50
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒 -->
maxWait=5000

4.3 项目开发

4.3.1 Dbutils工具类
public class DbUtils {
    private static DruidDataSource ds;
    private static final ThreadLocal<Connection> THREAD_LOCAL = new ThreadLocal<>();

    static {
        Properties properties = new Properties();
        InputStream inputStream = DbUtils.class.getResourceAsStream("/database.properties");
        try {
            properties.load(inputStream);
            ds = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection(){
        Connection conn = THREAD_LOCAL.get();
        try {
            if (conn == null) {
                conn = ds.getConnection();
                THREAD_LOCAL.set(conn);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn;
    }

    public static void begin() {
        Connection conn = null;
        try {
            conn = getConnection();
            conn.setAutoCommit(false);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    public static void commit() {
        Connection conn = null;
        try {
            conn = getConnection();
            conn.commit();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            closeAll(conn,null,null);
        }
    }

    public static void rollback() {
        Connection conn = null;
        try {
            conn = getConnection();
            conn.rollback();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            closeAll(conn,null,null);
        }
    }

    public static void closeAll(Connection conn, Statement statement, ResultSet resultSet) {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (conn != null) {
                conn.close();
                THREAD_LOCAL.remove();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}
4.3.2 EmpManager实体类
public class EmpManager {
    private String username;
    private String password;


    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;
    }

    public EmpManager(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public EmpManager() {
    }
}
4.3.3 Emp实体类
public class Emp {
    private int id;
    private String name;
    private double salary;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Emp(int id, String name, double salary, int age) {
        this.id = id;
        this.name = name;
        this.salary = salary;
        this.age = age;
    }

    public Emp(String name, double salary, int age) {
        this.name = name;
        this.salary = salary;
        this.age = age;
    }

    public Emp() {
    }
}
4.3.4 Page实体类
public class Page {
    private Integer pageIndex;//页码
    private Integer pageSize;//单页数据量
    private Integer totalCounts;//数据总量
    private Integer totalPages;//总页数
    private Integer beginRow;//起始行

    public Page(Integer pageIndex, Integer pageSize) {
        this.pageIndex = pageIndex;
        this.pageSize = pageSize;
        this.setBeginRow((pageIndex-1) * pageSize);
    }

    public Page(Integer pageIndex) {
        this(pageIndex,5);
    }

    public Integer getPageIndex() {
        return pageIndex;
    }

    public void setPageIndex(Integer pageIndex) {
        this.pageIndex = pageIndex;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getTotalCounts() {
        return totalCounts;
    }

    public void setTotalCounts(Integer totalCounts) {
        this.totalCounts = totalCounts;
        this.setTotalPages(totalCounts % pageSize == 0?totalCounts/pageSize:totalCounts/pageSize+1);
    }

    public Integer getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(Integer totalPages) {
        this.totalPages = totalPages;
    }

    public Integer getBeginRow() {
        return beginRow;
    }

    public void setBeginRow(Integer beginRow) {
        this.beginRow = beginRow;
    }
}
4.3.5 EmpManagerDao
public interface EmpManagerDao {
    EmpManager select(String username);
}
4.3.6 EmpDao
public interface EmpDao {
    int insert(Emp emp);
    int delete(int id);
    int update(Emp emp);
    Emp select(int id);
    //分页查询所有
    List<Emp> selectAll(Page page);
    //查询数据总行数
    long selectCounts();
}
4.3.7 EmpManagerDaoImpl
public class EmpManagerDaoImpl implements EmpManagerDao {
    private QueryRunner queryRunner = new QueryRunner();
    @Override
    public EmpManager select(String username) {
        try {
            EmpManager empManager = queryRunner.query(DbUtils.getConnection(), "select * from empManager where username=?", new BeanHandler<EmpManager>(EmpManager.class), username);

            return empManager;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        return null;
    }
}
4.3.8 EmpDaoImpl
package com.dz.dao.impl;

import com.dz.dao.EmpDao;
import com.dz.entity.Emp;
import com.dz.entity.Page;
import com.dz.utils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
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 EmpDaoImpl implements EmpDao {
    private QueryRunner queryRunner = new QueryRunner();
    @Override
    public int insert(Emp emp) {
        try {
            return queryRunner.update(DbUtils.getConnection(), "insert into emp(name,salary,age) values(?,?,?)", emp.getName(), emp.getSalary(), emp.getAge());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return 0;
    }

    @Override
    public int delete(int id) {
        try {
            return queryRunner.update(DbUtils.getConnection(),"delete from emp where id=?",id);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return 0;
    }

    @Override
    public int update(Emp emp) {
        try {
            return queryRunner.update(DbUtils.getConnection(),"update emp set name=?,salary=?,age=? where id=?",emp.getName(),emp.getSalary(),emp.getAge(),emp.getId());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return 0;
    }

    @Override
    public Emp select(int id) {
        try {
            return queryRunner.query(DbUtils.getConnection(),"select * from emp where id=?",new BeanHandler<Emp>(Emp.class),id);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Emp> selectAll(Page page) {
        try {
            return queryRunner.query(DbUtils.getConnection(),"select * from emp limit ?,?",new BeanListHandler<Emp>(Emp.class),page.getBeginRow(),page.getPageSize());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

    @Override
    public long selectCounts() {
        try {
            return queryRunner.query(DbUtils.getConnection(),"select count(*) from emp",new ScalarHandler<>());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return 0;
    }
}

4.3.9 EmpManagerService
public interface EmpManagerService {
    EmpManager login(String username,String password);
}
4.3.10 EmpService
public interface EmpService {
    int addEmp(Emp emp);
    int removeEmp(int id);
    int modifyEmp(Emp emp);
    Emp showEmp(int id);
    List<Emp> showAllEmp(Page page);
}
4.3.11 EmpManagerServiceImpl
public class EmpManagerServiceImpl implements EmpManagerService {
    private EmpManagerDao empManagerDao = new EmpManagerDaoImpl();
    @Override
    public EmpManager login(String username, String password) {
        EmpManager empManager = null;
        try {
            DbUtils.begin();
            EmpManager temp = empManagerDao.select(username);
            if (temp != null) {
                if (temp.getPassword().equals(password)) {
                    empManager = temp;
                }
            }
            DbUtils.commit();
        } catch (Exception e) {
            DbUtils.rollback();
            e.printStackTrace();
        }

        return empManager;
    }
}
4.3.12 EmpServiceImpl
public class EmpServiceImpl implements EmpService {
    private EmpDao empDao = new EmpDaoImpl();
    @Override
    public int addEmp(Emp emp) {
        int result = 0;
        try {
            DbUtils.begin();
            result = empDao.insert(emp);
            DbUtils.commit();
        } catch (Exception e) {
            DbUtils.rollback();
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public int removeEmp(int id) {
        int result = 0;
        try {
            DbUtils.begin();
            result = empDao.delete(id);
            DbUtils.commit();
        } catch (Exception e) {
            DbUtils.rollback();
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public int modifyEmp(Emp emp) {
        int result = 0;
        try {
            DbUtils.begin();
            result = empDao.update(emp);
            DbUtils.commit();
        } catch (Exception e) {
            DbUtils.rollback();
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public Emp showEmp(int id) {
        Emp emp = null;
        try {
            DbUtils.begin();
            emp = empDao.select(id);
            DbUtils.commit();
        } catch (Exception e) {
            DbUtils.rollback();
            e.printStackTrace();
        }
        return emp;
    }

    @Override
    public List<Emp> showAllEmp(Page page) {
        List<Emp> empList = new ArrayList<>();
        try {
            DbUtils.begin();
            long counts = empDao.selectCounts();
            page.setTotalCounts((int)counts);//赋值总条数,计算总页数
            empList = empDao.selectAll(page);
            DbUtils.commit();
        } catch (Exception e) {
            DbUtils.rollback();
            e.printStackTrace();
        }
        return empList;
    }
}
4.3.13 login.jsp
<%@ page import="java.util.Date" %>
<%@ page import="java.time.LocalDate" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>登陆页面</title>
    <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/style.css" />
</head>
<body>
<div id="wrap">
    <div id="top_content">
        <div id="header">
            <div id="rightheader">
                <p>
                    <%=LocalDate.now()%> <br />
                </p>
            </div>
            <div id="topheader">
                <h1 id="title">
                    <a href="#">管理员登陆</a>
                </h1>
            </div>
            <div id="navigation"></div>
        </div>
        <div id="content">
            <p id="whereami"></p>
            <h1>login</h1>
            <form action="${pageContext.request.contextPath}/manager/empManagerLogin" method="post">
                <table cellpadding="0" cellspacing="0" border="0"
                       class="form_table">
                    <tr>
                        <td valign="middle" align="right">用户名:</td>
                        <td valign="middle" align="left"><input type="text"
                                                                class="inputgri" name="username" /></td>
                    </tr>
                    <tr>
                        <td valign="middle" align="right">密码:</td>
                        <td valign="middle" align="left"><input type="password"
                                                                class="inputgri" name="password" /></td>
                    </tr>
                    <tr>
                        <td valign="middle" align="right">验证码:</td>
                        <td valign="middle" align="left"><input type="text"
                                                                class="inputgri" name="validateCode" /><img src="${pageContext.request.contextPath}/createCode"
                                                                                                            alt="验证码"></td>
                    </tr>
                </table>
                <p>
                    <input type="submit" class="button" value="Submit &raquo;" />
                </p>
            </form>
        </div>
    </div>
    <div id="footer">
        <div id="footer_bg">EMS/login.jsp</div>
    </div>
</div>
</body>
</html>

4.3.14 empList.jsp
<%@ page import="java.time.LocalDate" %>
<%@ 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" type="text/css" href="${pageContext.request.contextPath}/css/style.css" />
</head>
<body>
<div id="wrap">
    <div id="top_content">
        <div id="header">
            <div id="rightheader">
                <p>
                    <%=LocalDate.now()%>
                    <br />
                </p>
            </div>
            <div id="topheader">
                <h1 id="title">
                    <a href="#">员工列表</a>
                </h1>
            </div>
            <div id="navigation">
            </div>
        </div>
        <div id="content">
            <p id="whereami">
            </p>
            <h1>
                ${empManager.username},Welcome!
            </h1>
            <table class="table">
                <tr class="table_header">
                    <td>
                        ID
                    </td>
                    <td>
                        Name
                    </td>
                    <td>
                        Salary
                    </td>
                    <td>
                        Age
                    </td>
                    <td>
                        Operation
                    </td>
                </tr>
                <%--隔行变色--%>
                <c:forEach var="emp" items="${empList}" varStatus="e">
                    <c:if test="${e.count % 2 != 0}">
                        <tr class="row1">
                    </c:if>
                    <c:if test="${e.count % 2 == 0}">
                        <tr class="row2">
                    </c:if>

                        <td>
                            ${emp.id}
                        </td>
                        <td>
                            ${emp.name}
                        </td>
                        <td>
                            ${emp.salary}
                        </td>
                        <td>
                            ${emp.age}
                        </td>
                        <td>
                            <a href="<c:url context='${pageContext.request.contextPath}' value='/manager/safe/removeEmp?id=${emp.id}'/> ">delete emp</a>&nbsp;<a href="<c:url context='${pageContext.request.contextPath}' value='/manager/safe/showEmp?id=${emp.id}'/> ">update emp</a>
                        </td>
                    </tr>
                </c:forEach>
                <tr>
                    <td colspan="5">
                        <a href="<c:url context='${pageContext.request.contextPath}' value='/manager/safe/showAllEmp?pageIndex=1'/> ">首页</a>
                        <c:if test="${page.pageIndex > 1}">
                            <a href="<c:url context='${pageContext.request.contextPath}' value='/manager/safe/showAllEmp?pageIndex=${page.pageIndex-1}'/> ">上一页</a>
                        </c:if>
                        <c:if test="${page.pageIndex == 1}">
                            <a>上一页</a>
                        </c:if>
                        <c:if test="${page.pageIndex < page.totalPages}">
                            <a href="<c:url context='${pageContext.request.contextPath}' value='/manager/safe/showAllEmp?pageIndex=${page.pageIndex+1}'/> ">下一页</a>
                        </c:if>
                        <c:if test="${page.pageIndex == page.totalPages}">
                            <a>下一页</a>
                        </c:if>
                        <a href="<c:url context='${pageContext.request.contextPath}' value='/manager/safe/showAllEmp?pageIndex=${page.totalPages}'/> ">尾页</a>
                    </td>
                </tr>
            </table>
            <p>
                <input type="button" class="button" value="Add Employee" onclick="location='${pageContext.request.contextPath}/manager/safe/addEmp.jsp'"/>
            </p>
        </div>
    </div>
    <div id="footer">
        <div id="footer_bg">
            empList.jsp
        </div>
    </div>
</div>
</body>
</html>

4.3.15 addEmp.jsp
<%@ page import="java.time.LocalDate" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>新增员工界面</title>
    <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/style.css" />
</head>
<body>
<div id="wrap">
    <div id="top_content">
        <div id="header">
            <div id="rightheader">
                <p>
                    <%=LocalDate.now()%>
                    <br />
                </p>
            </div>
            <div id="topheader">
                <h1 id="title">
                    <a href="#">新增员工</a>
                </h1>
            </div>
            <div id="navigation">
            </div>
        </div>
        <div id="content">
            <p id="whereami">
            </p>
            <h1>
                add Emp info:
            </h1>
            <form action="${pageContext.request.contextPath}/manager/safe/addEmp" method="post">
                <table cellpadding="0" cellspacing="0" border="0"
                       class="form_table">
                    <tr>
                        <td valign="middle" align="right">
                            name:
                        </td>
                        <td valign="middle" align="left">
                            <input type="text" class="inputgri" name="name" />
                        </td>
                    </tr>
                    <tr>
                        <td valign="middle" align="right">
                            salary:
                        </td>
                        <td valign="middle" align="left">
                            <input type="text" class="inputgri" name="salary" />
                        </td>
                    </tr>
                    <tr>
                        <td valign="middle" align="right">
                            age:
                        </td>
                        <td valign="middle" align="left">
                            <input type="text" class="inputgri" name="age" />
                        </td>
                    </tr>
                </table>
                <p>
                    <input type="submit" class="button" value="Confirm" />
                </p>
            </form>
        </div>
    </div>
    <div id="footer">
        <div id="footer_bg">
            addEmp.jsp
        </div>
    </div>
</div>
</body>
</html>

4.3.16 EmpManagerLoginController
@WebServlet(name = "EmpManagerLoginController",value = "/manager/empManagerLogin")
public class EmpManagerLoginController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String inputVCode = request.getParameter("validateCode");
        String code = (String) request.getSession().getAttribute("code");

        if (!inputVCode.isEmpty() && inputVCode.equalsIgnoreCase(code)) {
            EmpManagerService empManagerService = new EmpManagerServiceImpl();
            EmpManager empManager = empManagerService.login(username, password);
            if (empManager != null) {
                HttpSession session = request.getSession();
                session.setAttribute("empManager",empManager);

                response.sendRedirect(request.getContextPath() + "/manager/safe/showAllEmp");
            }else {
                response.sendRedirect(request.getContextPath() + "/login.jsp");
            }
        }else {
            response.sendRedirect(request.getContextPath() + "/login.jsp");
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
4.3.17 CreateCodeController
@WebServlet(name = "CreateCodeController",value = "/createCode")
public class CreateCodeController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ValidateCode validateCode = new ValidateCode(200,30,4,10);
        String code = validateCode.getCode();
        HttpSession session = request.getSession();
        session.setAttribute("code",code);

        validateCode.write(response.getOutputStream());

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
4.3.18 ShowAllEmpController
@WebServlet(name = "ShowAllEmpController",value = "/manager/safe/showAllEmp")
public class ShowAllEmpController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String pageIndex = request.getParameter("pageIndex");
        if (pageIndex == null) {
            pageIndex = "1";
        }
        Page page = new Page(Integer.valueOf(pageIndex));

        EmpService empService = new EmpServiceImpl();
        List<Emp> empList = empService.showAllEmp(page);
        if (empList != null) {
            request.setAttribute("page",page);
            request.setAttribute("empList",empList);
            request.getRequestDispatcher("/manager/safe/empList.jsp").forward(request, response);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
4.3.19 AddEmpController
@WebServlet(name = "AddEmpController",value = "/manager/safe/addEmp")
public class AddEmpController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        Double salary = Double.valueOf(request.getParameter("salary"));
        Integer age = Integer.valueOf(request.getParameter("age"));

        Emp emp = new Emp(name,salary,age);

        EmpService empService = new EmpServiceImpl();
        empService.addEmp(emp);

        response.sendRedirect(request.getContextPath()+"/manager/safe/showAllEmp");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
4.3.20 RemoveEmpController
@WebServlet(name = "RemoveEmpController",value = "/manager/safe/removeEmp")
public class RemoveEmpController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer id = Integer.valueOf(request.getParameter("id"));

        EmpService empService = new EmpServiceImpl();
        empService.removeEmp(id);
        response.sendRedirect(request.getContextPath() + "/manager/safe/showAllEmp");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
4.3.21 ShowEmpController
@WebServlet(name = "ShowEmpController",value = "/manager/safe/showEmp")
public class ShowEmpController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer id = Integer.valueOf(request.getParameter("id"));

        EmpService empService = new EmpServiceImpl();
        Emp emp = empService.showEmp(id);

        request.setAttribute("emp",emp);
        request.getRequestDispatcher("/manager/safe/updateEmp.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
4.3.22 UpdateEmpController
@WebServlet(name = "UpdateEmpController",value = "/manager/safe/updateEmp")
public class UpdateEmpController extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //收参
        Integer id = Integer.valueOf(request.getParameter("id"));
        String name = request.getParameter("name");
        Double salary = Double.valueOf(request.getParameter("salary"));
        Integer age = Integer.valueOf(request.getParameter("age"));

        Emp emp = new Emp(id,name,salary,age);

        EmpService empService = new EmpServiceImpl();
        empService.modifyEmp(emp);

        response.sendRedirect(request.getContextPath()+"/manager/safe/showAllEmp");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
4.3.23 EncodingFilter
@WebFilter(filterName = "EncodingFilter",value = "/manager/*")
public class EncodingFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //设置统一编码格式
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }
}
4.3.24 CheckFilter
@WebFilter(filterName = "CheckFilter",value = "/manager/safe/*")
public class CheckFilter 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;

        HttpSession session = request.getSession();
        EmpManager empManager = (EmpManager) session.getAttribute("empManager");
        if (empManager != null) {
            chain.doFilter(request, response);
        }else {
            response.sendRedirect(request.getContextPath()+"/login.jsp");
        }

    }

    public void init(FilterConfig config) throws ServletException {

    }
}

五. Web开发总结

5.1 开发流程

在Web开发流程中, 遵守以下开发顺序:

  • DAO
    • table
    • entity
    • DAO接口
    • DAO实现
  • Service
    • Service接口
    • Service实现(调用DAO实现类, 并控制事务)
  • Controller(处理请求的Servlet)
    • 收集请求中的数据
    • 调用业务功能(调用Service实现类)
    • 在相应合适的作用域中存储数据
    • 流程跳转(forward|sendRedirect)--->.jsp
  • JSP
    • 在作用域中获取数据
    • 使用EL+JSTL将数据嵌套在HTML标签中
  • Filter
    • EncodingFilter: 统一编码格式过滤器
    • CheckFilter: 权限验证过滤器
原文地址:https://www.cnblogs.com/MRASdoubleZ/p/14674470.html