目前文件上传的(框架)组件: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. scala单元测试,包括功能测试和性能测试

    十分简单的scala单元测试 在编写性能要求高的模块的时候,单元测试是有必要的,通过搜索,我找到了一套提供单元功能测试和性能测试的可行方案,该方案简单好用,推荐给大家. 测试工具 首先找到适用于sca ...

  2. 一文读懂:超详细正态分布方差等于o的推导

    (uv)' = [(u+△u)(v+△v) - uv] /△x = (v△u+u△v +△u△v)/△x = v(△u/△x) + u(△v/△x) +(△u△v)/△x =u'v+uv'

  3. Redis为什么是单线程

    转自:https://www.zhihu.com/question/23162208 https://www.zhihu.com/question/55818031:加了一些个人的理解. Redis为 ...

  4. linux常见命令整理

    Linux管理文件和目录的命令 命令 功能 命令 功能 pwd 显示当前目录 ls 查看目录下的内容 cd 改变所在目录 cat 显示文件的内容 grep 在文件中查找某字符 cp 复制文件 touc ...

  5. hdu2680 choose the best route

    题目 题意:给定一个有向图,多个起点,一个终点,求起点到终点的最短路. 这道题TLE了好多次,两侧次的对比主要在于对起点的处理上,法一:最开始是采用的hdu2066--一个人的旅行,这道题的方法做的, ...

  6. A SQL to insert continuous values

    I need a table to store all the working days. I dont like loop, so I tried sql. The following is the ...

  7. python中的 += 与 +

    这一部分首先要理解python内存机制,Python中万物皆对象. 对于不可变对象,改变了原来的值,其别名(变量名)绑定到了新值上面,id肯定会改变 对于可变对象,+ 操作改变了值,id肯定会变,而+ ...

  8. MYC编译器源码之词法分析

    前文  .NET框架源码解读之MYC编译器 和 MYC编译器源码分析之程序入口 分别讲解了 SSCLI 里示例编译器的架构和程序入口,本文接着分析它的词法分析部分的代码. 词法解析的工作都由Tok类处 ...

  9. 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构

    本篇承接上篇内容,如果你不小心点击进来,建议重新从第一篇开始完整阅读. 构建NetCore应用框架之实战篇索引 一.BitAdminCore框架简介 从前篇论述我们知道,我们接下来将要去做一个管理系统 ...

  10. c#实现AOP

    AOP:面向切面编程,通过预编译方式或运行期动态代理实现程序功能的中统一处理业务逻辑的一种技术,比较常见的场景是:日志记录,错误捕获.性能监控等 AOP详解:https://www.cnblogs.c ...