文件上传和下载

文件上传和下载

文件上传

  • 实现web开发中的文件上传功能,需完成如下二步操作
    • 在web页面中添加上传输入项
    • 在servlet中读取上传文件的数据,并保存到本地硬盘中。
  • 如何在web页面中添加上传输入项?
    • <input type=“file”>标签用于在web页面中添加文件上传输入项,设置文件上传输入项时须注意:
    • 必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。
    • 必须把form的enctype属值设为multipart/form-data.设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理

可以使用Request对象提供了一个getInputStream方法,但是会特步麻烦。因此,Apache 开源组织提供了一个用来处理表单文件上传的一个开源组件(Commons-fileupload),该组件性能优异,并且其API使用极其简单,可以让开发人员轻松实现web文件上传功能,因此在web开发中实现文件上传功能,通常使用Commons-fileupload组件实现

  • Commons-fileupload组件使用

需要导入Commons-fileupload和commons-io

image

核心API--DiskFileItemFactory

DiskFileItemFactory 是创建 FileItem 对象的工厂,这个工厂类常用方法:

public void setSizeThreshold(int sizeThreshold)

  • 设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时, fileupload组件将使用临时文件缓存上传文件。

public void setRepository(java.io.File repository)

  • 指定临时文件目录,默认值为System.getProperty("java.io. tmpdir").

public DiskFileItemFactory(int sizeThreshold, java.io. File repository)

  • 构造函数

  • 核心API--ServletFileUpload

ServletFileUpload 负责处理上传的文件数据,并将表单中每个输入项封装成一个 FileItem 对象中。常用方法有:

  • boolean isMultipartContent(HttpServletRequest request)

判断上传表单是否为multipart/form-data类型

  • List parseRequest(HttpServletRequest request)

解析request对象,并把表单中的每一个输入项包装成一个fileItem对象,并返回一个保存了所有FileItem的list集合

  • setFileSizeMax(long fileSizeMax)

设置上传文件的最大值

  • setSizeMax(long sizeMax)

设置上传文件总量的最大值

  • setHeaderEncoding(java.lang.String encoding)

设置编码格式

  • setProgressListener(ProgressListener pListener)

设置进度条

public class UploadServlet3 extends HttpServlet {

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

		try{
			
			//1.得到解析器工厂
			DiskFileItemFactory factory = new DiskFileItemFactory();
			
			//2.得到解析器
			ServletFileUpload upload = new ServletFileUpload(factory);
			
			//3.判断上传表单的类型
			if(!upload.isMultipartContent(request)){
				//上传表单为普通表单,则按照传统方式获取数据即可
				return;
			}
			
			//为上传表单,则调用解析器解析上传数据
			List<FileItem> list = upload.parseRequest(request);  //FileItem
			
			//遍历list,得到用于封装第一个上传输入项数据fileItem对象
			for(FileItem item : list){
				
				if(item.isFormField()){
					//得到的是普通输入项
					String name = item.getFieldName();  //得到输入项的名称
					String value = item.getString();
					System.out.println(name + "=" + value);
				}else{
					//得到上传输入项
					String filename = item.getName();  //得到上传文件名  C:\Documents and Settings\ThinkPad\桌面\1.txt
					filename = filename.substring(filename.lastIndexOf("\\")+1);
					InputStream in = item.getInputStream();   //得到上传数据
					int len = 0;
					byte buffer[]= new byte[1024];
					
					//用于保存上传文件的目录应该禁止外界直接访问
					String savepath = this.getServletContext().getRealPath("/WEB-INF/upload");
					System.out.println(savepath);
					
					FileOutputStream out = new FileOutputStream(savepath + "\\" + filename);  //向upload目录中写入文件
					while((len=in.read(buffer))>0){
						out.write(buffer, 0, len);
					}
					
					in.close();
					out.close();
				}
			}
			
			
		
		
		}catch (Exception e) {
			e.printStackTrace();
		}

		
	}

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

		doGet(request, response);
	}

}
  • 注意问题:
  1. 上传文件名的中文乱码和上传数据的中文乱码

upload.setHeaderEncoding("UTF-8"); //解决上传文件名的中文乱码

//表单为文件上传,设置request编码无效,只能手工转换

1.1 value = new String(value.getBytes("iso8859-1"),"UTF-8");

1.2 String value = item.getString("UTF-8");

  1. 为保证服务器安全,上传文件应该放在外界无法直接访问的目录

  2. 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名

  3. 为防止一个目录下面出现太多文件,要使用hash算法打散存储

  4. 要限制上传文件的最大值,可以通过:

ServletFileUpload.setFileSizeMax(1024)方法实现,并通过捕获:FileUploadBase.FileSizeLimitExceededException异常以给用户友好提示

  1. 想确保临时文件被删除,一定要在处理完上传文件后,调用item.delete方法

  2. 要限止上传文件的类型:在收到上传文件名时,判断后缀名是否合法

8、监听文件上传进度:

ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setProgressListener(new ProgressListener(){
                public void update(long pBytesRead, long pContentLength, int arg2) {
                    System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
                }
            });
  1. 在web页面中动态添加文件上传输入项
function addinput(){
            var div = document.getElementById("file");

            var input = document.createElement("input");
            input.type="file";
            input.name="filename";

            var del = document.createElement("input");
            del.type="button";
            del.value="删除";
            del.onclick = function d(){
                this.parentNode.parentNode.removeChild(this.parentNode);
            }


            var innerdiv = document.createElement("div");


            innerdiv.appendChild(input);
            innerdiv.appendChild(del);

            div.appendChild(innerdiv);
        }

文件下载

response.setContentType("application/x-msdownload");
String str="attachment;filename="+URLEncoder.encode(fileName,"UTF-8“);
response.setHeader("Content-Disposition",str)

用response.getOutputStream方法返回 ServeltOutputStream 对象来向客户端 写入文件内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值