首页 > 编程语言 >common-fileupload组件实现java文件上传和下载

common-fileupload组件实现java文件上传和下载

时间:2023-12-13 18:45:55浏览次数:42  
标签:文件 fileupload java servlet request common import 上传

简介:文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到本地。对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件。这个common-fileupload上传组件的jar包可以去apache官网上面下载,也可以在struts的lib文件夹下面找到,struts上传的功能就是基于这个实现的。common-fileupload是依赖于common-io这个包的,所以还需要下载这个包。

文件上传

(1)文件上传前端界面(fileupload.jsp)

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html>
 4 <html>
 5 <head>
 6 <meta charset="UTF-8">
 7 <title>文件上传</title>
 8 </head>
 9 <body>
10 <form action="FileUpload" method="post" enctype="multipart/form-data">
11     <p><label>用户名:<input type="text" name="username"></label></p>
12     <p><label>密&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="password" name="pwd"></label></p>
13     <p><input type="file" name="upfile"></p>
14     <input type="submit" value="提交">
15 </form> 
16 </body>
17 </html>

[注]:在文件上传的页面要用enctype="multipart/form-data" method="post"来表示进行文件上传

(2)文件上传细节

  上述的代码虽然可以成功将文件上传到服务器上面的指定目录当中,但是文件上传功能有许多需要注意的小细节问题,以下列出的几点需要特别注意的:

  (2.1)、为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。

  (2.2)、为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。

  (2.3)、为防止一个目录下面出现太多文件,要使用hash算法打散存储。

  (2.4)、要限制上传文件的最大值。

  (2.5)、要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

(3)处理文件上传的servlet

  1 package com.etc.utils;
  2 
  3 import java.io.File;
  4 import java.io.IOException;
  5 import java.io.PrintWriter;
  6 import java.util.List;
  7 import java.util.UUID;
  8 
  9 import javax.servlet.ServletException;
 10 import javax.servlet.annotation.WebServlet;
 11 import javax.servlet.http.HttpServlet;
 12 import javax.servlet.http.HttpServletRequest;
 13 import javax.servlet.http.HttpServletResponse;
 14 
 15 import org.apache.commons.fileupload.FileItem;
 16 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 17 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 18 
 19 @WebServlet("/FileUpload")
 20 public class FileUpload extends HttpServlet {
 21     private static final long serialVersionUID = 1L;
 22 
 23     public FileUpload() {
 24         super();
 25     }
 26 
 27     protected void doGet(HttpServletRequest request, HttpServletResponse response)
 28             throws ServletException, IOException {
 29         request.setCharacterEncoding("UTF-8");
 30         response.setCharacterEncoding("UTF-8");
 31         response.setContentType("text/html;charset=UTF-8");
 32         PrintWriter out = response.getWriter();
 33         String filedName = "";
 34 
 35         // 1、创建工厂类:DiskFileItemFactory factory=new DiskFileItemFactory();
 36         DiskFileItemFactory factory = new DiskFileItemFactory();
 37         // 2、创建解析器:ServletFileUpload upload=new ServletFileUpload(factory);
 38         ServletFileUpload upload = new ServletFileUpload(factory);
 39         upload.setHeaderEncoding("UTF-8");
 40 
 41         // 设置缓冲区大小与临时文件目录
 42         factory.setSizeThreshold(1024 * 1024 * 10);
 43         File fileDir = new File("e:\\upload");
 44         if (!fileDir.exists())
 45             fileDir.mkdirs();
 46         // 设置文件存储仓库
 47         factory.setRepository(fileDir);
 48         // 设置单个文件大小限制
 49         upload.setFileSizeMax(1024 * 1024 * 10);
 50         // 设置所有文件总和大小限制
 51         upload.setSizeMax(1024 * 1024 * 100);
 52 
 53         // 3、使用解析器解析request对象:List<FileItem> list=upload.parseRequest(request);
 54         /**
 55          * FileItem
 56          * String getFieldName():获取表单项的name的属性值。
 57          * String getName():获取文件字段的文件名。如果是普通字段,则返回null
 58          * String getString():获取字段的内容。如果是普通字段,则是它的value值;如果是文件字段,则是文件内容。 
 59          * String getContentType():获取上传的文件类型,例如text/plain、image。如果是普通字段,则返回null。 
 60          * long getSize():获取字段内容的大小,单位是字节。 
 61          * boolean isFormField():判断是否是普通表单字段,若是,返回true,否则返回false。
 62          * InputStream getInputStream():获得文件内容的输入流。如果是普通字段,则返回value值的输入流
 63          */
 64         try {
 65             List<FileItem> list = upload.parseRequest(request);
 66             System.out.println(list);
 67             for (FileItem fileItem : list) {
 68                 /*
 69                  * 对文件进行处理
 70                  */
 71                 if (!fileItem.isFormField() && fileItem.getName() != null && !"".equals(fileItem.getName())) {
 72                     String fileName = fileItem.getName();
 73                     String uuid = UUID.randomUUID().toString();
 74                     //获取文件的后缀名
 75                     //String suffix = fileName.substring(fileName.lastIndexOf("."));
 76                     //获取文件上传目录路径,在项目部署路径下的upload目录里。若想让浏览器不能直接访问到图片,可以放在WEB-INF下
 77                     String uploadPath = request.getSession().getServletContext().getRealPath("/upload");
 78                     File file = new File(uploadPath);
 79                     file.mkdirs();
 80                     //将文件写入对应路径,并对文件进行重命名
 81                     fileItem.write(new File(uploadPath, uuid + "_"+ fileName));
 82                 }
 83                 /*
 84                  * 对表中的普通字段进行处理
 85                  */
 86                 if(fileItem.isFormField()) {
 87                     filedName = fileItem.getFieldName();
 88                     String username = null;
 89                     String pwd = null;
 90                     if("username".equals(filedName)) {
 91                         username = fileItem.getString("UTF-8");
 92                         out.println("用户名:" + username);
 93                     }
 94                     if("pwd".equals(filedName)) {
 95                         pwd = fileItem.getString("UTF-8");
 96                         out.println("\t密码:" + pwd);
 97                     }
 98                 }
 99             }
100         } catch (Exception e) {
101             // TODO Auto-generated catch block
102             e.printStackTrace();
103         }
104 
105     }
106     protected void doPost(HttpServletRequest request, HttpServletResponse response)
107             throws ServletException, IOException {
108         doGet(request, response);
109     }
110 }

文件下载

(1)列出提供下载的文件资源

要将Web应用系统中的文件资源提供给用户进行下载,首先我们要有一个页面列出上传文件目录下的所有文件,当用户点击文件下载超链接时就进行下载操作,编写一个ListFileServlet,用于列出Web应用系统中所有下载文件。

 1 package com.etc.utils;
 2 
 3 import java.io.File;
 4 import java.io.IOException;
 5 import java.util.HashMap;
 6 import java.util.Map;
 7 
 8 import javax.servlet.ServletException;
 9 import javax.servlet.annotation.WebServlet;
10 import javax.servlet.http.HttpServlet;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 
14 @WebServlet("/FileDownLoad")
15 public class FileDownLoad extends HttpServlet {
16     private static final long serialVersionUID = 1L;
17     public FileDownLoad() {
18         super();
19     }
20     
21     protected void doGet(HttpServletRequest request, HttpServletResponse response)
22             throws ServletException, IOException {
23         response.getWriter().append("Served at: ").append(request.getContextPath());
24         // 获取上传文件的目录
25         String uploadFilePath = this.getServletContext().getRealPath("/upload");
26         // 储存要下载的文件名
27         Map<String, String> fileMap = new HashMap<String, String>();
28         // 递归遍历fileMap目录下的所有文件和目录,将文件储存到map集合中
29         fileList(new File(uploadFilePath),fileMap);
30         //将Map集合发送到listfile.jsp页面进行显示
31         request.setAttribute("fileMap", fileMap);
32         request.getRequestDispatcher("/listfile.jsp").forward(request, response);
33     }
34 
35     public void fileList(File file, Map<String,String> fileMap) {
36         // 如果file代表的不是一个文件而是一个目录
37         if (!file.isFile()) {
38             File[] files = file.listFiles();
39             for (File file2 : files) {
40                 fileList(file2, fileMap);
41             }
42         } else {
43             /**
44              * 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
45              * file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:9349249849-88343-8344_timer.avi
46              * 那么file.getName().substring(file.getName().indexOf("_")+1)处理之后就可以得到timer.avi部分
47              */
48             String realName = file.getName().substring(file.getName().lastIndexOf("_")+1);
49             System.out.println(realName);
50             fileMap.put(file.getName(), realName);
51         }
52     }
53 
54     protected void doPost(HttpServletRequest request, HttpServletResponse response)
55             throws ServletException, IOException {
56         doGet(request, response);
57     }
58 }

(2)创建显示文件列表的jsp界面(listfile.jsp)

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
 4 <!DOCTYPE html>
 5 <html>
 6 <head>
 7 <meta charset="UTF-8">
 8 <link href="css/bootstrap.css" rel="stylesheet">
 9 <title>下载文件显示界面</title>
10 </head>
11 <body>
12     <div class="container">
13         <table class="table table-bordered">
14             <caption>文件下载列表</caption>
15             <c:forEach var="me" items="${requestScope.fileMap}">
16                 <tr>
17                     <c:url value="DownLoadServlet" var="downurl">
18                         <c:param name="filename" value="${me.key}"></c:param>
19                     </c:url>
20                 
21                     <td>${me.value}</td><td><a href="${downurl}">下载</a></td>
22                 </tr>
23             </c:forEach>
24         </table>
25     </div>
26 </body>
27 </html>

(3)实现文件下载的servlet

DownLoadServlet的代码如下:

 1 package com.etc.utils;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 import java.net.URLEncoder;
 9 
10 import javax.servlet.ServletException;
11 import javax.servlet.annotation.WebServlet;
12 import javax.servlet.http.HttpServlet;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 
16 import org.apache.commons.io.IOUtils;
17 
18 @WebServlet("/DownLoadServlet")
19 public class DownLoadServlet extends HttpServlet {
20     private static final long serialVersionUID = 1L;
21     
22     public DownLoadServlet() {
23         super();
24         // TODO Auto-generated constructor stub
25     }
26 
27     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
28         String fileName = request.getParameter("filename");
29         //获取文件路径
30         String fileSaveRootPath = this.getServletContext().getRealPath("/upload");
31         //获取真实的文件名
32         String realname = fileName.substring(fileName.indexOf("_")+1);
33         //得到要下载的文件
34         File file = new File(fileSaveRootPath+File.separator+fileName);
35         //如果文件不存在
36         if(!file.exists()) {
37             request.setAttribute("msg", "您要下载的文件已被删除!");
38             request.getRequestDispatcher("/message.jsp").forward(request, response);
39             return;
40         }
41         //设置响应头,控制浏览器下载该文件 可通过URLEncoder.encode(realname, "UTF-8")实现对下载的文件进行重命名
42         response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
43         //获取输入输出流
44         InputStream is = new FileInputStream(file);
45         OutputStream os = response.getOutputStream();
46         //调用common-io下面的静态方法,用于实现文件复制(从服务器端复制到本地)
47         IOUtils.copy(is, os);
48         is.close();
49     }
50 
51     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
52         doGet(request, response);
53     }
54 }

 

 

参考文章:http://blog.ncmem.com/wordpress/2023/12/13/common-fileupload%e7%bb%84%e4%bb%b6%e5%ae%9e%e7%8e%b0java%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/

欢迎入群一起讨论

 

 

标签:文件,fileupload,java,servlet,request,common,import,上传
From: https://www.cnblogs.com/songsu/p/17899693.html

相关文章

  • 无涯教程-Java - toString()函数
    该方法用于获取表示Number对象值的String对象。toString()-语法以下是此方法的所有变体-StringtoString()staticStringtoString(inti)这是参数的详细信息-i   - 将为其返回字符串表示形式的int。toString()-返回值toString()     - 这将返......
  • java 面向对象:类
    免责声明:java基础资料均来自于韩顺平老师的《循序渐进学Java零基础》教案,具体视频内容可以去B站观看,这些资料仅用于学习交流,不得转载用于商业活动1.java面向对象:类类与对象释义:类是抽象的,概念的,代表一类事物。例如人类,宠物类,即它是数据类型对象是具体的,实际的,代表一个具体的......
  • Docker容器中配置和启用Java Flight Recorder(JFR)
    1.简介和背景在Java应用程序性能调优中,JavaFlightRecorder(JFR)是一个非常强大的工具。它能够实时收集Java应用程序的运行数据,提供有关性能问题的深入见解。在Docker容器中使用JFR,可以更轻松地管理和监控应用程序性能。2.JFR的基本概念和工作原理JFR是Java的一项特性,它通过事件记......
  • Java GC日志分析
    阅读分析虚拟机和垃圾收集器的日志是处理Java虚拟机内存问题必备的基础技能。一、JDK统一日志格式垃圾收集器日志是一系列人为设定的规则,多少有点随开发者编码时的心情而定,没有任何的“业界标准”可言,换句话说,每个收集器的日志格式都可能不一样。除此以外还有一个麻烦,在JDK9以前......
  • Aapche Dubbo Java反序列化漏洞(CVE-2019-17564)
    AapcheDubboJava反序列化漏洞(CVE-2019-17564)漏洞描述ApacheDubbo是一款高性能、轻量级的开源JavaRPC服务框架。Dubbo可以使用不同协议通信,当使用http协议时,ApacheDubbo直接使用了Spring框架的org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter类做远程......
  • 无涯教程-Java - valueOf()函数
    valueOf方法返回相关的Number对象,其中包含传递的参数的值,参数可以是原始数据类型,字符串等。此方法是静态方法。该方法可以使用两个参数,其中一个是字符串,另一个是基数。valueOf()-语法以下是此方法的所有变体-staticIntegervalueOf(inti)staticIntegervalueOf(String......
  • 深入解析Kafka:Java开发者的必备利器
    摘要:本文将深入解析Kafka,探讨其核心概念、特性、使用场景以及如何使用Java进行Kafka的开发。通过图文并茂的方式,帮助读者更好地理解和掌握Kafka。一、Kafka简介Kafka是一个分布式流处理平台,由Apache开源。它提供了高吞吐量、低延迟、可扩展性和容错性的数据流处理能力,广泛应用于大......
  • JavaScript Library – Lit
    前言我写过一篇关于Lit的文章,MaterialDesign,AngularMaterial,MDC,MWC,Lit的关系。如今material-webMWC已经发布1.0了,估计Angular也会在不远的将来从material-components-webMDC迁移到MWC。以后,我们要想深入理解AngularMaterial就必须对MWC有一定了解......
  • 九,JAVA继承
    继承/extends子类继承父类后,子类可以获取父类中所有的非私有成员子类:被抽取共同成员的类,通常是多个类,Student,Worker父类共同成员所在的类,通常是少的一方,PersonJava中的类与类之间的继承是:单继承,支持多层继承Object类:上帝类,是所有类的父类java中如果一个类没有声......
  • Spring Boot应用启动 java -jar
    1.系统参数的标准格式为:-Dargname=argvalue,多个参数之间用空格隔开,如果参数值中间有空格,则用引号括起来#1.基本java-jarrun.jar#2.指定java路径nohup/opt/mdw/jdk1.8.0_241/bin/java-jarrun.jar#3.如果中文乱码,指定jar包的运行环境的编码java-Dfile.encoding=utf-8-......