Tomcat:9.0.6
Java:1.8.0_281
lib:TomCat下的lib、commons-fileupload-1.2.2.jar、commons-io-2.4.jar
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传title>
head>
<body>
<h1>文件上传h1>
<form method="post" action="upload.do" enctype="multipart/form-data">
上传文件:
<input type="file" name="file" required>
<input type="submit" value="上传">
<input type="reset" value="取消">
form>
body>
html>
package com.fileUpload.servlet;
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.annotation.WebServlet;
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;
/**
* 类说明:完成文件上传操作
* 继承于HttpServlet类,并重写doPost(HttpServletRequest, HttpServletResponse)方法
*/
@WebServlet("/upload.do")
public class Upload extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置请求的编码格式为UTF-8(在此版本中Tomcat已经具备HttpServletRequest为UTF-8的编码格式,可以省略不写)
request.setCharacterEncoding("UTF-8");
// 设置响应的编码格式为UTF-8
response.setContentType("text/html;charset=UTF-8");
// 开始调用此类中包含的方法进行文件上传
fileUpload(request, response);
}
/**
* 文件上传——查看是否为文件上传类型
* 如果不是则退出方法不再执行后续所有代码
* 如果是文件上传类型,继续执行doUpload(HttpServletRequest, HttpServletResponse)方法
* @param request 由前端页面传来的请求——来源于doPost(HttpServletRequest, HttpServletResponse)方法
* @param response 由此处即后端,做出的响应——来源于doPost(HttpServletRequest, HttpServletResponse)方法
*/
private void fileUpload(HttpServletRequest request, HttpServletResponse response) {
// 是否为文件上传类型
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
// 判断是否为文件上传类型
if (isMultipart){
// 是文件上传类型
// 处理文件上传
doUpload(request, response);
}
// 不是文件上传类型
// return;
}
/**
* 生成固定的系统路径,并创建这个目录
* 路径创建完毕后,使用commons-fileupload-1.2.2.jar架包中的方法创建FileItemFactory、ServletFileUpload生成List对象
* List对象将作为前端表单提交的所有信息的对象,其中包含了文件上传及非文件上传的所有信息
* 遍历List对象,并判断是否为文件上传,即在前端中type=“file”,若不是则执行一般的表单提交方式,若是则执行文件上传操作
* @param request 由前端页面传来的请求——来源于fileUpload(HttpServletRequest, HttpServletResponse)方法
* @param response 由此处即后端,做出的响应——来源于fileUpload(HttpServletRequest, HttpServletResponse)方法
*/
private void doUpload(HttpServletRequest request, HttpServletResponse response) {
//文件路径设置部分
// windows设置文件上传的路径(文件路径可自行设置,必须为绝对路径!!!)
// 获取当前项目在windows中的路径
String uploadPath = request.getServletContext().getRealPath("/");
// 拼接路径,实现放在网站的部署目录下(File.separator就是一个右斜线"\")
uploadPath = uploadPath + "upload" + File.separator;
// 文件路径处理
File uploadFile = new File(uploadPath);
// 文件路径是否存在
if (uploadFile.exists()){
// 文件路径存在,不做处理(此处代码可做调整,作者为详细说明故如此书写)
}else {
// 文件路径不存在
// 创建文件路径
uploadFile.mkdir();
}
// 判断表单数据是否为文件上传部分
// 创建文件上传所需API实例
// 创建工厂
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析request请求,获取FileItem(commons-fileupload-1.2.2.jar架包内包含)对象集合
List<FileItem> fileItemList = null;
try {
fileItemList = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
// 遍历集合内的内容
for (FileItem fileItem : fileItemList) {
// 判断fileItem是否为普通的表单数据
if (fileItem.isFormField()){
// 是普通表单数据,采用普通表单数据处理办法
doData(fileItem);
}else {
// 非普通表单,而是文件数据,采用文件上传表单数据处理办法,根据返回值判定是否上传成功
boolean doFile = doFile(fileItem, uploadPath);
if (doFile){
// 文件上传成功!(此处自行处理,作者只是提供了一种可能和处理的位置)
}else {
// 文件上传失败!(此处自行处理,作者只是提供了一种可能和处理的位置)
}
}
}
}
/**
* 普通表单处理,此处处理的为非文件上传的表单数据(在本次案例中对应前端无普通表单数据,故此方法不会被使用)
* @param fileItem 在commons-fileupload-1.2.2.jar架包中包含的FileItem对象,由doUpload(HttpServletRequest, HttpServletResponse)方法创建并传递
*/
private void doData(FileItem fileItem) {
// 获取前端input中name属性名称,即中的user
String filedName = fileItem.getFieldName();
// 对结果进行UTF-8编码
try {
String value = fileItem.getString("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 此处只是作者提供的一种最普通的处理方式,若只有文件上传的表单数据,此处可以直接省略
switch (filedName){
case "user":
// 暂时不做处理
break;
case "fileType":
// 暂时不做处理
break;
default:
System.out.println("数据上传input——name属性未找到!");
}
}
/**
* 对文件上传类型进行限制,限制方法为文件上传的后缀名是否符合(此处可添加对文件大小的限制)
* 对文件进行重新命名,并保留原有后缀名
* 执行文件上传
* @param fileItem 在commons-fileupload-1.2.2.jar架包中包含的FileItem对象,由doUpload(HttpServletRequest, HttpServletResponse)方法创建并传递
* @param uploadPath 文件上传路径,由doUpload(HttpServletRequest, HttpServletResponse)方法创建并传递
* @return
*/
private boolean doFile(FileItem fileItem, String uploadPath) {
// 获取所上传文件的名称
String fileName = fileItem.getName();
// 判断是否真为文件上传,若无法获取文件上传名或文件上传名为空字符串,则认为为非文件上传类型
if (fileName != null && !"".equals(fileName)){
// 是真文件上传
// 对上传文件进行限制,使用fileNewName(String)方法对文件进行限制,限制条件可自行书写
boolean checkFile = checkFile(fileName);
// 判断是否符合文件限制
if (checkFile){
// 符合文件限制
// 设置文件新名字,使用checkFile(String)方法设置新的文件名称并返回,新文件名生成规则可自行设置(注意,名称如果重复将会覆盖原来的文件)
String fileNewName = fileNewName(fileName);
// 创建文件对象,根据文件路径及文件名称
File file = new File(uploadPath, fileNewName);
// 文件写入,此处将会产生Exception异常
try {
fileItem.write(file);
} catch (Exception e) {
e.printStackTrace();
}
}else {
// 不符合文件限制
}
}else {
// 不是真文件上传(此处自行处理,作者只是提供了一种可能和处理的位置)
}
return false;
}
/**
* 产生新的文件名称,
* 文件命名格式
* 时间戳+随机数+原文件类型
* 随机数范围[1000,10000)
* @param fileName 原文件名称
* @return 新的文件名称
*/
private String fileNewName(String fileName) {
// 获取最后一个“.”的位置,(作者提示:此处可以使用正则表达式进行限制)
int index = fileName.lastIndexOf(".");
// 通过最后一个“.”的位置,截取文件后缀名(.jpg)
String fileType = fileName.substring(index);
// 产生一个随机数作为新的文件名,随机数范围[1000,10000),大于等于1000小于10000
int temp = (int)(Math.random() * 1000 + 9000);
// 组成新的名字,时间戳+随机数+原文件类型
String fileNewName = System.currentTimeMillis() + temp + fileType;
return fileNewName;
}
/**
* 判断是否符合此方法中限制的文件后缀
* @param fileName 原文件名
* @return true符合,false不符合
*/
private boolean checkFile(String fileName){
// 获取最后一个“.”的位置
int index = fileName.lastIndexOf(".");
// 通过最后一个“.”的位置,截取文件后缀名(jpg)
String fileType = fileName.substring(index + 1);
// 判断后缀名是否为png、jpg(equalsIgnoreCase不区分大小写)(可以自行添加,或采用switch的方式)
if ("png".equalsIgnoreCase(fileType) ||
"jpg".equalsIgnoreCase(fileType)){
// 文件后缀符合为png、jpg
return true;
}
return false;
}
}
package com.community.utils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 表单文件上传工具类
* 使用说明:
* 首先调用fileUpload()方法上传文件,如果不是文件上传类型返回null,是文件上传类型返回值中:Map<文件名,文件相对路径>,如果路径为null,则说明上传失败
* fileUpload()方法获取到的路径,可以通过下标0、1、2、3......获取相应路径
* 调用getMap()方法获取非文件上传类型的对象集合
*/
public class FileUploads {
/**
* 非文件上传类型的参数返回,Map<文件名,value>
*/
private Map<String,String> map = new HashMap<>();
/**
* 文件上传类型结果,Map<文件名,文件路径>
*/
private Map<Integer,String> fileMap = new HashMap<>();
/**
* 文件上传路径
*/
private String filePath = null;
/**
* 请求
*/
private HttpServletRequest request = null;
public Map<String, String> getMap() {
return map;
}
/**
* 文件路径设置
*/
private void setFilePath() {
// windows设置文件上传的路径
String uploadPath = request.getServletContext().getRealPath("/") + "upload" + File.separator;
System.out.println(request.getServletContext().getRealPath("/"));
System.out.println(uploadPath);
// 文件路径是否存在
File uploadFile = new File(uploadPath);
if (uploadFile.exists()){
// 文件路径存在,不做处理
}else {
// 文件路径不存在
// 创建文件路径
uploadFile.mkdir();
}
this.filePath = uploadPath;
}
/**
* 文件上传开始方法
* @param request 请求
* @throws Exception
*/
public Map<Integer, String> fileUpload(HttpServletRequest request) throws Exception {
// 设置请求对象
this.request = request;
// 文件上传,检测是否未文件上传类型
boolean load = load();
if (!load){
return null;
}
// 设置路径
setFilePath();
// 执行上传操作
doUpload();
return fileMap;
}
/**
* 文件上传,检测是否未文件上传类型
* @return 是返回true,不是返回false
*/
private boolean load() {
// 是否为文件上传类型
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
// 判断是否为文件上传类型
if (isMultipart){
// 是文件上传类型
// 处理文件上传
return true;
}
// 不是文件上传类型
return false;
}
/**
* 文件上传核心
* @throws Exception
*/
private void doUpload() throws Exception {
// 创建文件上传所需API实例
// 创建工厂
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析request请求,获取FileItem(commons-fileupload-1.2.2.jar架包内包含)对象集合
List<FileItem> fileItemList = null;
fileItemList = upload.parseRequest(request);
int tempInt = 0;
// 遍历集合内的内容
for (FileItem fileItem : fileItemList) {
// 判断fileItem是否为普通的表单数据
if (fileItem.isFormField()){
// 是普通表单数据,并对数据进行编码
map.put(fileItem.getFieldName(),fileItem.getString("UTF-8"));
}else {
// 非普通表单,而是文件数据
String fileNewName = doFile(fileItem);
if (fileNewName != null){
String tempStr = filePath + fileNewName;
fileMap.put(tempInt,tempStr);
}else {
fileMap.put(tempInt,null);
}
tempInt ++;
}
}
}
/**
* 文件写入操作
* @param fileItem FileItem实体类对象
* @return 写入成功返回true,失败返回false
* @throws Exception
*/
private String doFile(FileItem fileItem) throws Exception {
// 获取文件名称
String fileName = fileItem.getName();
// 判断是否真为文件上传
if (fileName != null && !"".equals(fileName)){
// 是真文件上传
// 对上传文件进行限制
boolean checkFile = checkFile(fileName);
// 判断是否符合文件限制
if (checkFile){
// 符合文件限制
// 设置文件新名字
String fileNewName = fileNewName(fileName);
// 创建文件对象,根据文件路径及文件名称
File file = new File(filePath, fileNewName);
// 文件写入
fileItem.write(file);
return fileNewName;
}
}
return null;
}
/**
* 文件名字限制操作
* @param fileName 文件名
* @return 符合返回true,不符合返回false
*/
private boolean checkFile(String fileName){
// 获取最后一个“.”的位置
int index = fileName.lastIndexOf(".");
// 通过最后一个“.”的位置,截取文件后缀名
String fileType = fileName.substring(index + 1);
// 判断后缀名是否为png、jpg(equalsIgnoreCase不区分大小写)
if ("png".equalsIgnoreCase(fileType) ||
"jpg".equalsIgnoreCase(fileType)){
// 文件后缀符合为png、jpg
return true;
}
return false;
}
/**
* 产生新的文件名称
* @param fileName 文件名
* @return 新的文件名
*/
private String fileNewName(String fileName) {
// 获取最后一个“.”的位置
int index = fileName.lastIndexOf(".");
// 通过最后一个“.”的位置,截取文件后缀名
String fileType = fileName.substring(index);
// 组成新的名字,时间戳+4位随机数+原文件类型
String fileNewName = System.currentTimeMillis() + Integer.toString((int)(Math.random() * 1000 + 1000)) + fileType;
return fileNewName;
}
}