一、Apache Commons-FileUpload简介

Apache Commons是一个专注于可重用Java组件的所有方面的 Apache 项目。
Apache Commons项目由三个部分组成:

  • Commons Proper - 可重用Java组件的存储库。
  • The Commons Sandbox - 用于Java组件开发的工作区。
  • The Commons Dormant - 当前不活动的组件存储库。

Commons-FileUpload是Commons Proper中的一个组件,该组件依赖于Commons-IO ,Commons-IO也是 Commons Proper中的一个组件。
Commons FileUpload的JAR包下载
Commons IO的JAR包下载

二.maven依赖

<!-- upload file -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>

三.前端界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% String path = request.getContextPath(); %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>upload</title>
</head>
<br>
<br> <form action="<%=path%>/device/uploadFile" method ="post" enctype="multipart/form-data">
<input type ="file" name ="doc1"><br><br>
<input type ="file" name ="doc2"><br><br>
<input type ="text" name = info><br><br>
<input type ="password" name ="password"><br><br> <input type="submit" value="提交">
</form> <body> </body>
</html>

四.后台代码

@RequestMapping(value="/uploadFile")
public String uploadFile(final HttpServletRequest request, final HttpServletResponse response){ request.setAttribute("msg", "Not first time!");
//创建一个“硬盘文件条目工厂”对象
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置阈值,设置JVM一次能够处理的文件大小(默认吞吐量是10KB)
factory.setSizeThreshold(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD);
//设置临时文件的存储位置(文件大小大于吞吐量的话就必须设置这个值,比如文件大小:1GB ,一次吞吐量:1MB)
factory.setRepository(new File("d:\\test"));
//创建核心对象
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//设置最大可支持的文件大小(10MB)
fileUpload.setFileSizeMax(1024*1024*10);
//设置转换时使用的字符集
fileUpload.setHeaderEncoding("UTF-8");
if(ServletFileUpload.isMultipartContent(request)){
try {
List<FileItem> fileItems = fileUpload.parseRequest(request);
for ( FileItem fileItem : fileItems) {
if(fileItem.isFormField()){//判断该FileItem为一个普通的form元素
//获取字段名
String fieldName = fileItem.getFieldName();
//获取字段值,并解决乱码
String fieldValue = fileItem.getString("UTF-8");
System.out.println(fieldName +" : " + fieldValue); }else{//判断该FileItem为一个文件 System.out.println("Start to uplaod file!");
//获取文件名
String fileName = fileItem.getName();
System.out.println("fileName : " + fileName);
//获取文件大小
long fileSize = fileItem.getSize();
System.out.println("fileSize : " + fileSize); fileItem.write(new File("D://test//upload"+File.separator +fileName));
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} return "device/uploadFile";
}

五。异常

catch(FileUploadBase.SizeLimitExceededException ex){
out.print("上传失败,文件太大,单个文件的最大限制是:"+upload.getSizeMax()+"bytes!");
}

1.其中需要注意的是流的操作,和File类的操作,mkdirs()和mkdir()的区别是什么?它们都是用来创建文件夹的,区别在mkdirs能创建多级目录,而mkdir()只能创建当前的文件夹,如果发现上一层目录并还没有创建时,它也会无动于衷,什么也不干,也就不能创建当前文件夹,必须先要创建了上一级文件夹才可以。

2.上面还有很多的问题需要解决,比如上传文件名的乱码问题,比如单表内容的乱码问题,比如上传文件同名问题,如果上传的文件很大,该如何进行处理,比如,放在同一级目录下的文件过多如何处理。每次都自己手动写输出流,将内容存到指定位置,太过麻烦,等等问题,现在写一个加强版,在解决上面所有的问题。

3.上传文件名乱码问题:使用servletFileUpload.setHeaderEncoding("UTF-8");或者request.setCharacterEncoding("UTF-8")都可以

4.表单内容乱码问题:使用getString("utf-8")即可,也就是在获取内容时,就可以设置码表。

5.上传文件同名问题:使用UUID.randomUUID().toString().replace("-", "").获得一个独一无二的32位数字

6.使用FileUtils.copyInputStreamToFile(is, file);来将内容输出到指定路径文件中去,mkdirs() 自动创建目录

7.同一级目录下的文件过多问题:创建多级目录,通过文件名的hashcode的值,hashCode为int型,占4个字节,一个字节占8位,也就是占32位,将其分组,4位4位一组,就能分8组,每一次代表一层目录,也就能够分8层目录,每一层中,有可以创建16种不同的文件夹。这样算下来,就能有很多很多个文件夹了,每个文件夹下面都可以存很多文件,看我们的业务需求,来决定要创建几层目录,就从hashcode中拿几组数据出来。原理图如下

            

 生成两级目录

public class StringUtils {

    /**
* 生成二级目录
* @param fileName abc.txt
* @return /4/5
*/
public static String getDir(String fileName) {
//1 hashCode值
int hashCode = fileName.hashCode();
System.out.println(hashCode);
//2 第一层 0xf表示15的16进制数。
int dir1 = hashCode & 0xf;
//3 第二层目录
int dir2 = hashCode >>> 4 & 0xf; //4 拼写
return "/" + dir1 + "/" + dir2;
} public static void main(String[] args) {
System.out.println(getDir("abc.txt"));
} }

总结上传:

        其实理解了也不是很难,就是上传文件后的处理比较麻烦,各种小问题,存储过程最为麻烦。

        1、创建工厂类

        2、使用核心类,

        3、解析request请求,

        4、遍历请求体的内容,将上传内容和普通表单内容都获取出来

        5、获取到上传内容时,对其存储位置进行设置

        其中很多细节问题都在上面已经说清楚了,代码中也有很多注释。

Apache Commons FileUpload实现文件上传的更多相关文章

  1. Apache Commons fileUpload实现文件上传之一

      需要两个jar包: commons-fileupload.jar Commons IO的jar包(本文使用commons-io-2.4.jar) 利用Servlet来实现文件上传. package ...

  2. Apache Commons FileUpload 实现文件上传

    Commons FileUpload简介 Apache Commons是一个专注于可重用Java组件开发的 Apache 项目.Apache Commons项目由三个部分组成: 1.Commons P ...

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

    通过Maven建立Spring MVC项目,引入了Spring相关jar依赖. 1.为了使用commons fileupload组件,需要在pom.xml中添加依赖: <properties&g ...

  4. zt对于C#中的FileUpload解决文件上传大小限制的问题设置

    对于C#中的FileUpload解决文件上传大小限制的问题设置 您可能没意识到,但对于可以使用该技术上载的文件的大小存在限制.默认情况下,使用 FileUpload 控件上载到服务器的文件最大为 4M ...

  5. 使用fileupload实现文件上传

    一. fileupload组件工作原理 先来张图片, 帮助大家理解 fileupload核心API 1. DiskFileItemFactory构造器1) DiskFileItemFactory() ...

  6. FileUpload实现文件上传(包含多文件)

    package com.hzml.serve; import java.io.File; import java.io.IOException; import java.io.PrintWriter; ...

  7. asp.net web常用控件FileUpload(文件上传控件)

    FileUpload控件的主要中能:向指定目录上传文件,该控件包括一个文本框和一个浏览按钮. 常用的属性:FileBytes,FileContent.FileName.HasFile.PostedFi ...

  8. zk FileUpload(文件上传)

    <button label="上传 Image" upload="true,maxsize=1073741824"> <attribute n ...

  9. extjs采用fileupload进行文件上传后台实现

    前台js: form: Ext.define("GS.base.BasicImportForm",{    extend:"Ext.form.Panel",   ...

随机推荐

  1. winrunner 测试工具

    WinRunner在项目中的作用     (winrunner测试设计:http://blog.chinaunix.net/uid/301743/year-2013-list-81.html?/178 ...

  2. Innodb的redo log block

  3. 在evernote中如何使序号正常连续?

    答: 在二级内容之前按Shift + Enter键,再次换行即可序号正常,示例如下: 1. 第一行(在此处按下Shift+Enter键) 第一行第一列(在此处按下Shift+Enter键) 第一行第二 ...

  4. post 发送方式

    /** * post 方式 解码 */ public static String getWebContentByPost(String urlString, String data, final St ...

  5. [LeetCode] 685. Redundant Connection II 冗余的连接之 II

    In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) f ...

  6. ASP.NET Core Restful Web API 相关资源索引

    GraphQL 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上) 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下) [视频] 使用ASP.NET C ...

  7. .Net Core 1.1 + CentOs 7 环境配置

    centos7下使用yum安装mysql5.7.10 参考:http://www.cnblogs.com/hwd-cnblogs/p/5213337.html http://www.jb51.net/ ...

  8. 最新 物易云通java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.物易云通等10家互联网公司的校招Offer,因为某些自身原因最终选择了物易云通.6.7月主要是做系统复习.项目复盘.Leet ...

  9. Influx Sql系列教程四:series/point/tag/field

    influxdb中的一条记录point,主要可以分为三类,必须存在的time(时间),string类型的tag,以及其他成员field:而series则是一个measurement中保存策略和tag集 ...

  10. Python: ImportRequestsError: No module named 'requests'解决方法

    运行Python程序时,出现下面错误: import requests  ModuleNotFoundError: No module named ‘requests’ 原因:没有导入requests ...