【19】文件上传与下载

文件上传与下载

一、文件上传

1.应用场景

招聘网站、email等

2.上传条件

  • 必须使用post请求,因为get请求最大为1kb
  • 表单默认会对提交数据进行URL编码,对文件(二进制数据)无效,需要改变enctype的属性值为multipart/form-data,数据将以流形式上传
    <form enctype="application/x-www-form-urlencoded">//默认,进行URL编码
    <form enctype="multipart/form-data">//带附件,二进制字节流形式,不进行URL编码
    //此时request.getParameter方法将无法获取到表单的数据
  • 使用流技术获取用户上传的数据相当麻烦

3.使用Fileupload框架

  • 导入commons-fileupload-1.2.1.jar包和commons-io-1.4.jar包(Apache组织的)
  • 工作原理
    • 浏览器发出请求信息—>WEB服务器将它封装到Request对象中
    • DiskFileItemFactory—>ServletFileupLoad—解析Request—>FileItem
  • 使用
DiskFileItemFactory factory = new DiskItemFactory();//创建文件对象工厂
factory.setSizeThreshold(1024*100);//临时文件最大存储控件,默认为10k,这里设置为100k,当文件小于这个值时就使用临时内存,否则用临时目录存
factory.setRepository(File tmpFile);//设置临时目录存储
ServletFileUpload servletFileUpload = new ServletFileUpload(factory);//创建文件上传解析器
boolean flag= servletFileupload.isMultipartContent(request);//判断客户端是否以文件形式/规则上传数据
List<FileItem> list = servletFileupload.parseRequest(request);//解析Request
for(FileItem item:list){
    if(item.isFormField()){ //判断该表单项是否为普通的文本表单项
        item.getFieldName();//获取表单项的name属性值
        item.getString([String encoding]);//获取表单项的value属性值
    }else{
        item.getName();//获取上传的文件名
        InputStream in = item.getInputStream();//获取文件的输入流对象
        item.delete();//删除暂存问件
    }
}
  • 注意

    • 上传的文件是到服务器中的,不是到开发的工程目录
    • 上传到WebRoot目录下的文件外界是可以直接访问到的,包括可执行的文件,这是相当危险的。所以,应该移动到WEB-INF目录,因为这个目录只有服务器程序可以访问。当然如果非得放到WebRoot中的话可以在web.xml中配置映射加以保护。
    • 解决相同文件名的文件覆盖问题

      文件名改为:UUID+源文件名+后缀名。UUID的生成:根据CPU id和当前时间戳计算出来的,全球唯一。

    • 文件保存的位置问题:

    getServletContext().getRealPath("/WEB-INF/images");
    //获取该路径对应服务器的真实路径,因为文件是存在服务器中的,而不是存在项目工程的!
    • 解决同一文件夹文件过多导致的“卡机”问题–打散目录存储

      • 以日期打散,每一天生成一个目录
      • 以文件的首字母打散,首字母相同的放到同一个目录
      • 哈希打散,文件名的哈希码值
        * 得到文件名的哈希值的十六进制
      • 获取十六进制的前面n位生成n级目录
    • 限制用户上传的文件大小

    setFileSizeMax(size);//设置每个表单项的上传最大大小
    setSizeMax(size);//设置整个表单的上传最大大小
    //如果要提示用户的话,要将提示信息保存到request域中,再请求转发

二、文件下载

1.设置响应头

response.setHeader("content-disposition", "attachement;filename="+URLEncoder.encode(fileName, "UTF-8"));

2.输出流

response.getOutputStream();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值