文件的上传(FileUpload)
在Web应用中,文件上传和下载功能是非常常用的功能,对于文件上传,浏览器在上传的过程中是将文件以一个二进制的数据流的形式提交到服务器端的,不能够使用request.getParameter形式获取参数,因此需要将表单转换成二进制表单。
1. 添加依赖
在pom.xml的dependencies
中添加组件包:
<dependencies>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependencies>
2.转换表单
新建一个FileUpload.jsp文件或是在原来的表单中做修改都可以,我们需要在form
中加入:
enctype="multipart/formdata"
(用enctype设置为二进制表单)method="post"
(表单的提交方式必须是post形式)
<form action="FileUploadController" method="post" enctype="multipart/form-data">
<input type="text" name="username" /><br>
<input type="file" name="headphone" /><br>
<input type="submit" value="上传" />
</form>
点击上传,我们可以鼠标右键>“检查”或者点击F12查看,可以看到已经传过去了
3.实现文件的上传
- 新建一个文件:
FileUploadController.java
并继承HttpServlet
- 调用doPost方法
别的细节详见注释:
package com.csi.eshop.controller;
import com.csi.eshop.domain.UserInfo;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
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.List;
import java.util.UUID;
public class FileUploadController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用FileUpload实现数据的上传
//步骤1:创建FileItemFactory
FileItemFactory factory = new DiskFileItemFactory();
//步骤2:ServletFileUpload
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//步骤3:设置对request进行解析,ServletFileUpload.parseRequest
List<FileItem> fileItems = null ;
try {
fileItems = fileUpload.parseRequest(req);
} catch (FileUploadException e) {
e.printStackTrace();
}
UserInfo userInfo = new UserInfo();
//步骤4:获取到所有的表单中的字段FileItem
for (FileItem fileItem :fileItems){
//判断是否是一个文件
//isFormField():是否形成字段,是:普通类型
if (fileItem.isFormField()){
System.out.println(fileItem.getFieldName() + ":" + fileItem.getString());//输出文件:表单名
if ("username".equals(fileItem.getFieldName())){//指定表单
userInfo.setUserName(fileItem.getString());
}
}else{//很多文件
//步骤6:将文件上传到对应位置
//步骤6-1:文件上传的位置设定
String realPath = req.getServletContext().getRealPath("/upload");
//真实目录的对象
File realDir = new File(realPath);
//创建目录
//如果realDir不存在的话,就新建一个
if (!realDir.exists()){
realDir.mkdir();
}
//获取到的文件的名字
String fileName = fileItem.getName();
//将文件一分为二,获取到文件的扩展名
String extName = fileName.substring(fileName.lastIndexOf("."));
//新文件名名称创建
String newName = UUID.randomUUID().toString() + extName;
//实现文件的上传
File uploadFile = new File(realPath,newName);
try {
fileItem.write(uploadFile);
} catch (Exception e) {
e.printStackTrace();
}
userInfo.setHeadphone("upload/"+newName);
}
}
}
}
最后,就可以在你指定的路径里看到上传好的文件啦(夹带私货.jpg)
注意事项:
- 为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下
- 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名要限制上传文件的最大值
- 可以限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法
如果文章内有错误、不妥之处还请大家指正,十分感谢!