FileUpload上传的基本步骤
一、FileUpload与SmartUpload相比较有着很高的复杂度,
1、创建磁盘工厂: DiskFileFactory factory = new DiskFileFactory();
2、创建处理工具: ServletFileUpload upload = new ServletFileUpload(factory);
3、设置上传文件大小:upload.setFileSizeMax(3145728);
4、接受全部内容: List<Filetem> items = upload.parseRequest(request);
在FileUpload中,不管是基本数据还是上传的文件,只要是上传了,则一切的操作都是按照FileItem表示出来,都通过List一起接收。
FileUpload中最烦的部分就是接受,因为混在一起了。
<%-- 表单页面 --%> <html> <head> <title>欢迎光临</title> </head> <body> <form action="fileupload_1.jsp" method="post" enctype="multipart/form-data"> 名称: <input type="text" name="uname"><br> 照片: <input type="file" name="pic"><br> <input type="submit" value="上传"> <input type="reset" value="重置"> </form> </body> </html>
<%@ page contentType="text/html" pageEncoding="gb2312"%> <%@ page import="java.util.*"%> <%@ page import="org.apache.commons.fileupload.*"%> <%@ page import="org.apache.commons.fileupload.disk.*"%> <%@ page import="org.apache.commons.fileupload.servlet.*"%> <html> <head> <title>欢迎光临</title> </head> <% request.setCharacterEncoding("gb2312"); %> <body> <% DiskFileItemFactory factory = new DiskFileItemFactory(); //创建磁盘工厂 ServletFileUpload upload = new ServletFileUpload(factory); //创建处理工具 upload.setFileSizeMax(3*1024*1024); //设置上传文件3M大小 List<FileItem> items = upload.parseRequest(request); //接收全部内容(图片、文字..) Iterator<FileItem> iter = items.iterator(); while(iter.hasNext()) { FileItem item = iter.next(); String fname = item.getFieldName();//取得表单控件的名字 %> <ul><h3><%=fname%>---><%=item.isFormField()%><h3> <% if(!item.isFormField()) { //不是普通文本 String fileName = item.getName(); //取得文件名称 String contentType = item.getContentType(); //取得文件类型 long sizeInBytes = item.getSize(); // %> <li>上传文件名称:<%=fileName%> <li>上传文件类型:<%=contentType%> <li>上传文件大小:<%=sizeInBytes%> <% } else { String value = item.getString(); %> <li>普通参数: <%=value%> <% } %> </ul> <% } %> </body> </html>
Filetem 中的 boolean isFormField() 来判断是文件或是图片
除了接收文件,还要保存文件。如果是批量上传,一定要有自动命名的操作
为文件上传自动命名
如果多个用户上传的文件的名称一样,则肯定会发生覆盖的情况,为了解决这种问题,可以采用为上传文件自动命名的方式,为了防止重名,自动命名可以采用如下的格式:
1、IP地址+时间戳+三位随机数
2、例如: 现在练级的IP地址是:192.168.2.3 ; 日期时间是: 2011-11-1 01:41:24.043 ; 三位随机数是:200, 则拼凑出的新文件名称就是:
19216800200320111101014124043200.文件后缀 下面此类适用于ipv4
<%-- fileupload_1.html--%> package com.demo; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; // 文件随机自动命名 public class IPTimeStamp { private SimpleDateFormat sdf = null; private String ip = null; public IPTimeStamp() {} public IPTimeStamp(String ip) { this.ip = ip; } public String getIPTimeRand() { StringBuffer buf = new StringBuffer(); if(this.ip != null) { String s[] = this.ip.split("\\."); for(int i=0; i<s.length; i++) { buf.append(this.addZero(s[i],3)); } } buf.append(this.getTimeStamp()); Random r = new Random(); //后面随机数 加 3位 for(int i=0; i<3; i++) { buf.append(r.nextInt(10)); //所有的数不超过 10 } return buf.toString(); } //返回时间戳 public String getDate() { this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); return this.sdf.format(new Date()); } public String getTimeStamp() { this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); return this.sdf.format(new Date()); } private String addZero(String str,int len) { StringBuffer s = new StringBuffer(); s.append(str); while(s.length() < len) { s.insert(0,"0"); } return s.toString(); } public static void main(String args[]) { System.out.println(new IPTimeStamp("192.168.2.3").getIPTimeRand()); } }
_______________________________________________________________________________________________________
以下是由IPV6地址运行,进行批量上传
<%-- fileupload_2.jsp ---%> <%@ page contentType="text/html" pageEncoding="gb2312"%> <html> <head> <title>欢迎光临</title> </head> <body> <form action="fileupload_2.jsp" method="post" enctype="multipart/form-data"> 名称: <input type="text" name="uname"><br> 照片: <input type="file" name="pic1"><br> 照片: <input type="file" name="pic2"><br> 照片: <input type="file" name="pic3"><br> <input type="submit" value="上传"> <input type="reset" value="重置"> </form> </body> </html>
<%-- fileupload_2.jsp ---%> <%@ page contentType="text/html" pageEncoding="gb2312"%> <%@ page import="java.util.*,java.io.*"%> <%@ page import="org.apache.commons.fileupload.*"%> <%@ page import="org.apache.commons.fileupload.disk.*"%> <%@ page import="org.apache.commons.fileupload.servlet.*"%> <%@ page import="com.demo.*"%> <html> <head> <title>欢迎光临</title> </head> <% request.setCharacterEncoding("gb2312"); %> <body> <% DiskFileItemFactory factory = new DiskFileItemFactory(); //创建磁盘工厂 factory.setRepository(new File(this.getServletContext().getRealPath("/")+"uploadtemp")); //保存临时文件 ServletFileUpload upload = new ServletFileUpload(factory); //创建处理工具 upload.setFileSizeMax(3*1024*1024); //设置上传文件3M大小 List<FileItem> items = upload.parseRequest(request); //接收全部内容(图片、文字..) Iterator<FileItem> iter = items.iterator(); IPtimeStamp its = new IPtimeStamp(request.getRemoteAddr()); while(iter.hasNext()) { FileItem item = iter.next(); String fname = item.getFieldName();//取得表单控件的名字 %> <ul><h3><%=fname%>---><%=item.isFormField()%><h3> <% if(!item.isFormField()) { //不是普通文本 File saveFile = null; InputStream input = null; OutputStream output = null; input = item.getInputStream(); output = new FileOutputStream(new File(this.getServletContext().getRealPath("/")+"upload" + File.separator + its.getIPtimeRand() + "." + item.getName().split("\\.")[1])); int temp = 0; byte data[] = new byte[512]; while((temp=input.read(data,0,512)) != -1) { output.write(data); //分块保存 } input.close(); output.close(); %> <% } else { String value = item.getString(); %> <li>普通参数: <%=value%> <% } %> </ul> <% } %> </body> </html>
// IPV6 文件随机自动命名 package com.demo; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; public class IPtimeStamp { private SimpleDateFormat sdf = null; private String ip = null; public IPtimeStamp() {} public IPtimeStamp(String ip) { this.ip = ip; } public String getIPtimeRand() { StringBuffer buf = new StringBuffer(); if(this.ip != null) { String s[] = this.ip.split("\\:|\\%"); //用正则表达式解析ipv6地址 fe80::f442:fa63:14f1:9057%10 for(int i=0; i<s.length; i++) { buf.append(this.addZero(s[i],4)); } } buf.append(this.getTimeStamp()); Random r = new Random(); //后面随机数 加 3位 for(int i=0; i<3; i++) { buf.append(r.nextInt(10)); //所有的数不超过 10 } return buf.toString(); } //返回时间戳 public String getDate() { this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); return this.sdf.format(new Date()); } public String getTimeStamp() { this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); return this.sdf.format(new Date()); } private String addZero(String str,int len) { StringBuffer s = new StringBuffer(); s.append(str); while(s.length() < len) { s.insert(0,"0"); } return s.toString(); } public static void main(String args[]) { System.out.println(new IPtimeStamp("fe80::f442:fa63:14f1:9057%10").getIPtimeRand()); } }
FileUpload 的问题
在实际操作上对于这种组件存在以下几个不便之处:
1、无法像使用request.getParameter()方法那样准确的取得提交的参数
2、无法像使用request.getParameterValues() 那样准确的取得一组提交参数
3、所有的上传文件都需要进行依次的判断,才能给分别保存,不能依次性批量保存
针对如上问题,因此得到如下包装类
FileUploadTool 类 (包装可以完成自动上传的工具类) 以下是方法
1、 public FileUploadTools(HttpServletRequest request, int maxSize, String tempDir) throws Exception 类型--> 构造 描述 --> 实例化FileUpload类,并接收request对象、最大上传文件限制、上传临时保存目录路径
2、public String getParameter(String name) 类型--> 普通 描述 --> 根参数名称取得参数内容
3、 public String[] getParameterValues(String name) 类型--> 普通 描述 --> 根参数名称,取得一组参数内容
4、public Map<String, FileItem> getUploadFiles() 类型--> 普通 描述 --> 取得全部的上传文件
5、public List<String> savaAll(String saveDir) throws IOException 类型---> 普通 描述 --> 自动保存全部的上传文件,并将已上传文件的名称返回给调用处
转至 FileUpload上传的基本步骤 2