文件上传
- 实现web开发中的文件上传功能,需完成如下二步操作:
- 在web页面中添加上传输入项
- 在servlet中读取上传文件的数据,并保存到本地硬盘中。
- 如何在web页面中添加上传输入项?
标签用于在web页面中添加文件上传输入项,设置文件上传输入项时须注意:
- 必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。
- 必须把form的++enctype属值设为multipart/form-data++.设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。
使用Commons-fileupload组件实现文件上传,需要导入该组件相应的支撑jar包:++Commons-fileupload和commons-io++。
//①创建解析工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//②创建解析器
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> list;
try {
//③调用解析器解析request
list = upload.parseRequest(request);
//④遍历解析数据
for(FileItem item:list){
if(item.isFormField()){
//普通输入项
String inputName = item.getFieldName();
String inputValue = item.getString();
System.out.println(inputName + "="+inputValue);
}else{
//文件输入项
String filename = item.getName().substring(item.getName().lastIndexOf("\\")+1);
InputStream in = item.getInputStream();
int len = 0;
byte buffer[] = new byte[1024];
FileOutputStream out = new FileOutputStream("d:\\"+filename);
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
注°
上传文件中文乱码问题
解决文件的乱码
ServletFileUpload.setHeaderEncoding(“UTF-8”)
解决普通输入项的乱码(注意,表单类型为multipart/form-data的时候,设置request的编码是无效的)
FileItem.setString(“UTF-8”); //解决乱码
- 在处理表单之前,要记得调用:
ServletFileUpload.isMultipartContent方法判断提交表单的类型,如果该方法返回true,则按上传方式处理,否则按照传统方式处理表单即可。 - 设置解析器缓冲区的大小,以及临时文件的删除
- 设置解析器缓冲区的大小 DiskFileItemFactory.setSizeThreshold(1024*1024);
- 临时文件的删除:在程序中处理完上传文件后,一定要记得调用item.delete()方法,以删除临时文件(一定要放在流关闭代码之后)
- 设置解析器缓冲区的大小 DiskFileItemFactory.setSizeThreshold(1024*1024);
- 限制上传文件的大小
调用解析器的ServletFileUpload.setFileSizeMax(1024*1024*5);
如果上传文件超出限制,则解析器会抛FileUploadBase.FileSizeLimitExceededException异常,程序员通过是否抓到这个异常,进而就可以给用户友好提示。
5. 为避免上传文件的覆盖,程序在保存上传文件时,要为每一个文件生成一个唯一的文件名
public String generateFileName(String filename){
return UUID.randomUUID().toString() + “_” + filename;
}
6. 为避免在一个文件夹下面保存超过1000个文件,影响文件访问性能,程序应该把上传文件打散后存储。
public String generateSavePath(String path,String filename){
int hashcode = filename.hashCode(); //121221
int dir1 = hashcode&15;
int dir2 = (hashcode>>4)&0xf;
String savepath = path + File.separator + dir1 + File.separator + dir2;
File file = new File(savepath);
if(!file.exists()){
file.mkdirs();
}
return savepath;
}
- 监听上传进度
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setProgressListener(new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("当前已解析:" + pBytesRead);
}
});
文件下载
Web应用中实现文件下载的两种方式
1. 超链接直接指向下载资源
2. 程序实现下载需设置两个响应头:
- 设置Content-Type 的值为:application/x-msdownload。
Web 服务器需要告诉浏览器其所输出的内容的类型不是普通的文本文件或 HTML文件,而是一个要保存到本地的下载文件。
- Web 服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这需要设置 Content-Disposition报头。该报头指定了接收程序处理数据内容的方式,在 HTTP 应用中只有 attachment 是标准方式,attachment 表示要求用户干预。在 attachment 后面还可以指定 filename 参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。在设置 Content-Dispostion 之前一定要指定 Content-Type.