import java.io.File; |
import java.io.IOException; |
import java.io.PrintWriter; |
import java.util.Iterator; |
import java.util.List; |
import java.util.regex.Matcher; |
import java.util.regex.Pattern; |
import javax.servlet.ServletException; |
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; |
/**上传文件 |
* 要求:(1)上传的文件不能超过文件指定的最大值(2)对有些后缀名的文件不能上传 |
*/ |
/** |
*Module: Upload.java |
*Description: 上传文件到指定的目录(程序和上传的目录在同一台主机) |
*Company: XXX |
*Author: ptp |
*Date: Feb 6, 2012 |
*/ |
public class Upload extends HttpServlet { |
// 定义常量,保存文件路径 |
private static final String FILE_PATH = "D:" + File.separator + "test" |
+ File.separator + "upload" + File.separator; // 文件上传的路径 |
private static final String FILE_TEMP = "D:" + File.separator + "test" |
+ File.separator + "temp" + File.separator;; // 文件缓存路径 |
public void doPost (HttpServletRequest request, HttpServletResponse response) |
throws ServletException, IOException { |
response.setContentType ( "text/html; charset=GB2312" ); |
PrintWriter out = response.getWriter(); |
// ServletFileUpload.isMultipartContent(request); |
// 可以处理之前用上面的方法检测request中是否有multipart内容,不过,已经是废弃的方法了 |
// 生成DiskFileItemFactory工厂 |
DiskFileItemFactory factory = new DiskFileItemFactory(); |
// 对工厂进行相关的配置 |
// 设置最多只允许在内存中存储的数据,单位:字节 |
factory.setSizeThreshold ( 2048 ); |
// 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录 文件缓存路径 【暂时没有实现这个功能】 |
//判断指定的目录是否存在,如果不存在则新建该目录,注意mkdirs()和mkdir()的区别: |
//如果test不存在,用mkdir()程序会在后面会报错,用mkdirs()就不会报错 |
File fileTemp = new File (FILE_TEMP); |
if (!fileTemp.exists() ) { |
fileTemp.mkdirs(); |
} |
File filePath1 = new File (FILE_PATH); |
if (!filePath1.exists() ) { |
filePath1.mkdir(); //此处可以用mkdir()方法,因为前面的代码执行后test目录一定存在 |
} |
//设置缓存路径 |
factory.setRepository (fileTemp); |
// 将DiskFileItemFactory对象传给ServletFileUpload构造方法,生成上传类ServletFileUpload的对象 |
ServletFileUpload sevletFileUpload = new ServletFileUpload (factory); |
// 设置允许用户上传文件大小,单位:字节,这里设为2M |
sevletFileUpload.setSizeMax ( 2 * 1024 * 1024 ); |
// 设置编码,解决上传文件名乱码 |
sevletFileUpload.setHeaderEncoding ( "GB2312" ); /**按照JDK的介绍,此方法是解决上传文件名中文乱码问题,但是后面测试发现不能实现*/ |
//获得允许用户上传文件大小 |
long maxSize = sevletFileUpload.getSizeMax(); |
try { |
/** |
* 开始读取上传信息 从request中取到上传文件列表 |
* 超过了设置的最大值2M会报异常 |
* 文件缓存目录不存在也会报异常(前面已经对目录存在做了判断,所以不可能出现目录不存在报的情况) |
*/ |
List fileItems = sevletFileUpload.parseRequest (request); |
//调用上传文件的方法 |
if ( null != fileItems) { |
upLoadFile (fileItems, out); |
} |
} catch (FileUploadException e) { |
out.println ( "对不起,您上传的文件大小超过了允许的最大值" + maxSize / 1024 / 1024 + "M!" ); |
e.printStackTrace(); |
} |
} |
/** |
* 上传文件 |
* @param fileItems |
* @param out |
*/ |
public void upLoadFile (List fileItems, PrintWriter out) { |
try { |
// 依次处理每个上传的文件 |
Iterator iter = fileItems.iterator(); |
// 正则匹配,过滤路径取文件名 |
/* |
* $ 行的结尾 . 任何字符(与行结束符可能匹配也可能不匹配) + 一次或多次 |
* \\\\匹配FILE_PATH中的\\,4个右斜杠转义后变为2个 |
*/ |
String regExp = ".+\\\\(.+)$" ; |
// 过滤掉的文件类型 |
String[] errorType = { ".exe" , ".com" , ".cgi" , ".asp" }; |
StringBuffer error = new StringBuffer(); |
//拼接不能上传的文件类型,即字符串error,用于后面显示 |
for ( int i = 0 ; i < errorType.length; i++) { |
if (i == errorType.length - 1 ) { |
error.append (errorType[i] + "。" ); |
} else { |
error.append (errorType[i] + "," ); |
} |
} |
Pattern p = Pattern.compile (regExp); //将给定的正则表达式regExp编译到模式中 |
while (iter.hasNext() ) { |
FileItem item = (FileItem) iter.next(); |
/*忽略其他不是文件域的所有表单信息 |
*isFormField()方法判断FileItem类对象封装的数据是否属于一个普通表单字段, |
*还是属于一个文件表单字段,如果是普通表单字段则返回true,否则返回false |
*只有是文件表单字段才能进入if中的代码 |
*/ |
if (!item.isFormField() ) { |
String name = item.getName(); // 用于获得上传文件的名称,如:c:\documents and settings\administrator\桌面\test.txt |
long size = item.getSize(); // 获得上传文件的大小 |
if ( (name == null || name.equals ( "" ) ) && size == 0 ) { // 文件表单为空或文件大小为0跳过本次循环,继续下一次循环 |
continue ; |
} |
Matcher m = p.matcher (name); // 创建匹配给定输入与此模式的匹配器 |
boolean result = m.find(); // 方法扫描输入序列以查找与该模式匹配的下一个子序列 |
if (result) { |
for ( int temp = 0 ; temp < errorType.length; temp++) { |
if (m.group ( 1 ).endsWith (errorType[temp]) ) { |
throw new IOException ( "非法文件类型禁止上传,以下文件类型不能上传:" + error); |
} |
} |
try { |
//保存上传的文件到指定的目录 |
File filePath = new File (FILE_PATH + m.group ( 1 ) ); |
item.write (filePath); |
//在页面上输出上传文件后的信息 |
out.print (name + " " + size + "<br>" ); |
} catch (Exception e) { |
out.println (e); |
} |
} else { |
throw new IOException ( "上传文件失败" ); |
} |
} |
} |
} catch (IOException e) { |
out.println (e); |
} |
} |
public void doGet (HttpServletRequest request, HttpServletResponse response) |
throws ServletException, IOException { |
this .doPost (request, response); |
} |
} |
中级程序员
by: 坏人 发表于:2013-06-24 21:34:16 顶(0) | 踩(0) 回复
回复评论