您的位置:首页 > 其它

文件上传----监听

2012-09-09 21:16 155 查看
一、文件上传

1、前提条件:

form表单提供input type="file"类型的输入域,必须有name属性

form表单的enctype属性取值为multipart/form-data

form表单的method提交方式为post方式

2、如果表单的enctype设置成了multipart/form-data,那么传统获取参数的方式就失效了。

3、上传文件的请求正文内容如下:

-----------------------------7dc22234707de

Content-Disposition: form-data; name="username"

wzt

-----------------------------7dc22234707de

Content-Disposition: form-data; name="photo1"; filename="C:\Documents and Settings\鐜嬫槶鐝絓妗岄潰\a.txt"

Content-Type: text/plain

aaaaaa

-----------------------------7dc22234707de

Content-Disposition: form-data; name="photo2"; filename="C:\Documents and Settings\鐜嬫槶鐝絓妗岄潰\b.txt"

Content-Type: text/plain

bbbbbb

-----------------------------7dc22234707de--

按照MIME协议进行描述的。

二、利用apache-commons-fileupload组件进行文件上传

1、所需jar包

commons-fileupload.jar

commons-io.jar

2、核心类

DiskFileItemFacotry:创建FileItem的工厂。

还能设置缓存大小(默认10k)和临时文件的存放路径

ServletFileUpload:解析请求的正文,得到代表表单某一部分的FileItem对象

FileItem:代表表单中的一个输入域

boolean isFormField():是否是普通表单数据

String getFieldName():得到普通输入域的名称

String getString():得到普通输入域提交的数据值

InputStream getInputStream():得到上传域的输入流

String getName():得到上传文件的名称

三、文件上传时需要考虑的9大问题

1、上传文件名的中文乱码和表单数据的中文乱码(传统的设置编码无效)

普通字段中文数据

FileItem.getString(编码)

上传文件名中文乱码:

方式一:request.setCharacterEncoding("UTF-8")

方式二:ServletFileUpload.setHeaderEncoding("UTF-8");

2、如何保证服务器的安全

把上传的文件放到用户访问不到的地方WEB-INF

3、多次上传同名文件的覆盖

UUID更改文件名,保证不重复

UUID_文件名

当前的毫秒值:(乐观者)

4、如何防止同一目录下文件太多的问题

分目录存储

hashcode算目录

1100 0011 1101 1100 0101 0001 1010 1101

0000 0000 0000 0000 0000 0000 0000 1111

0000 0000 0000 0000 0000 0000 0000 1101 0~15

1100 0011 1101 1100 0101 0001 1010 1101

0000 0000 0000 0000 0000 0000 1111 0000

0000 0000 0000 0000 0000 0000 1010 0000>>4

0000 0000 0000 0000 0000 0000 0000 1010 0~15

5、上传文件的大小控制(单个文件和总大小),及如何友好提示用户

单个文件:

单个文件大小限制:

ServletFileUpload.setFileSizeMax(字节)

超出了大小:FileUploadBase.FileSizeLimitExceededException异常

总文件大小:

ServletFileUpload.setSizeMax(字节)

超出了大小:FileUploadBase.SizeLimitExceededException异常

6、超出10k的文件的临时文件的处理

会出现临时文件。组件本身不会自动删除临时文件。

在上传完毕后,执行FileItem.delete()方法手工删除。

注意:关闭流后再删除

7、限制上传文件的类型

通过判断上传文件的扩展名来进行限制(不严格)

FileItem.getContentType():获取到MIME类型,通过这个进行过滤

图片的MIME类型都是以images开头

8、监听文件的上传进度

ServletFileUpload注册监听

9、用户没有选择文件上传时的问题

示例:

package com.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

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;

public class UploadServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);

request.setCharacterEncoding("UTF-8");

String inFilePath = getServletContext().getRealPath(
"\\WEB-INF\\upload\\");
String dirDate = DateFormat.getDateInstance().format(new Date());
inFilePath = inFilePath + "\\" + dirDate;

File file = new File(inFilePath);

if (!file.exists())
file.mkdirs();

try {
List<FileItem> list = upload.parseRequest(request);

for (FileItem item : list) {

if (item.isFormField()) {

String name = item.getFieldName();
String value = item.getString("UTF-8");
} else {

String fileType = item.getContentType();
String fileName = item.getName();

fileName = fileName
.substring(fileName.lastIndexOf("\\") + 1);

OutputStream out = new FileOutputStream(inFilePath + "\\"
+ UUID.randomUUID().toString() + "_" + fileName);

InputStream in = item.getInputStream();
byte[] buff = new byte[1024];
int len = -1;
while ((len = in.read(buff)) != -1) {
out.write(buff);
}
out.close();
in.close();
}
System.out.println("上传完成");
}

} catch (FileUploadException e) {
throw new RuntimeException("上传失败");
}
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

doGet(request, response);
}

}


四、Servlet规范中的监听

编写步骤:

a、编写一个类,实现特定的监听接口

b、在web.xml中进行注册监听

<listener>

<listener-class>com.itheima.listener.MyServletContextListener</listener-class>

</listener>

1、(3个)监听ServletContext、HttpSession、ServletRequest三个对象的创建和销毁

ServletContextListener

HttpSessionListener

ServletRequestListener

2、(3个)监听域对象中属性的增加和删除的事件监听器

ServletContextAttributeListener

HttpSessionAttributeListener

ServletRequestAttributeListener

3、(2)感知型监听器。(不需要注册)

HttpSessionBindingListener:感知自己被绑到了HttpSession域中了

HttpSessionActivationListener:感知自己激活和钝化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: