使用fileupload实现文件上传(1)

一. fileupload组件工作原理

先来张图片, 帮助大家理解

fileupload核心API

1. DiskFileItemFactory
构造器
1) DiskFileItemFactory() // 使用默认配置
2) DiskFileItemFactory(int sizeThreshold, File repository)
  sizeThreshold 内存缓冲区, 不能设置太大, 否则会导致JVM崩溃
  repository 临时文件目录

2. ServletFileUpload
1) isMutipartContent(request) // 判断上传表单是否为multipart/form-data类型 true/false
2) parseRequest(request) // 解析request, 返回值为List<FileItem>类型
3) setFileSizeMax(long) // 上传文件单个最大值
4) setSizeMax(long) // 上传文件总量最大值
5) setHeaderEncoding(String) // 设置编码格式
6) setProgressListener(ProgressListener) // 设置监听器, 可以用于制作进度条

二. 使用fileupload实现文件上传

1. 编写JSP

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 2 <html>
 3 <head>
 4     <title>演示文件上传</title>
 5 </head>
 6 <body>
 7     <form action="${pageContext.request.contextPath}/servlet/FileUpload1" method="post" enctype="multipart/form-data">
 8         用户名: <input type="text" name="username"/><br/>
 9         文件1: <input type="file" name="file1"/><br/>
10         文件2: <input type="file" name="file2"/><br/>
11         <input type="submit"/>
12     </form>
13 </body>
14 </html>

要点:

1) 表单包含file类型输入项时, enctype属性必须设置为multipart/form-data

2) input:file必须指定name属性

3) 表单提交方式为post, 因为get请求无法携带大量数据

4) 若表单的提交方式为multipart/form-data, 那么在Servlet就无法使用getParameter方法获取表单数据, 可以通过获取客户机提交数据的输入流来获取所有上传数据, 然后进行解析.

1 // 获取客户机提交数据的输入流
2 request.getInputStream();

5) 解析数据难度较大, 一般不自己编写程序, 可以使用开源项目解析数据

2. 编写Servlet

 1 public class FileUpload1 extends HttpServlet {
 2     @Override
 3     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 4
 5         InputStream in = null;
 6         OutputStream out = null;
 7
 8         try {
 9             // 使用默认配置创建解析器工厂
10             DiskFileItemFactory factory = new DiskFileItemFactory();
11             // 获取解析器
12             ServletFileUpload upload = new ServletFileUpload(factory);
13             // 上传表单是否为multipart/form-data类型
14             if (!upload.isMultipartContent(request)) {
15                 return;
16             }
17             // 解析request的输入流
18             List<FileItem> fileItemList = upload.parseRequest(request);
19             // 迭代list集合
20             for (FileItem fileItem : fileItemList) {
21                 if (fileItem.isFormField()) {
22                     // 普通字段
23                     String name = fileItem.getFieldName();
24                     String value = fileItem.getString();
25                     System.out.println(name + "=" + value);
26                 } else {
27                     // 上传文件
28                     // 获取上传文件名
29                     String fileName = fileItem.getName();
30                     fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
31                     // 获取输入流
32                     in = fileItem.getInputStream();
33
34                     // 获取上传文件目录
35                     String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
36                     // 上传文件名若不存在, 则先创建
37                     File savePathDir = new File(savePath);
38                     if (!savePathDir.exists()) {
39                         savePathDir.mkdir();
40                     }
41
42                     // 获取输出流
43                     out = new FileOutputStream(savePath + "\\" + fileName);
44                     int len = 0;
45                     byte[] buffer = new byte[1024];
46                     while((len=in.read(buffer)) > 0) {
47                         out.write(buffer, 0, len);
48                     }
49                 }
50             }
51         } catch (Exception e) {
52             e.printStackTrace();
53         } finally {
54             if (in != null) {
55                 in.close();
56             }
57             if (out != null) {
58                 out.close();
59             }
60         }
61
62     }
63
64     @Override
65     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
66         doGet(req, resp);
67     }
68 }

1) 在WEB-INF中创建upload文件夹时. IDEA不会在out目录的WEB-INF中创建upload文件夹, 需要手动创建, 所以上面先检查upload文件夹是否存在

2) 在finally中关闭流时, 应该先检查流是否为null, 否则当上传表单不为multipart/form-data类型时, 执行return后再执行finally, 程序就会出现NPE

3) 记得在web.xml中配置servlet的映射路径

3. 测试

4. 使用浏览器抓包

三. 禁止别人访问上传文件目录

上传文件目录应该放在WEB-INF目录下, 禁止别人访问上传文件目录, 否则黑客可能通过上传脚本, 然后访问该脚本, 对网站发起攻击

举例:

1. 黑客上传一个JSP文件

test.jsp
1 <%
2     Runtime.getRuntime().exec("shutdown -s -t 200")  // 执行Windows命令
3 %>

2. 通过访问该文件, 关闭服务器

http://localhost:8080/upload/test.jsp

备注:

1) Runtime类  // 调用Windows程序

2) Window命令:

  shutdown -a
  format c:\

四. 待解决的问题

1. 中文文件名乱码问题
2. 上传文件目录, 文件存储个数 -> 使用Hash算法打散
3. 文件覆盖问题 -> 使用UUID作为文件名称

原文地址:https://www.cnblogs.com/shaohsiung/p/9536901.html

时间: 2024-10-12 03:21:54

使用fileupload实现文件上传(1)的相关文章

Spring MVC使用commons fileupload实现文件上传功能

通过Maven建立Spring MVC项目,引入了Spring相关jar依赖. 1.为了使用commons fileupload组件,需要在pom.xml中添加依赖: <properties> <spring.version>3.0.7.RELEASE </spring.version> <junit.version>3.8.1</junit.version> <fileupload.version>1.2.2</fileupl

完成FileUpload的文件上传功能,且可改按钮样式

FileUpload控件: 更改按钮样式思路: 自己定义一个按钮,设置该按钮的样式,然后将FileUpload控件通过定位定在自己定义的按钮上面,设置z-index,使得控件浮在自己定义的按钮上面,记得设置该控件为透明,这样,看着点的是自己定义的那个按钮,实际上点击的是控件,然后定义一个"上传"按钮,点击上传按钮时进入代码层: 上传文件思路: 1)确定上传文件所保存的路径: 2)判断路径是否存在,存在则继续,不存在则创建: 3)获取上传文件的上传路径 或者文件名 4)保存文件: 多文件

Apache Commons fileUpload实现文件上传之一

  需要两个jar包: commons-fileupload.jar Commons IO的jar包(本文使用commons-io-2.4.jar) 利用Servlet来实现文件上传. package web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http

Apache Commons FileUpload实现文件上传

Commons FileUpload简介 Apache Commons是一个专注于可重用Java组件开发的 Apache 项目.Apache Commons项目由三个部分组成: 1.Commons Proper - 可重用Java组件的存储库. 2.The Commons Sandbox - 用于Java组件开发的工作区. 3.The Commons Dormant - 当前不活动的组件存储库. Commons-FileUpload是Commons Proper中的一个组件,该组件依赖于Comm

配置fileupload(文件上传组件)

<properties> <commons-fileupload.version>1.3.1</commons-fileupload.version> </properties> <dependencyManagement> <dependencies> <!-- 文件上传组件 --> <dependency> <groupId>commons-fileupload</groupId>

SpringMVC使用FileUpload进行文件上传

导入FileUpload和common-io的Jar包 注意:1.Struts2需要使用其他方法:struts2过滤时,会改变reqeust的类型,由HttpServletRequest变成MultiPartRequestWrapper 1.Test.jsp: <form action="<%=basePath%>self/testFileUpload.do" method="post" enctype="multipart/form-d

zk FileUpload(文件上传)

<button label="上传 Image" upload="true,maxsize=1073741824"> <attribute name="onUpload"><![CDATA[ org.zkoss.util.media.Media media = event.getMedia(); String fileName = ""; if(media!=null) fileName = me

Using FileUpload(Apache文件上传组件)

Using FileUpload FileUpload can be used in a number of different ways, depending upon the requirements of your application. In the simplest case, you will call a single method to parse the servlet request, and then process the list of items as they a

fileupload文件上传

在使用java开发文件上传时,网络上有很多不一样的工具.但是每次如果都需要开发一次,对于使用者来说,这个过程是浪费时间的.所以我们有必要选取其中一个适合自己的文件上传组件,然后对其进一步分装,形成自己的开发工具类.下面我针对自己的工程,对fileupload进行了封装. fileupload是apache的一个组件,要想使用fileupload,需要用到下面两个jar:commons-fileupload-1.3.1.jar,commons-io-1.1.jar(版本不一样,可能相关jar包不一