Tomcat:9.0.6
Java:1.8.0_281
lib:TomCat下的lib、commons-fileupload-1.2.2.jar、commons-io-2.4.jar
文件上传
文件上传
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 {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 设置请求的编码格式为UTF-8(在此版本中Tomcat已经具备HttpServletRequest为UTF-8的编码格式,可以省略不写)request.setCharacterEncoding("UTF-8");// 设置响应的编码格式为UTF-8response.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 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属性名称,即中的userString 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小于10000int 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、jpgreturn 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 map = new HashMap<>();/*** 文件上传类型结果,Map<文件名,文件路径>*/private Map fileMap = new HashMap<>();/*** 文件上传路径*/private String filePath = null;/*** 请求*/private HttpServletRequest request = null;public Map 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 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 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、jpgreturn 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;}
}