设为首页 收藏本站
查看: 1223|回复: 0

[经验分享] java文件上传-使用apache-fileupload组件

[复制链接]

尚未签到

发表于 2017-12-24 16:52:19 | 显示全部楼层 |阅读模式


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

用fileupload上传文件:
  需要导入第三方包:
  Apache-fileupload.jar – 文件上传核心包。
  Apache-commons-io.jar – 这个包是fileupload的依赖包。同时又是一个工具包。
DSC0000.png

  核心类:
  DiskFileItemFactory – 设置磁盘空间,保存临时文件。只是一个具类。
  ServletFileUpload  - 文件上传的核心类,此类接收request,并解析reqeust
  ServletFileUpload.parseRequest(request);  --List<FileItem>   解析request
  一个FileItem就是一个标识分隔符开始 到结束。如下图:
DSC0001.png

  查看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系统的临时文件存放目录,通过环境变量,可找到这个目录
DSC0002.png DSC0003.png

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

单文件上传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>
  
@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>  
//声明输出字节流
  
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;");
  
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>
  

DSC0004.png

  临时文件:
DSC0005.png

  服务端:
DSC0006.png

  响应:
DSC0007.png

  实际项目中都是有文件服务器的,公司一般都提供了上传到文件服务器接口,有的是上传一个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>

  
@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>  
//使用工具类
  
//        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 border="1">
  
<tr>
  
<td>
  
File:
  
</td>
  
<td>
  
<input type="file" name="file">

  
<button>  
</td>
  
</tr>
  
</table>
  
<br/>

  
<input type="button">
  
<input>  
</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>删除</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.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">   
  
<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张图片:
DSC0008.png

  up目录L:
DSC0009.png

  响应:
DSC00010.png

  多文件上传,如果是同一个文件,会覆盖以前的,需要重命名,具体自己实现吧,如用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 theoriginal
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>
如果你上传是一普通的文本元素,则可以通过以下方式获取元素中的数据

<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>

  

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>  
<hr/>
  
<p>url:http://localhost:8080/day22/jsps/desc.jsp
  
<img>  
</body>
  
</html>
  

DSC00011.png

DSC00012.png


性能提升?使用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>

  
@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>setFileSizeMax(long).
  2:设置第每一个文件的大小 ,如果设置每 一个文件大小10M。

void

  setFileSizeMax(long fileSizeMax)
  
          Sets the maximum
allowed>getSizeMax().
  两者一般设置一个就行了,可以catch到这个异常给提示信息。
  

ServletFileUpload up = new ServletFileUpload(disk);  

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

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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-427565-1-1.html 上篇帖子: Apache Shiro 简单概念 下篇帖子: Apache ZooKeeper 服务启动源码解释
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表