文件上传简介1---上传到指定的目录
来源:互联网 发布:实对称矩阵对角化方法 编辑:程序博客网 时间:2024/05/17 23:59
preparation
本节摘要:本节主要介绍上传文件到指定目录。
引入:
文件上传是开发中常用的功能,本节主要介绍用commons-fileupload-1.1.jar包实现基本的文件上传功能,即上传文件到指定的目录中,同时介绍上传过程中使用到的相关类及其方法。
下载插件:
准备需要的jar包
* commons-fileupload-1.1.jar 文件上传jar包(必须导入)
* commons-io-1.2.jar (必须导入)如果不导入的程序编译时不会报错,但是发布后运行时会报错
* log4j-1.2.8.jar 强烈建议导入,但在本类中不是必须的,后面的上传文件到数据库中的类中会使用
* classes12.jar 连接oracle数据库的jar包,后面的上传文件到数据库中时必须导入
开发环境:
System:xp JDK:1.5(开发的JDK版本) Tomcat:5.X Myeclipse:6.5
注意:编译的JDK版本用JDK1.4(如果用JDK1.5编译,会报”Unsupported major.minor version 49.0”错误)
项目环境:
文件上传目录介绍:
在D盘根目录新建一个test文件夹,然后在test文件夹中新建以下两个文件夹
* temp:存放超过设置大小的文件(>2M的文件)
* uploadfile:上传文件的存放目录(<=2M的文件)
class&method:
*DiskFileItemFactory
* 实现了FileItemFactory接口
* 主要方法有:
* public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName)
* setRepository(File repository);设置缓存路径 也有相应的get方法
* setSizeThreshold(int sizeThreshold);设置上传文件内存缓冲区的大小 也有相应的get方法
*
* ServletFileUpload
* 从FileUpload继承,而FileUpload又从FileUploadBase继承
* ServletFileUpload(FileItemFactory fileItemFactory);传入一个fileItemFactory对象,构造ServletFileUpload对象
* List parseRequest(HttpServletRequest request);从request中获得文件请求列表
* void setSizeMax(long sizeMax);//设置允许上传文件大小 也有相应的get方法
* setHeaderEncoding(String encoding);//设置上传文件名编码的格式 也有相应的get方法
*
* Pattern
* 正则表达式的编译表示形式,指定为字符串的正则表达式必须首先被编译为此类的实例。
* 然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配
* static Pattern compile(String regex);将给定的正则表达式编译到模式中
* Matcher matcher(CharSequence input);创建匹配给定输入与此模式的匹配器,返回此模式的新匹配器
*
* FileItem
* 抽象接口,继承Serializable
* boolean isFormField();判断FileItem类对象封装的数据是否属于一个普通表单字段,
* 还是属于一个文件表单字段,如果是普通表单字段则返回true,否则返回false
* String getName();用于获得文件上传字段中的文件名
* String getFieldName();用于返回表单字段元素的name属性值
* long getSize();获得上传文件的大小 单位:字节
* getContentType();用于获得上传文件的类型
* void write(File paramFile);用于将FileItem对象中保存的主体内容保存到某个指定的文件中
*
* Matcher
* 通过解释 Pattern 对 character sequence 执行匹配操作的引擎。
* 通过调用模式的 matcher 方法从模式创建匹配器。创建匹配器后,可以使用它执行三种不同的匹配操作:
* matches方法尝试将整个输入序列与该模式匹配。
* lookingAt 尝试将输入序列从头开始与该模式匹配。
* find 方法扫描输入序列以查找与该模式匹配的下一个子序列。
* String group(int group)返回在以前匹配操作期间由给定组捕获的输入子序列
*
* String
* boolean endsWith(String suffix)测试此字符串是否以指定的后缀结束。
start
1.新建web项目UpDown,导入上面介绍的4个jar包
2.新建upload.html文件,用于上传的前台的UI界面
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2 <html> 3 <head> 4 <title>文件上传</title> 5 <meta name="Generator" content="EditPlus"> 6 <meta name="Author" content=""> 7 <meta name="Keywords" content=""> 8 <meta name="Description" content=""> 9 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 10 </head>11 12 <body>13 <h1>14 文件上传演示demo---上传到本机文件夹中(程序和上传目录在同一主机)15 </h1>16 <!-- 17 1.上传的内容有图片的时候,form中必须加入 ENCTYPE="multipart/form-data" 18 2.在<input>标签中必须有name属性(除了提交按钮submit),否则运行时虽然不会报错,但是文件无法成功上传19 -->20 <form name="uploadform" method="POST" action="upload"21 ENCTYPE="multipart/form-data">22 <table border="1" width="450" cellpadding="4" cellspacing="2"23 bordercolor="#9BD7FF">24 <tr>25 <td width="100%" colspan="2">26 文件1:27 <input name="a" size="40" type="file">28 </td>29 </tr>30 <tr>31 <td width="100%" colspan="2">32 文件2:33 <input name=b” " size="40" type="file">34 </td>35 </tr>36 <tr>37 <td width="100%" colspan="2">38 文件3:39 <input name="c" size="40" type="file">40 </td>41 </tr>42 43 </table>44 <br />45 <br />46 <table>47 <tr>48 <td align="center">49 <input name="upload" type="submit" value="开始上传" />50 </td>51 </tr>52 </table>53 </form>54 </body>55 </html>
3.新建servlet文件Upload.java文件,用于对上传的文件进行处理
1 package upload; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.PrintWriter; 6 import java.util.Iterator; 7 import java.util.List; 8 import java.util.regex.Matcher; 9 import java.util.regex.Pattern; 10 import javax.servlet.ServletException; 11 import javax.servlet.http.HttpServlet; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 import org.apache.commons.fileupload.FileItem; 15 import org.apache.commons.fileupload.FileUploadException; 16 import org.apache.commons.fileupload.disk.DiskFileItemFactory; 17 import org.apache.commons.fileupload.servlet.ServletFileUpload; 18 19 /**此程序是上传文件到指定的目录的一个小小的demo 20 * 有以下两个要求:(1)上传的文件不能超过文件指定的最大值(2)对有些后缀名的文件不能上传 21 */ 22 /** 23 *Module: Upload.java 24 *Description: 上传文件到指定的目录(程序和上传的目录在同一台主机) 25 *Company: XXX 26 *Author: ptp 27 *Date: Feb 6, 2012 28 */ 29 public class Upload extends HttpServlet { 30 31 // 定义常量,保存文件路径 32 private static final String FILE_PATH = "D:" + File.separator + "test" 33 + File.separator + "upload" + File.separator;// 文件上传的路径 34 35 private static final String FILE_TEMP = "D:" + File.separator + "test" 36 + File.separator + "temp" + File.separator;;// 文件缓存路径 37 38 public void doPost(HttpServletRequest request, HttpServletResponse response) 39 throws ServletException, IOException { 40 41 response.setContentType("text/html; charset=GB2312"); 42 43 PrintWriter out = response.getWriter(); 44 45 // ServletFileUpload.isMultipartContent(request); 46 // 可以处理之前用上面的方法检测request中是否有multipart内容,不过,已经是废弃的方法了 47 48 // 生成DiskFileItemFactory工厂 49 DiskFileItemFactory factory = new DiskFileItemFactory(); 50 51 // 对工厂进行相关的配置 52 // 设置最多只允许在内存中存储的数据,单位:字节 53 factory.setSizeThreshold(2048); 54 55 // 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录 文件缓存路径 【暂时没有实现这个功能】 56 //判断指定的目录是否存在,如果不存在则新建该目录,注意mkdirs()和mkdir()的区别: 57 //如果test不存在,用mkdir()程序会在后面会报错,用mkdirs()就不会报错 58 File fileTemp = new File(FILE_TEMP); 59 if (!fileTemp.exists()){ 60 fileTemp.mkdirs(); 61 } 62 File filePath1 = new File(FILE_PATH); 63 if (!filePath1.exists()) { 64 filePath1.mkdir();//此处可以用mkdir()方法,因为前面的代码执行后test目录一定存在 65 } 66 67 //设置缓存路径 68 factory.setRepository(fileTemp); 69 70 // 将DiskFileItemFactory对象传给ServletFileUpload构造方法,生成上传类ServletFileUpload的对象 71 ServletFileUpload sevletFileUpload = new ServletFileUpload(factory); 72 73 // 设置允许用户上传文件大小,单位:字节,这里设为2M 74 sevletFileUpload.setSizeMax(2 * 1024 * 1024); 75 76 // 设置编码,解决上传文件名乱码 77 sevletFileUpload.setHeaderEncoding("GB2312");/**按照JDK的介绍,此方法是解决上传文件名中文乱码问题,但是后面测试发现不能实现*/ 78 79 //获得允许用户上传文件大小 80 long maxSize = sevletFileUpload.getSizeMax(); 81 82 try { 83 /** 84 * 开始读取上传信息 从request中取到上传文件列表 85 * 超过了设置的最大值2M会报异常 86 * 文件缓存目录不存在也会报异常(前面已经对目录存在做了判断,所以不可能出现目录不存在报的情况) 87 */ 88 List fileItems = sevletFileUpload.parseRequest(request); 89 //调用上传文件的方法 90 if (null != fileItems) 91 upLoadFile(fileItems, out); 92 93 } catch (FileUploadException e) { 94 out.println("对不起,您上传的文件大小超过了允许的最大值" + maxSize / 1024 / 1024 + "M!"); 95 e.printStackTrace(); 96 } 97 } 98 99 /**100 * 上传文件101 * @param fileItems102 * @param out103 */104 public void upLoadFile(List fileItems,PrintWriter out){105 try{106 // 依次处理每个上传的文件107 Iterator iter = fileItems.iterator();108 109 // 正则匹配,过滤路径取文件名110 /*111 * $ 行的结尾 . 任何字符(与行结束符可能匹配也可能不匹配) + 一次或多次112 * \\\\匹配FILE_PATH中的\\,4个右斜杠转义后变为2个113 */114 String regExp = ".+\\\\(.+)$";115 116 // 过滤掉的文件类型117 String[] errorType = { ".exe", ".com", ".cgi", ".asp" };118 119 StringBuffer error=new StringBuffer();120 121 //拼接不能上传的文件类型,即字符串error,用于后面显示122 for(int i=0;i<errorType.length;i++){123 if (i == errorType.length - 1) {124 error.append(errorType[i] + "。");125 } else {126 error.append(errorType[i] + ",");127 }128 }129 130 Pattern p = Pattern.compile(regExp);//将给定的正则表达式regExp编译到模式中131 while (iter.hasNext()) {132 FileItem item = (FileItem) iter.next();133 /*忽略其他不是文件域的所有表单信息134 *isFormField()方法判断FileItem类对象封装的数据是否属于一个普通表单字段,135 *还是属于一个文件表单字段,如果是普通表单字段则返回true,否则返回false136 *只有是文件表单字段才能进入if中的代码137 */138 if (!item.isFormField()) {139 String name = item.getName();// 用于获得上传文件的名称,如:c:\documents and settings\administrator\桌面\test.txt140 long size = item.getSize();// 获得上传文件的大小141 if ((name == null || name.equals("")) && size == 0)// 文件表单为空或文件大小为0跳过本次循环,继续下一次循环142 continue;143 Matcher m = p.matcher(name);// 创建匹配给定输入与此模式的匹配器144 boolean result = m.find();// 方法扫描输入序列以查找与该模式匹配的下一个子序列145 if (result) {146 for (int temp = 0; temp < errorType.length; temp++) {147 if (m.group(1).endsWith(errorType[temp])) {148 throw new IOException("非法文件类型禁止上传,以下文件类型不能上传:"+error);149 }150 }151 try {152 153 //保存上传的文件到指定的目录154 File filePath=new File(FILE_PATH + m.group(1));155 item.write(filePath);156 157 //在页面上输出上传文件后的信息158 out.print(name + " " + size + "<br>");159 160 } catch (Exception e) {161 out.println(e);162 }163 } else {164 throw new IOException("上传文件失败");165 }166 }167 }168 } catch (IOException e) {169 out.println(e);170 }171 }172 173 public void doGet(HttpServletRequest request, HttpServletResponse response)174 throws ServletException, IOException {175 this.doPost(request, response);176 }177 }
4.配置web.xml文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 6 7 <servlet> 8 <servlet-name>upload</servlet-name> 9 <servlet-class>upload.Upload</servlet-class>10 </servlet>11 <servlet-mapping>12 <servlet-name>upload</servlet-name>13 <url-pattern>/upload</url-pattern>14 </servlet-mapping>15 16 </web-app>
5.发布项目
result
访问的URL如下:
http://localhost:8080/UpDown/upload.html
upload.html页面如下:
上传完成后跳转显示的页面如下:
检查指定的上传目录:
检查文件大小限制(上传一个大于2M的文件,然后点击”开始上传”,界面显示如下):
检查文件后缀名过滤(上传一个exe文件,然后点击”开始上传”,界面显示如下):
遗留&拓展部分:
* 1.中文乱码问题 IE界面显示乱码、上传目录乱码
* 2.上传目录和程序不在同一台主机上的处理方式
* 2.文件缓存问题
* 3.文件的端点续传功能
* 4.上传滚动条问题
answer
1.关于中文乱码问题的解决方法
经过测试以下语句设置为utf-8即可解决,设置为gbk或gb2312都无法解决中文乱码问题
sevletFileUpload.setHeaderEncoding("utf-8");
- 文件上传简介1---上传到指定的目录1
- 文件上传简介1---上传到指定的目录2
- 文件上传简介1---上传到指定的目录3
- 文件上传简介1---上传到指定的目录
- 上传文件到指定目录
- 用struts上传文件时创建目录以及把文件上传到指定的目录
- C#上传文件到网站指定目录
- 将上传文件保存到指定目录
- FCK的上传图片上传到我们指定的目录
- 本地文件上传到指定目录
- ftp上传文件及将文件上传到指定目录下(多层目录下)
- C# 上传文件到指定目录,单击下载文件,删除指定目录文件,打开文件列表
- 上传文件到指定的FTP服务器
- JAVA上传文件图片到指定服务器目录
- java 用ajaxFileUpload上传文件到指定目录
- PHP上传文件到指定目录(Zend Studio 12.5)
- JAVA上传文件图片到指定服务器目录
- HTML如何把文件上传到指定目录下
- C++虚函数编译分析
- C/C++函数指针传递和typedef的误区
- 利用js来通过复选框控制表格的长宽
- yuv and rgb
- 结构体的内存分配(对齐)
- 文件上传简介1---上传到指定的目录
- OCP-1Z0-052-V8.02-167题
- 转折后的总结--2014年找工作
- 虚拟类--动物描述
- OCP-1Z0-052-V8.02-166题
- 图片上按钮特效 热点链接(img map area)
- 华为机考回忆版(三:自己的)
- C++学习之旅——C++类型转换
- directx 编译书中带的源码出现无法解析的外部符号