目前文件上传的(框架)组件:Apache----fileupload 、Orialiy – COS – 2008() 、Jsp-smart-upload – 200M。

用fileupload上传文件:

需要导入第三方包:

Apache-fileupload.jar – 文件上传核心包。

Apache-commons-io.jar – 这个包是fileupload的依赖包。同时又是一个工具包。

核心类:

DiskFileItemFactory – 设置磁盘空间,保存临时文件。只是一个具类。

ServletFileUpload  - 文件上传的核心类,此类接收request,并解析reqeust

  ServletFileUpload.parseRequest(request);  --List<FileItem>   解析request

      一个FileItem就是一个标识分隔符开始 到结束。如下图:

查看DiskFileItemFactory源代码,可知

If not otherwise configured, the default configuration values are as
follows:
Size threshold is 10KB.
Repository is the system default temp directory, as returned by
System.getProperty("java.io.tmpdir")

可知,如果不设置临时目录,会保存在默认的临时目录-  System.getProperty("java.io.tmpdir");这个目录正是windows系统的临时文件存放目录,通过环境变量,可找到这个目录

这里存放着许多临时文件。

单文件上传Servlet:

package com.lhy.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List; 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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; @WebServlet(name="Up2Servlet",urlPatterns="/Up2Servlet")
public class Up2Servlet extends HttpServlet{ @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTf-8");
//获取tomcat下的up目录的路径
String path = getServletContext().getRealPath("/up");
//临时文件目录
String tmpPath = getServletContext().getRealPath("/tmp"); //检查我们是否有文件上传请求
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
//1,声明DiskFileItemFactory工厂类,用于在指定磁盘上设置一个临时目录
DiskFileItemFactory disk = new DiskFileItemFactory(1024*10,new File(tmpPath));
//2,声明ServletFileUpload,接收上边的临时文件。也可以默认值
ServletFileUpload up = new ServletFileUpload(disk);
//3,解析request
try {
List<FileItem> list = up.parseRequest(req);
//如果就一个文件,
FileItem file = list.get(0);
//获取文件名:
String fileName = file.getName();
//获取文件的类型:
String fileType = file.getContentType();
//获取文件的字节码:
InputStream in = file.getInputStream();
//文件大小
int size = file.getInputStream().available();
//声明输出字节流
OutputStream out = new FileOutputStream(path+"/"+fileName);
//文件copy
byte[] b = new byte[1024];
int len = 0;
while((len=in.read(b))!=-1){
out.write(b, 0, len);
}
out.flush();
out.close(); //删除上传生成的临时文件
file.delete(); //显示数据
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
pw.println("文件名:"+fileName);
pw.println("文件类型:"+fileType);
pw.println("<br/>文件大小(byte):"+size);
} catch (FileUploadException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} } }

from:

<form action="<%=basePath%>Up2Servlet" method="post" enctype="multipart/form-data">
File1:<input type="file" name="txt"><br/>
<input type="submit"/>
</form>

临时文件:

服务端:

响应:

实际项目中都是有文件服务器的,公司一般都提供了上传到文件服务器接口,有的是上传一个file类型,有的是流。

多文件上传Servlet:

package com.lhy.upload;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; 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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils; @WebServlet(name="Up3Servlet",urlPatterns="/Up3Servlet")
public class Up3Servlet extends HttpServlet{ @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTf-8");
String path = getServletContext().getRealPath("/up");
//临时文件目录
String tmpPath = getServletContext().getRealPath("/tmp");
//声明disk
DiskFileItemFactory disk = new DiskFileItemFactory();
disk.setSizeThreshold(1024*1024);
disk.setRepository(new File(tmpPath));
//声明解析requst的servlet
ServletFileUpload up = new ServletFileUpload(disk);
try{
//解析requst
List<FileItem> list = up.parseRequest(req);
//声明一个list<map>封装上传的文件的数据
List<Map<String,String>> ups = new ArrayList<Map<String,String>>();
for(FileItem file:list){
Map<String,String> mm = new HashMap<String, String>();
//获取文件名
String fileName = file.getName();
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
String fileType = file.getContentType();
InputStream in = file.getInputStream();
int size = in.available();
//使用工具类
// FileUtils.copyInputStreamToFile(in,new File(path+"/"+fileName));
//file 的方法可以直接写出文件
file.write(new File(path+"/"+fileName));
mm.put("fileName",fileName);
mm.put("fileType",fileType);
mm.put("size",""+size); ups.add(mm);
file.delete();
}
req.setAttribute("ups",ups);
//转发
req.getRequestDispatcher("/jsps/show.jsp").forward(req, resp); }catch(Exception e){
e.printStackTrace();
}
} }

表单:

<form name="xx" action="<%=basePath%>Up3Servlet" method="post" enctype="multipart/form-data">
<table id="tb" border="1">
<tr>
<td>
File:
</td>
<td>
<input type="file" name="file">
<button onclick="_del(this);">删除</button>
</td>
</tr>
</table>
<br/>
<input type="button" onclick="_submit();" value="上传">
<input onclick="_add();" type="button" value="增加">
</form>

js

<script type="text/javascript">
function _add(){
var tb = document.getElementById("tb");
//写入一行
var tr = tb.insertRow();
//写入列
var td = tr.insertCell();
//写入数据
td.innerHTML="File:";
//再声明一个新的td
var td2 = tr.insertCell();
//写入一个input
td2.innerHTML='<input type="file" name="file"/><button onclick="_del(this);">删除</button>';
}
function _del(btn){
var tr = btn.parentNode.parentNode;
//alert(tr.tagName);
//获取tr在table中的下标
var index = tr.rowIndex;
//删除
var tb = document.getElementById("tb");
tb.deleteRow(index);
}
function _submit(){
//遍历所的有文件
var files = document.getElementsByName("file");
if(files.length==0){
alert("没有可以上传的文件");
return false;
}
for(var i=0;i<files.length;i++){
if(files[i].value==""){
alert("第"+(i+1)+"个文件不能为空");
return false;
}
}
document.forms['xx'].submit();
}
</script>

show.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<p>以下是你上传的文件</p>
<c:forEach items="${ups}" var="mm">
文件名:${mm.fileName}<br/>
类型:${mm.fileType}<br/>
大小:${mm.size}(bytes)
<hr/>
</c:forEach>
</body>
</html>

测试,上传3张图片:

up目录L:

响应:

多文件上传,如果是同一个文件,会覆盖以前的,需要重命名,具体自己实现吧,如用uuid

//获取扩展
String extName = fileName.substring(fileName.lastIndexOf("."));//.jpg
//UUID
String uuid = UUID.randomUUID().toString().replace("-", "");
//新名称
String newName = uuid+extName;


限制只能上传图片:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String path = getServletContext().getRealPath("/up");
//项目里建的临时目录,存放临时文件,linux适用
String tmpPath = getServletContext().getRealPath("/tmp");
DiskFileItemFactory disk =
new DiskFileItemFactory(1024*10,new File(tmpPath));
ServletFileUpload up = new ServletFileUpload(disk);
try{
List<FileItem> list = up.parseRequest(req);
//只接收图片*.jpg-iamge/jpege.,bmp/imge/bmp,png,
List<String> imgs = new ArrayList<String>();
for(FileItem file :list){
if(file.getContentType().contains("image/")){
String fileName = file.getName();
//如果是原始方式Servlet上传,IE:c:\\xxx\\aa.jpg,但是用框架ie也是aa.jpg,这句没啥用好似
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
//获取扩展
String extName = fileName.substring(fileName.lastIndexOf("."));//.jpg
//UUID
String uuid = UUID.randomUUID().toString().replace("-", "");
//新名称
String newName = uuid+extName; FileUtils.copyInputStreamToFile(file.getInputStream(),
new File(path+"/"+newName));
//放到list
imgs.add(newName);
}
file.delete();
}
req.setAttribute("imgs",imgs);
req.getRequestDispatcher("/jsps/imgs.jsp").forward(req, resp);
}catch(Exception e){
e.printStackTrace();
} }

imgs.jsp:显示上传的图片

<body>
<p>图片是:</p>
<c:forEach items="${imgs}" var="img">
<img src="<c:url value='/up/${img}'/>"></img>
</c:forEach>
</body>


处理表单域中普通的input:

指定表单的enctype="multipart/form-data" 后,表单将会以二进制请求,普通的input 用request.getParameter("xxx");为null,fileupload能很方便处理普通表单域:

FileItem接口方法:

 void

delete()
          删除保存在临时目录中的文件。

 

 

String

getContentType()  获取文档的类型
          Returns the
content type passed by the browser or null if not defined.

String

getFieldName() 获取字段的名称,即name=xxxx
          Returns the name
of the field in the multipart form corresponding to this file item.

<input type=”file” name=”img”/>

InputStream

getInputStream()
          Returns an InputStream that can be
used to retrieve the contents of the file.

String

getName()
          Returns the original
filename in the client's filesystem, as provided by the browser (or other
client software).

获取文件名称。

如果是在IE获取的文件为 c:\aaa\aaa\xxx.jpg –即完整的路径。

非IE;文件名称只是 xxx.jpg

 

long

getSize()  获取文件大小 相当于in.avilivable();
          Returns the size
of the file item

如果你上传是一普通的文本元素,则可以通过以下方式获取元素中的数据

<form enctype=”multipart/form-data”>

    <input
type=”text” name=”name”/>

String

getString()  用于获取普通的表单域的信息。
          Returns the
contents of the file item as a String, using the default character encoding.(IOS-8859-1)

String

getString(String encoding) 可以指定编码格式
          Returns the
contents of the file item as a String, using the specified encoding.

void

write(File file) 直接将文件保存到另一个文件中去。
          A convenience
method to write an uploaded item to disk.

以下文件用判断一个fileItem是否是file(type=file)对象或是text(type=text|checkbox|radio)对象:

 boolean

isFormField()  如果是text|checkbox|radio|select这个值就是true.
          Determines
whether or not a FileItem instance represents a simple form field.

Servlet:

package com.lhy.upload;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID; 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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; @WebServlet(name="UpDescServlet",urlPatterns="/UpDescServlet")
public class UpDescServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//可以获取中文的文件名
request.setCharacterEncoding("UTF-8");
//项目真实路径
String path = getServletContext().getRealPath("/up");
//声明disk
DiskFileItemFactory disk = new DiskFileItemFactory();
disk.setRepository(new File("D:/tmp"));//临时文件目录
try{
//声明解析requst的servlet
ServletFileUpload up = new ServletFileUpload(disk);
//解析requst
List<FileItem> list = up.parseRequest(request);
//声明一个map用于封装信息
Map<String,Object> img = new HashMap<String, Object>();
for(FileItem file:list){
//第一步:判断是否是普通的表单项
if(file.isFormField()){
//可以读取多个普通的input
String fileName = file.getFieldName();//<input type="text" name="desc">=desc
String value = file.getString("UTF-8");//默认以ISO方式读取数据
System.err.println(fileName+"="+value);
//放入图片的说明
img.put(fileName,value);
}else{//说明是一个文件
String fileName = file.getName();//以前的名称
//处理文件名
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
img.put("oldName",fileName);
//修改名称
String extName = fileName.substring(fileName.lastIndexOf("."));
String newName =
UUID.randomUUID().toString().replace("-", "")+extName;
//保存新的名称
img.put("newName",newName);
file.write(new File(path+"/"+newName));
System.err.println("文件名是:"+fileName);
System.err.println("文件大小是:"+file.getSize());
img.put("size",file.getSize());
file.delete();
}
}
//将img=map放到req
request.setAttribute("img",img);
//转发
request.getRequestDispatcher("/jsps/desc.jsp").forward(request, response);
}catch(Exception e){
e.printStackTrace();
}
} }

form表单:

<form action="<c:url value='/UpDescServlet'/>" method="post"
enctype="multipart/form-data">
你的图片:<input type="file" name="img"><br />
说明:<input type="text" name="desc"/><br/>
说明2:<input type="text" name="desc2"/><br/>
<input type="submit" />
</form>

desc.jsp:

<body>
<p>请选择图片:名称(以前的名称oldName),顯示這張圖片newName。图片大小size,图片的说明desc</p>
${img.oldName}<br/>
${img.size}<br/>
${img.desc}<br/>
${img.desc2} <br/>
<img width="300" height="300" src="<c:url value='/up/${img.newName}'/>"></img>
<hr/>
<p>url:http://localhost:8080/day22/jsps/desc.jsp
<img width="300" height="300" src="<c:url value='/up/8.jpg'/>"/>
</body>
</html>



性能提升?使用FileItemIterator上传:

package com.lhy.upload;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date; 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 org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils; @WebServlet(name="FastServlet",urlPatterns="/FastServlet")
public class FastServlet extends HttpServlet{ @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
long start = new Date().getTime();
req.setCharacterEncoding("UTF-8");
String path = getServletContext().getRealPath("/up");
DiskFileItemFactory disk = new DiskFileItemFactory();
try {
ServletFileUpload up = new ServletFileUpload(disk);
//迭代器模式
FileItemIterator iter = up.getItemIterator(req);
while(iter.hasNext()){
FileItemStream item = iter.next();
String fileName = item.getName();
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
InputStream in = item.openStream();
FileUtils.copyInputStreamToFile(in, new File(path+"/"+fileName));
}
} catch (Exception e) {
e.printStackTrace();
}
long end = new Date().getTime();
System.out.println(end - start);
} }

不知道能不能提升性能,我分别用这个和上边的上传了一个myeclipse2014安装包1.1G,用上传前后的毫秒差计算,结果显示这个耗时100930,上边的方法耗时54240,并没有提升性能反而满了,迭代器模式不知道能不能提升性能,。。

限制上传文件的大小:

ServletFileUpload类的方法:

1:限制总文件的大小 。    如 上传10文件,设置最多总上传大小为100M。

void

setSizeMax(long sizeMax)
          Sets the maximum
allowed size of a complete request, as opposed to setFileSizeMax(long).

2:设置第每一个文件的大小 ,如果设置每 一个文件大小10M。

 void

setFileSizeMax(long fileSizeMax)
          Sets the maximum
allowed size of a single uploaded file, as opposed to getSizeMax().

两者一般设置一个就行了,可以catch到这个异常给提示信息。

ServletFileUpload up = new ServletFileUpload(disk);
//限制总文件的大小,如果上传多个文件
up.setSizeMax(1024*1024*100);//限制上传最大100M
//设置第每一个文件的大小 两者有一个即可
// up.setFileSizeMax(1024*1024);

有些上传插件,如插件fileuploadify 在页面就可以限制上传文件。

java文件上传-使用apache-fileupload组件的更多相关文章

  1. 实现文件上传功能(FileUpload组件)

    文件上传: 项目中经常用到文件上传. 自己实现文件上传,使用文件上传组件fileupload组件 1.指定表单类型为文件上传, enctype=”multipart/form-data” 2.提交方式 ...

  2. java文件上传下载 使用SmartUpload组件实现

    使用SmartUpload组件实现(下载jsmartcom_zh_CN.jar) 2017-11-07 1.在WebRoot创建以下文件夹,css存放样式文件(css文件直接拷贝进去),images存 ...

  3. MVC文件上传-使用jQuery.FileUpload和Backload组件实现文件上传

    本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: 处理文件上传的服务端组件Backload 用于处理文件上传的服务端组件 ...

  4. 2013第38周日Java文件上传下载收集思考

    2013第38周日Java文件上传&下载收集思考 感觉文件上传及下载操作很常用,之前简单搜集过一些东西,没有及时学习总结,现在基本没啥印象了,今天就再次学习下,记录下自己目前知识背景下对该类问 ...

  5. JAVA文件上传 ServletFileUpLoad 实例

    1.  jsp <%@ page language="java" contentType="text/html" pageEncoding="u ...

  6. 小兔Java教程 - 三分钟学会Java文件上传

    今天群里正好有人问起了Java文件上传的事情,本来这是Java里面的知识点,而我目前最主要的精力还是放在了JS的部分.不过反正也不麻烦,我就专门开一贴来聊聊Java文件上传的基本实现方法吧. 话不多说 ...

  7. java文件上传-原始的Servlet方式

    前言: 干了这几个项目,也做过几次文件上传下载,要么是copy项目以前的代码,要么是百度的,虽然做出来了,但学习一下原理弄透彻还是很有必要的.刚出去转了一圈看周围有没有租房的,在北京出去找房子是心里感 ...

  8. java文件上传工具包

    java 文件上传工具包 主要有两个方法:单文件上传和多文件上传 @Slf4j public class UploadFileUtil { //上传单张图片 public String uploadP ...

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

    简介:文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...

随机推荐

  1. 使用百度webuploader实现大文件上传

    版权所有 2009-2018荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...

  2. 20155225 2016-2017-2 《Java程序设计》第九周学习总结

    20155225 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 JDBC入门 了解JDBC架构 使用JDBC API JDBC是用于执行SQL的解决方案,开 ...

  3. CodeForces - 589J —(DFS)

    Masha has recently bought a cleaner robot, it can clean a floor without anybody's assistance. Schema ...

  4. 日期类的加减及java中所以日期类的操作算法大全

    1.计算某一月份的最大天数 1Calendar time=Calendar.getInstance();2time.clear();3time.set(Calendar.YEAR,year); //y ...

  5. Firemonkey里触发home按键被按下的事件

    吾八哥我最近在使用Delphi里的Firemonkey平台写一个叫“由由密码管家”的APP工具,是跨多平台的,如ios/android/windows/macOs.由于是用于密码管理的,那么在手机里操 ...

  6. ActiveMQ5.0实战三:使用Spring发送,消费topic和queue消息

    实战一 , 实战二 介绍了ActiveMQ的基本概念和配置方式. 本篇将通过一个实例介绍使用spring发送,消费topic, queue类型消息的方法. 不懂topic和queue的google 之 ...

  7. LeetCode140:Word Break II

    题目: Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where e ...

  8. LeetCode143:Reorder List

    题目: Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must d ...

  9. 创建/读取/删除Session对象

    //创建Session对象 Session["userName"] = "顾德博";//保存,这里可以存储任意类型的数据,包括对象.集合等 Session.Ti ...

  10. JS 中的数据类型

    简介 JavaScript 语言的每一个值,都属于某一种数据类型.JavaScript 的数据类型,共有七种 数值(number):整数和小数,比如1和3.14 字符串(string):文本 布尔值( ...