Java、servlet、Tomcat实现文件上传操作
创始人
2024-02-14 13:18:00

目录

  • 一、写在前面的话
    • 1.1、环境说明
    • 1.2、观看基础推荐说明
  • 二、单一功能实现代码说明
    • 2.1、前端代码——使用简单的Html5页面
    • 2.2、前后端连接servlet文件书写——使用语言Java
  • 三、整合为工具类使用代码说明——使用语言Java

一、写在前面的话

1.1、环境说明

Tomcat:9.0.6
Java:1.8.0_281
lib:TomCat下的lib、commons-fileupload-1.2.2.jar、commons-io-2.4.jar

1.2、观看基础推荐说明

  1. 需要掌握Java的继承、方法重写
  2. 需要掌握基础的Java语言逻辑
  3. 需要掌握基础的Java方法调用
  4. 需要掌握Java的类的引用
  5. 需要了解servlet的简单使用
  6. 需要掌握前后端交互的基本使用
  7. 需要掌握Tomcat的配置,及Java工程的创建、Java外部包的引用
  8. 需要掌握简单的Html页面书写
  9. 需要具备高中及以上数学知识水平
  10. 需要对文件编码格式有一定了解

二、单一功能实现代码说明

2.1、前端代码——使用简单的Html5页面

注意事项
  1. 此方法采用form表单提交
  2. form表单的提交方式必须为post,说明:文件上传将会以IO流的方式,此时会对数据进行转换,get方式无法完整存储
  3. form必须添加enctype属性,并声明类型为数据传输(multipart/form-data
  4. required表示必填,即不进行文件上传无法点击上传按钮
  5. type="file"表示为文件上传,是HTML5自带属性
  6. action="upload.do"为文件上传地址的配置,upload.do是在servlet中设置,也可以在xml中配置


文件上传


文件上传

上传文件:

2.2、前后端连接servlet文件书写——使用语言Java

注意事项
  1. package 后的内容需要根据自己项目自行修改
  2. 文件上传需要commons-fileupload-1.2.2.jar、commons-io-2.4.jar的架包
  3. 此方法中文件上传是直接书写在了servlet中,供做学习使用,耐心看完所有注释,此方法中对于文件上传出现的种种可能都做出了处理位置,可以自行添加,也可以不做处理
  4. 此方法form必须有enctype="multipart/form-data"的属性
  5. 此方法使用了文本标记语言@WebServlet(“/upload.do”),若已经在web.xml中进行了servlet的配置,请删除任意其中一个的配置,这两种方法等价
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;}
}

三、整合为工具类使用代码说明——使用语言Java

注意事项
  1. 此工具使用前请先观看本博客其他内容,以方便自己改写工具类的使用
  2. 此工具类为提供路径设置的方法,路径已在此工具中写死
  3. 再次强调,先观看前后端连接servlet文件书写——使用语言Java
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;}
}

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...