关于javaweb中上传和下载文件的操作
上传文件
前端页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>上传文件</title>
</head>
<body>
<form action="UploadController" method="post" enctype="multipart/form-data">
上传文件:<input type="file" name="file1"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
- 表单from 的属性一定要添加:enctype=“multipart/form-data”,意思为上传二进制的数据表单,如果没有设置,默认就是文本表单,上传不了文件。
Controller(控制层代码)
@WebServlet("/UploadController")
// 设置请求文件的最大值,设置上传文件的最大值
@MultipartConfig(maxRequestSize = 200 * 1024 * 1024, maxFileSize = 100 * 1024 * 1024)
public class UploadController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置请求体和响应体的编码格式为utf-8
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 获取用户名
String username = request.getParameter("username");
System.out.println("username----->" + username);
// 获取文件对象part通过 request.getPart();
Part part = request.getPart("file1");
// 获取上传的文件名orldFileName
String orldFileName = part.getSubmittedFileName();
// 获取要保存文件的基本路径(更目录)path,可以事先在WEB-INF下创建upload文件用于存放文件
String path = this.getServletContext().getRealPath("/WEB-INF/upload");
// 设置上传文件类型,如下设置图片的格式,可以不用时删除就好
List<String> nameList = new ArrayList<String>();
nameList.add(".jpg");
nameList.add(".bmp");
nameList.add(".png");
String extName = orldFileName.substring(orldFileName.lastIndexOf("."));
if (!nameList.contains(extName)) {
System.out.println("上传失败");
return;
}
// 通过工具类自己编写的工具类UploadUtils获取加上UUID的新文件名newFileName,如源文件名为:a.jpg ,加上UUID后变为0220006505013_a.jpg
String newFileName = UploadUtils.getNewFilename(orldFileName);
// 通过工具类UploadUtils获取基本路径加上多级目录的路径,放在同一个文件夹里面存储太多文件
String newFilePath = UploadUtils.getNewFilePath(path, orldFileName);
// 加文件进行写入保存路径newFilePath+"/"+新文件名newFileName
part.write(newFilePath + "/" + newFileName);
// 控制台打印路径
System.out.println("上传路径" + newFilePath + "/" + newFileName);
// 响应客户端上传成功
response.getWriter().println("上传成功");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
工具类(UploadUtils)
public class UploadUtils {
public static String getNewFilename(String fileName) { // 生产新的文件名
// 通过 UUID..randomUUID().toString()生产一长串的数字转字符串2acd-dsdsd-dddsc121-35135-2251
// 通过String.replace()替换生产字符串中d的"-",得到2acddsdsddddsc121351352251
// 然后进行新文件名的拼接得到2acddsdsddddsc121351352251_a.jpg,注明传过来的fileNmae的值为a.jpg
// 然后返回新的文件名
return UUID.randomUUID().toString().replace("-", "") + "_" + fileName;
}
public static String getNewFilePath(String basePath, String fileName) { // 生产多级目录
// 根据文件名获取它是哈希值hashCode
int hashCode = fileName.hashCode();
// 将哈希值&上15得到二级目录
int path1 = hashCode & 15;
// 再讲二级目录右移4位后&上15得到三级目录
int path2 = (path1 >> 4) & 15;
//将基本路径拼接二级目录和三级目录得到最终的保存路径
String dirt = basePath + "//" + path1 + "//" + path2;
// 判断这个路径是否存在,不存在就创建,然后返回
File file = new File(dirt);
if (!file.exists()) {
file.mkdirs();
}
return dirt;
}
}
长传后得到文件
下载文件
前端代码及效果
<%@ 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 border="1">
<tr>
<td>文件名</td>
<td>下载</td>
</tr>
<c:forEach items="${requestScope.map}" var="file">
<tr>
<td>${file.value}</td>
<td><a href="${pageContext.request.contextPath}/manager/DownLoadController?filename=${file.key}">下载</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
- 前端代码效果
Controller(控制层)
- 获取文件集合(FileListController)
@WebServlet("/manager/FileListController")
public class FileListController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建map集合,用于存储遍历的文件名(key是存储带UUID的文件名,value存储不带UUID的原文件名,用于展示给用户看的)
HashMap<String, String> map = new HashMap<>();
//获取基本路径
String basePath = request.getServletContext().getRealPath("/WEB-INF/upload");
// 通过工具类DownLoadUtils,WEB-INF/upload下的所有文件,然后保存到map中
DownLoadUtils.getFileList(new File(basePath), map);
// 保存到request.setAttribute中
request.setAttribute("map", map);
// 进行转发到客户端fileList.jsp页面。
request.getRequestDispatcher("/fileList.jsp").forward(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
- 下载文件(DownLoadController)
@WebServlet("/manager/DownLoadController")
public class DownLoadController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取有uuid的文件名
String uuidName = request.getParameter("filename");
// 获取文件保存的根路径
String basePath = this.getServletContext().getRealPath("/WEB-INF/upload");
// 拆分UUid的文件名得到源文件名
String fileName = uuidName.split("_")[1];
// 得到基本路径+多级目录
String basePathName = UploadUtils.getNewFilePath(basePath, fileName);
// 设置响应头,显示下载
response.setHeader("content-disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "utf-8"));
//下载
FileInputStream fileInputStream = new FileInputStream(basePathName + "/" + uuidName);
ServletOutputStream servletOutputStream = response.getOutputStream();
byte buf[] = new byte[1024];
int count = 0;
while ((count = fileInputStream.read(buf)) != -1) {
servletOutputStream.write(buf, 0, count);
}
// 关闭通道
servletOutputStream.close();
fileInputStream.close();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
工具类(DownLoadUtils)
public class DownLoadUtils {
public static void getFileList(File file, Map<String, String> map) {
// 根据文件名,获取该文件下面的所有文件集合
File[] files = file.listFiles();
// 首先判断文件集合是否为空
if (files != null) {
// 用增强for循环遍历
for (File f : files) {
// 判断文件是否为目录,为目录就调用 getFileList(f, map);进行递归
if (f.isDirectory()) {
getFileList(f, map);
} else {
// 文件不为目录,就获取带UUID的文件名
String fileName = f.getName();
// 进行文件名分割得到不带UUID的源文件名
int i = fileName.indexOf("_");
String realNme = fileName.substring(i + 1);
// 存储到map集合中
map.put(fileName, realNme);
}
}
}
}
}