接着上一篇讲:

Jsp+Servlet实现文件上传下载(一)--文件上传 点击打开链接

本章来实现一下上传文件列表展示,同时优化了一下第一章中的代码。

废话少说,上代码

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

mysql创建附件表

DROP TABLE tbl_accessory;

CREATE TABLE tbl_accessory
(
id INT AUTO_INCREMENT PRIMARY KEY,
file_name VARCHAR(500),
file_size DOUBLE(10,2),
file_ext_name VARCHAR(100),
file_path VARCHAR(2000)
)
; SELECT * FROM tbl_accessory; DELETE FROM tbl_accessory;

创建附件实体类

package entity.upload;

/**
* 附件实体类
*
* @author xusucheng
* @create 2017-12-29
**/
public class EntityAccessory {
private int id;
private String fileName;
private double fileSize;
private String file_ext_name;
private String filePath; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
this.fileName = fileName;
} public double getFileSize() {
return fileSize;
} public void setFileSize(double fileSize) {
this.fileSize = fileSize;
} public String getFile_ext_name() {
return file_ext_name;
} public void setFile_ext_name(String file_ext_name) {
this.file_ext_name = file_ext_name;
} public String getFilePath() {
return filePath;
} public void setFilePath(String filePath) {
this.filePath = filePath;
}
}

创建DBUtil工具类

package util;

import java.sql.*;
import java.io.InputStream;
import java.util.Properties; /**
* 数据库工具类
*
* @author xusucheng
* @create 2017-11-18
**/
public class DBUtil {
//定义链接所需要的变量
private static Connection con = null;
private static PreparedStatement ps = null;
private static ResultSet rs = null; //定义链接数据库所需要的参数
private static String url = "";
private static String username = "";
private static String driver="";
private static String password=""; //定义读取配置文件所需要的变量
private static Properties pp = null;
private static InputStream fis = null; /**
* 加载驱动
*/
static {
try {
//从dbinfo.properties配置文件中读取配置信息
pp = new Properties();
fis = DBUtil.class.getClassLoader().getResourceAsStream("db.properties"); pp.load(fis);
url = pp.getProperty("url");
username = pp.getProperty("username");
driver=pp.getProperty("driver");
password=pp.getProperty("password"); //加载驱动
Class.forName(driver); } catch (Exception e) {
System.out.println("驱动加载失败!");
e.printStackTrace();
} finally {
try {
fis.close();
} catch (Exception e) {
e.printStackTrace();
} fis = null; //垃圾回收自动处理
} } /**
* 得到Connection链接
* @return Connection
*/
public static Connection getConnection() { try {
//建立连接
con = DriverManager.getConnection(url, username, password); } catch (Exception e) {
System.out.println("数据库链接失败!");
e.printStackTrace();
} return con;
} /*public DBUtil(String sql){
try {
ps = getConnection().prepareStatement(sql);//准备执行语句
} catch (Exception e) {
e.printStackTrace();
}
} public void close() {
try {
con.close();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}*/ /**
* 统一的资源关闭函数
* @param rs
* @param ps
* @param con
*/
public static void close(ResultSet rs,Statement ps, Connection con){ if(rs != null) {
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(ps != null) {
try {
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if(con != null) {
try {
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} }

创建附件实体DAO类

package dao.upload;

import entity.upload.EntityAccessory;
import util.DBUtil; import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; /**
* 附件上传DAO
*
* @author xusucheng
* @create 2017-12-29
**/
public class AccessoryDao {
public static void add(EntityAccessory entity) {
Connection conn = DBUtil.getConnection();
String sql = "insert into tbl_accessory(file_name,file_size,file_ext_name,file_path) values(?,?,?,?)";
try {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, entity.getFileName());
ps.setDouble(2, entity.getFileSize());
ps.setString(3, entity.getFile_ext_name());
ps.setString(4, entity.getFilePath());
ps.execute();
//conn.commit(); DBUtil.close(null, ps, conn);
} catch (SQLException e) {
e.printStackTrace();
}
} public static List<EntityAccessory> list() {
Connection conn = DBUtil.getConnection();
String sql = "select id,file_name,file_size,file_ext_name,file_path from tbl_accessory";
List<EntityAccessory> accessoryList = new ArrayList<>();
try {
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery(); while (rs.next()) {
EntityAccessory entity = new EntityAccessory();
entity.setId(rs.getInt("id"));
entity.setFileName(rs.getString("file_name"));
entity.setFileSize(new BigDecimal(rs.getDouble("file_size") / 1024).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
entity.setFile_ext_name(rs.getString("file_ext_name"));
entity.setFilePath(rs.getString("file_path"));
accessoryList.add(entity);
} DBUtil.close(rs, ps, conn);
} catch (SQLException e) {
e.printStackTrace();
} return accessoryList; } public static void remove(int id) {
Connection conn = DBUtil.getConnection();
String sql = "delete from tbl_accessory where id=?";
try {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,id);
ps.execute();
//conn.commit(); mysql默认开启了autocommit DBUtil.close(null,ps,conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
}

创建list.jsp列表页面

<html>
<head>
<title>上传文件列表</title>
</head>
<body> <h3>文件列表</h3>
<table class="acclist_tab" border="1" bordercolor="#000000" cellspacing="0" cellpadding="2" style="border-collapse:collapse;">
<tr>
<th>文件名</th>
<th>文件大小(KB)</th>
<th>操作</th>
</tr>
<c:if test="${not empty accessoryList}">
<c:forEach items="${accessoryList}" var="acc">
<tr>
<td>${acc.fileName}</td>
<td>${acc.fileSize}</td>
<td><a href="">删除</a></td>
</tr>
</c:forEach>
</c:if>
</table>
</body>
</html>

创建展示列表Servlet:listUploadedFilesServlet

package servlet.upload;

import dao.upload.AccessoryDao;
import entity.upload.EntityAccessory; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List; /**
* 返回已上传文件列表
*
* @author xusucheng
* @create 2017-12-29
**/ @WebServlet("/listUploadedFiles")
public class listUploadedFilesServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取文件列表
List<EntityAccessory> accessoryList = AccessoryDao.list();
request.setAttribute("accessoryList", accessoryList); request.getRequestDispatcher("pages/upload/list.jsp").forward(request, response);
} @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}

增加error.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> <h3>上传失败:</h3>
<c:if test="${not empty errorMessage}">
<%--<input type="text" id="errorMessage" value="${errorMessage}" style="color:red;" disabled="disabled">--%>
<h4 style="color: red;">${errorMessage}</h4>
</c:if> </body>
</html>

优化了第一章中的上传控制器

package servlet.upload;

import dao.upload.AccessoryDao;
import entity.upload.EntityAccessory;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; 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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.UUID; /**
* 处理文件上传
*
* @author xusucheng
* @create 2017-12-27
**/
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置文件上传基本路径
String savePath = this.getServletContext().getRealPath("/WEB-INF/uploadFiles");
//设置临时文件路径
String tempPath = this.getServletContext().getRealPath("/WEB-INF/tempFiles");
File tempFile = new File(tempPath);
if (!tempFile.exists()) {
tempFile.mkdir();
} //定义异常消息
String errorMessage = "";
//创建file items工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置缓冲区大小
factory.setSizeThreshold(1024 * 100);
//设置临时文件路径
factory.setRepository(tempFile);
//创建文件上传处理器
ServletFileUpload upload = new ServletFileUpload(factory);
//监听文件上传进度
ProgressListener progressListener = new ProgressListener() {
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("正在读取文件: " + pItems);
if (pContentLength == -1) {
System.out.println("已读取: " + pBytesRead + " 剩余0");
} else {
System.out.println("文件总大小:" + pContentLength + " 已读取:" + pBytesRead);
}
}
};
upload.setProgressListener(progressListener); //解决上传文件名的中文乱码
upload.setHeaderEncoding("UTF-8");
//判断提交上来的数据是否是上传表单的数据
if (!ServletFileUpload.isMultipartContent(request)) {
//按照传统方式获取数据
return;
} //设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
//upload.setFileSizeMax(1024 * 1024);
//设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
upload.setSizeMax(1024 * 1024 * 10); try {
//使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> iterator = items.iterator();
while (iterator.hasNext()) {
FileItem item = iterator.next(); //判断jsp提交过来的是不是文件
if (item.isFormField()) {
errorMessage = "请提交文件!";
break;
} else {
//文件名
String fileName = item.getName();
if (fileName == null || fileName.trim() == "") {
System.out.println("文件名为空!");
}
//处理不同浏览器提交的文件名带路径问题
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
//文件大小
Long fileSize = item.getSize();
//文件扩展名
String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1);
//判断扩展名是否合法
if (!validExtension(fileExtension)) {
errorMessage = "上传文件非法!";
item.delete();
break;
}
//获得文件输入流
InputStream in = item.getInputStream();
//得到保存文件的名称
String saveFileName = createFileName(fileName);
//得到文件保存路径
String realFilePath = createRealFilePath(savePath, saveFileName);
//创建文件输出流
FileOutputStream out = new FileOutputStream(realFilePath);
//创建缓冲区
byte buffer[] = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) > 0) {
//写文件
out.write(buffer, 0, len);
}
//关闭输入流
in.close();
//关闭输出流
out.close();
//删除临时文件
item.delete();
//将上传文件信息保存到附件表中
EntityAccessory entity = new EntityAccessory();
entity.setFileName(fileName);
entity.setFileSize(fileSize);
entity.setFile_ext_name(fileExtension);
entity.setFilePath(realFilePath);
AccessoryDao.add(entity);
} } } catch (FileUploadBase.FileSizeLimitExceededException e) {
e.printStackTrace();
errorMessage = "单个文件超出最大值!!!";
} catch (FileUploadBase.SizeLimitExceededException e) {
e.printStackTrace();
errorMessage = "上传文件的总的大小超出限制的最大值!!!";
} catch (FileUploadException e) {
e.printStackTrace();
errorMessage = "文件上传失败!!!";
} finally {
if (!"".equals(errorMessage)) {
request.setAttribute("errorMessage", errorMessage);
request.getRequestDispatcher("pages/upload/error.jsp").forward(request, response);
} else {
response.sendRedirect("listUploadedFiles");
} } } @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} private boolean validExtension(String fileExtension) {
String[] exts = {"jpg", "txt", "doc", "pdf"};
for (int i = 0; i < exts.length; i++) {
if (fileExtension.equals(exts[i])) {
return true;
} } return false;
} private String createFileName(String fileName) {
return UUID.randomUUID().toString() + "_" + fileName;
} /**
* 根据基本路径和文件名称生成真实文件路径,基本路径\\年\\月\\fileName
*
* @param basePath
* @param fileName
* @return
*/
private String createRealFilePath(String basePath, String fileName) {
Calendar today = Calendar.getInstance();
String year = String.valueOf(today.get(Calendar.YEAR));
String month = String.valueOf(today.get(Calendar.MONTH) + 1); String upPath = basePath + File.separator + year + File.separator + month + File.separator;
File uploadFolder = new File(upPath);
if (!uploadFolder.exists()) {
uploadFolder.mkdirs();
} String realFilePath = upPath + fileName; return realFilePath;
}
}

测试效果截图

下集预告

实现附件删除功能!

Jsp+Servlet实现文件上传下载(二)--文件列表展示的更多相关文章

  1. SpringMVC文件上传下载(单文件、多文件)

    前言 大家好,我是bigsai,今天我们学习Springmvc的文件上传下载. 文件上传和下载是互联网web应用非常重要的组成部分,它是信息交互传输的重要渠道之一.你可能经常在网页上传下载文件,你可能 ...

  2. Spring Boot2(十四):单文件上传/下载,文件批量上传

    文件上传和下载在项目中经常用到,这里主要学习SpringBoot完成单个文件上传/下载,批量文件上传的场景应用.结合mysql数据库.jpa数据层操作.thymeleaf页面模板. 一.准备 添加ma ...

  3. JavaWeb 文件上传下载

    1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下 ...

  4. java中的文件上传下载

    java中文件上传下载原理 学习内容 文件上传下载原理 底层代码实现文件上传下载 SmartUpload组件 Struts2实现文件上传下载 富文本编辑器文件上传下载 扩展及延伸 学习本门课程需要掌握 ...

  5. 转载:JavaWeb 文件上传下载

    转自:https://www.cnblogs.com/aaron911/p/7797877.html 1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端 ...

  6. Struts的文件上传下载

    Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...

  7. Spring MVC文件上传下载

    Spring MVC文件上传下载 单文件上传 底层是使用Apache fileupload 组件完成上传,Spring MVC对这种方式进行封装. pom.xml <dependency> ...

  8. jsp+servlet实现文件上传下载

    相关素材下载 01.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" ...

  9. Servlet文件上传下载

    今天我们来学习Servlet文件上传下载 Servlet文件上传主要是使用了ServletInputStream读取流的方法,其读取方法与普通的文件流相同. 一.文件上传相关原理 第一步,构建一个up ...

  10. SpringBoot入门一:基础知识(环境搭建、注解说明、创建对象方法、注入方式、集成jsp/Thymeleaf、logback日志、全局热部署、文件上传/下载、拦截器、自动配置原理等)

    SpringBoot设计目的是用来简化Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,SpringBoot致力于在蓬勃发 ...

随机推荐

  1. [转帖]技术分享| MySQL 的 AWR Report?— MySQL 状态诊断报告

    https://segmentfault.com/a/1190000039959767     作者:秦福朗 爱可生 DBA 团队成员,负责项目日常问题处理及公司平台问题排查.热爱 IT,喜欢在互联网 ...

  2. [转帖]SPEC CPU 2017 单线程整数性能测试与总结 (2022)

    https://zhuanlan.zhihu.com/p/574105237 x86处理器的整数性能在过去4年间取得了长足的进步 x86处理器移动端性能缩水非常严重 ARM公版的旗舰级处理器相比前代进 ...

  3. [转帖]Linux内核线程kthread简介【最好的一篇!】

    https://zhuanlan.zhihu.com/p/581587583 Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求).内核需要多个执行流并行,为了 ...

  4. [转帖]Guanaco, Llama, Vicuña, Alpaca该怎么区别

    https://zhuanlan.zhihu.com/p/106262896 在智利和秘鲁高原区经常会遇到的一种动物让人十分挠头,学术点称呼就是骆驼科其中一个族群--羊驼属和骆马属.头疼在于,分不清楚 ...

  5. [转帖]CPU结构对Redis性能的影响

    文章系转载,便于分类和归纳,源文地址:https://wangkai.blog.csdn.net/article/details/111571446 CPU的多核架构和多CPU架构都会影响到Redis ...

  6. Linux的free命令与OOM的简单总结

    简介 查看操作系统配置最关键的几个命令是 lscpu 查看CPU信息 以及free 查看内存信息. 不过free信息有一个疑惑点 他的 free的值可能很小. 会让搭建产生误解. 这里简单说明一下. ...

  7. 【JS 逆向百例】当乐网登录接口参数逆向

    声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:当乐网登录 主页:https://oauth.d.cn ...

  8. Gin-官方文档

    目录 官方文档 官方文档 https://learnku.com/docs/gin-gonic/2018/gin-readme/3819 https://www.kancloud.cn/shuangd ...

  9. 大数据面试题集锦-Hadoop面试题(三)-MapReduce

    你准备好面试了吗?这里有一些面试中可能会问到的问题以及相对应的答案.如果你需要更多的面试经验和面试题,关注一下"张飞的猪大数据分享"吧,公众号会不定时的分享相关的知识和资料. 目录 ...

  10. vscode中文搜索乱码或搜索不到

    使用vscode在全局搜索时,代码中的内容无法搜索出来,或者搜索出来是乱码. 经验证:与vscode的语言设置无关,设置为中文或英文都是一样的 后面猜想到会不会与文件自身的编码有关,因为我们项目中的代 ...