使用Servlet实现多文件上传
一位朋友最近在学习JavaWeb开发,开始学习多文件上传操作,他自己尝试着去网上看一些博客教程,能明白其中大概的思路,
还是让我和他说说,如何实现单文单件上传功能。我和他说了一下大致的思路与操作步骤,主要分为前端和后端两部分来实现多文件上传操作。
Servlet版本要求必须是3.0+。
后台Java代码实现思路:
.1.继承HttpServlet,重写doPost()方法;
.2.从请求对象中获取文件上传对象Parts;
注意:必须在servlet中添加@MultipartConfig注解
.3.获取文件相关信息,比如类型、大小,判断是否合法;
.4.拼接文件保存路径;
.5.获取文件对象的输入流和保存文件的输出流;
.6.读取文件内容并写入到输出流中;
.7.刷新输出流缓冲区。
说明:多文件上传的时候,判断文件类型和大小是否合法可以在一个循环中完成。然后上传的时候,在另外一个循环中完成。如果有一个文件上传失败,则终止后面的文件上传。如果逻辑更加严谨一些,一次多文件上传操作失败之后,比如上传5个文件,前面三个成功,后面两个失败,是需要删除前两三个已经成功了的文件的。
前端html实现思路:
.1.创建html页面,编写form表单;
.2.设置form表单的请求方法为post方法;
.3.设置form表单的enctype属性值为"multipart/form-data";
.4.添加input标签,属性type设置为file;accept属性设置为accept=".png,.jpg",里面具体的值设置为想要上传的文件后缀名即可(可选)。
.5.在input标签中添加multiple属性,表示多文件上传。
后端示例代码实现如下:
// 注意:必须在servlet中添加@MultipartConfig注解
@MultipartConfig
@WebServlet("/uploadOne")
public class UploadFileOne extends HttpServlet {
private final static String UPLOAD_PATH = "D:\\JavaWorkSpace\\course2024\\maven-demo\\src\\main\\webapp\\";
private final static List<String> FILE_TYPE = Arrays.asList(".jpg", ".png", ".gif");
private final static Long FILE_MAX_SIZE = 4 * 1024 * 1024L;
// 1.继承HttpServlet,重写doPost方法
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 2.从请求对象中获取文件上传对象Part
Collection<Part> parts = req.getParts();
String fileName;
for(Part filePart : parts){
fileName = filePart.getSubmittedFileName();
String fileType = fileName.substring(fileName.lastIndexOf("."));
// 3.获取文件相关信息,比如类型、大小,判断是否合法
System.out.println("fileType--->" + fileType);
if(!FILE_TYPE.contains(fileType)){
CommonResult.failed(resp,"文件类型错误");
return;
}
System.out.println("size--->" + filePart.getSize());
if(filePart.getSize() > FILE_MAX_SIZE){
CommonResult.failed(resp,"文件大小超过4M");
return;
}
System.out.println("fileName--->" + fileName);
}
String savePath = null;
for(Part filePart : parts){
// 4.拼接文件保存路径
savePath = UPLOAD_PATH + filePart.getSubmittedFileName();
System.out.println("savePath--->" + savePath);
// 5.获取文件对象的输入流和保存文件的输出流
try(BufferedInputStream bis = new BufferedInputStream(filePart.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream((new FileOutputStream(savePath)));
){
byte[] buffer = new byte[1024];
int len;
// 6.读取文件内容并写入到输出流中
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
// 7.刷新输出流
bos.flush();
} catch (Exception e){
throw new RuntimeException("多文件上传失败"); }
}
CommonResult.success(resp,"上传完成");
}
}
前端示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="./upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" accept=".png,.jpg" multiple/>
<br>
<input type="submit" value="上传" />
</form>
</body>
</html>
最终测试效果如下,
测试方式一:可以直接在浏览器中先请求html页面,然后选择文件,测试上传。
测试方式二:使用调试工具,比如ApiFox;测试时非常方便,可以反反复复地进行测试文件上传操作,一直到文件上传正确为止(强烈推荐)。
至此:文件上传的功能全部完成。说明:Java代码中,在进行I/O流操作时,能使用带buffer缓冲区的类尽量使用,因为它的效率会高很多。参考博客:
https://blog.csdn.net/qq_32099833/article/details/109002715