文件上传
2024/12/19大约 3 分钟
文件上传
重点
一、简介
在项目中,文件的上传是常见的功能。很多程序或者软件中都经常使用到文件的上传。
- 邮箱中有附件的上传;
- 图片上传。
二、什么是文件上传
当用户在前端页面点击文件上传后,用户上传的文件数据提交给服务器端,实现保存。
三、上传的相关限制
3.1、上传对表单的限制
`method="post"`;
`enctype="multipart/form-data"`;
表单中需要添加文件表单项:` <input type="file" name="xxx" />`
<form action="xxx" method="post" enctype="multipart/form-data">
用户名;<input type="text" name="username"/><br/>
照 片:<input type="file" name="photo"/><br/>
<input type="submit" value="上传"/>
</form>
3.2、上传对Servlet的限制
`request.getParameter("xxx")`这个方法在表单为`enctype="multipart/form-data"`时,它作废了,它永远都返回`null`。
3.3、如何实现文件上传
3.3.1、相关Jar包
* **commons-fileupload-1.4.jar**
* **commons-io-2.2.jar**
它会帮我们解析request中的上传数据,解析后的结果是一个表单项数据封装到一个**FileItem**对象中。我们只需要调用FileItem的方法即可。
3.3.2、具体步骤
1. 创建工厂:`DiskFileItemFactory factory = new DiskFileItemFactory()`;
2. 创建解析器:`ServletFileUpload sfu = new ServletFileUpload(factory)`;
3. 使用解析器来解析`request`,得到`FileItem`集合:
`List<FileItem> fileItemList = sfu.parseRequest(request)`,
`FileItem`中常用方法:
boolean isFormField():是否为普通表单项!返回true为普通表单项,如果为false即文件表单项
`String getFieldName()`:返回当前表单项的名称;
`String getString(String charset)`:返回表单项的值;
`String getName()`:返回上传的文件名称;
`long getSize()`:返回上传文件的字节数;
`InputStream getInputStream()`:返回上传文件对应的输入流;
`void write(File destFile)`:把上传的文件内容保存到指定的文件中。
//1 创建工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//2 创建解析器
ServletFileUpload sfu = new ServletFileUpload(factory);
//使用解析器ServletFileUpload.parseRequest() 来解析request,得到FileItem集合
try {
List<FileItem> list = sfu.parseRequest(request);
for (FileItem item : list) {
if(item.isFormField()) {
String fieldName = item.getFieldName();
String value = item.getString("utf-8");
System.out.println(fieldName + ":" + value);
} else {
String fileName = item.getName();
long size = item.getSize();
System.out.println("文件名:" + fileName);
System.out.println("文件大小" + size);
ServletContext servletContext = this.getServletConfig().getServletContext();
String realPath = servletContext.getRealPath("/img");
item.write(new File(realPath + "/" + fileName));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
文件上传步骤:1 导包2 在web下建file目录,可以建一个空文件,避免file目录不能打包的问题3 建jsp,注意 method="post" enctype= "multipart/form-data"4 建servlet,重写doPost方法
3.4、需要注意的细节
3.4.1、文件名或普通表单项乱码
如何解决:
`request.setCharacterEncoding("utf-8");`
`servletFileUpload.setHeaderEncoding("utf-8");`
以上两个方案二选一
//创建工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建解析器
ServletFileUpload sfu = new ServletFileUpload(factory);
request.setCharacterEncoding("utf-8");
//sfu.setHeaderEncoding("utf-8");
try {
//使用解析器来解析request,得到FileItem集合
List<FileItem> list = sfu.parseRequest(request);
for (FileItem item : list) {
if(item.isFormField()) {
String fieldName = item.getFieldName();
String value = item.getString("utf-8");
System.out.println(fieldName + ":" + value);
} else {
String fileName = item.getName();
long size = item.getSize();
System.out.println("文件名:" + fileName);
System.out.println("文件大小" + size);
ServletContext servletContext = this.getServletConfig().getServletContext();
String realPath = servletContext.getRealPath("/img");
item.write(new File(realPath + "/" + fileName));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
3.4.2、同名文件上传问题
使用UUID:
fileName = UUID.randomUUID().toString();
//创建工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建解析器
ServletFileUpload sfu = new ServletFileUpload(factory);
request.setCharacterEncoding("utf-8");
//sfu.setHeaderEncoding("utf-8");
try {
//使用解析器来解析request,得到FileItem集合
List<FileItem> list = sfu.parseRequest(request);
for (FileItem item : list) {
if(item.isFormField()) {
String fieldName = item.getFieldName();
String value = item.getString("utf-8");
System.out.println(fieldName + ":" + value);
} else {
String fileName = item.getName();
long size = item.getSize();
System.out.println("文件名:" + fileName);
System.out.println("文件大小" + size);
ServletContext servletContext = this.getServletConfig().getServletContext();
String realPath = servletContext.getRealPath("/img");
item.write(new File(realPath +
"/" +
UUID.randomUUID().toString().replace("-", "") +
"_" +
fileName));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}