JavaWeb-文件的上传与下载

一、文件的上传与下载
  1. 上传前提:
    • 表单的提交方式必须为post!! enctype必须是"multipart/form-data"--->指示正文内容是使用MIME协议进行描述的
    • 必须提供:<input type="file"  name="f1"/>
    • 对比:enctype="application/x-www-form-urlencoded",正文中的内容是:username=shan&password=123
    • 如果enctype的类型是:multipart/form-data,那么传统的request.getParamter(String)会失效
    • enctype=multipart/form-data描述正文的方式如下:
      • enctype="multipart/form-data"描述正文的方式如下:

      • -----------------------------7dc167160938
      • Content-Disposition: form-data; name="username"

      • admin
      • -----------------------------7dc167160938
      • Content-Disposition: form-data; name="f1"; filename="C:\Documents and Settings\鐜嬫槶鐝絓妗岄潰\a.txt"
      • Content-Type: text/plain                  MIME类型

      • aaaaa
      • -----------------------------7dc167160938
      • Content-Disposition: form-data; name="f2"; filename="C:\Documents and Settings\鐜嬫槶鐝絓妗岄潰\b.txt"
      • Content-Type: text/plain

      • bbbbb
      • -----------------------------7dc167160938--
  2. 利用第三方组件进行文件上传(上传步骤)
    • 先导入两个jar包:commons-io-1.4-bin.zipcommons-fileupload-1.2.2-bin.zip
    • 得到DiskFileItemFactory:设置临时目录和缓存大小。可以使用默认的
      • DiskFileItemFactory  factory = new  DiskFileItemFactory();
    • 得到ServletFileUpload:文件上传组件(也就是正文解析器)
      • ServletFileUpload   upload = new  ServletFileUpload( factory );
    • 判断用户表单是否是  multipart/form-data 类型的?
      • boolean  isMultipart  =   upload .isMultipart();
    • 是,解析request,得到List<FileItem>
      • List<FileItem>  items = upload.parseRequest( request );
    • 遍历items,判断FileItem,如果是普通字段,打印出来;如果是上传文件,把文件保存到某个目录中.
      • 普通字段:由item.getFiledName() 和 item.getString("UTF-8") 获得表单提交的字段名和值.
      • 上传文件:通过InputStream和OutputStream来完成上传,中间还要通过getName()获取文件的路径并正确截取该路径,而且还需要考虑上传文件重名的问题,详述在下
  3. 上传文件时要考虑的9个问题
    1. 文件名和表单数据的中文乱码问题?(传统方式已失效)
      • 普通字段:通过FileItem的  getString("UTF-8")
      • 文件名中文:
        • 方式一:request.setCharacterEncoding("UTF-8").
        • 方式二:upload.setHeaderEncoding("UTF-8");
    2. 如何保证服务器的安全?
      • 把上传的文件放到用户无法直接访问的地方  WEB-INF
    3. 文件的重名问题? ====>可以把文件进行改名:保证文件名唯一即可。
      • 方式一:当前时间System.currentTime..+"_"+a.txt(乐观主意,同一毫秒值没有传同一资源的用户)
      • 方式二:UUID.randomUUID().toString()+"_"+fileName.substring(fileName.indexOf("\\")+1); UUID保证文件名的唯一(推荐)
    4. 如何防止同一目录下文件太多的问题?
      • 分开目录分别存储 images
        • 方式一:(乐观主义)2012-11-11/a.txt把每天上传的文件放到一个日期的文件夹中
        • 方式二:利用HashCode算法打散存储文件夹,使用二级目录存放:images/dir1/dir2/a.txt
        • hashCode算法:
        • 0110 0111 1010 1111 0101 0001 1100 1010
        • &0xf
        • 0000 0000 0000 0000 0000 0000 0000 1111
        • -------------------------------------------------
        • 0000 0000 0000 0000 0000 0000 0000 1010
        • 转换为整数:0~15  16个
        • -------------------------------------------------------------------
        • 0110 0111 1010 1111 0101 0001 1100 1010
        • &0xf0
        • 0000 0000 0000 0000 0000 0000 1111 0000
        • -------------------------------------------------
        • 0000 0000 0000 0000 0000 0000 1100 0000
        • >>4
        • 0000 0000 0000 0000 0000 0000 0000 1100
        • 转换为整数:0~15  16个
        • -------------------------------------------------------------------
    5. 上传文件的大小控制?及如何友好提示?
      • 单个文件的大小控制
        • ServletFileUpload的setFileSizeMax(7 * 1024 * 1024);
        • 抓住异常(FileUploadBase.FileSizeLimitExceededException),给出友好提示
      • 总文件大小控制
        • ServletFileUpload的setSizeMax(10 * 1024 * 1024);
        • 抓住异常(FileUploadBase.SizeLimitExceededException),给出友好提示
    6. 超出10k的文件的临时处理?
      • fileupload默认情况下不会删除超过10K的临时文件。
      • 手工删除:FileItem的delete(); 一定要在流关闭后再删除
    7. 限制上传文件的类型?
      • 方式一:通过判断文件的扩展名来限制文件上传的类型,(不靠谱)
      • 方式二:获取上传文件的MIME类型,做限制和过滤
        • String  type = item.getContentType();
        • if(!type.endsWith("image/")
        •               continue;
    8. 监听文件的上传进度?
      • upload.setProgressListener(new ProgressListener() {
      • public void update(long pBytesRead, long pContentLength, int pItems) {
      • //应该把该数据通过异步方式传给界面上:JavaScript XMLHttpRequest
      • System.out.println("读到了:" +pBytesRead+",文件大小:"+pContentLength+",第几项:"+pItems);
      • }
      • });
    9. 用户没有选择上传文件时的问题
  4. HTML的DOM编程:动态添加上传输入域
  5. 文件的下载
  6. 监听、事件源、事件(观察者设计模式)
  7. Servlet规范中的监听器
    • 1、如何注册监听器到事件源上
    • web.xml
    • <listener>
    • <listener-class>com.itheima.listener.ServletContextListenerDemo</listener-class>
    • </listener>
    • 2、
    • 监听对象:ServletContext、HttpSession、ServletRequest
    • -------------------------------------3个监听器,主要监听他们的创建和销毁
    • ServletContextListener
    • HttpSessionListener
    • ServletRequestListener

    • 监听对象:ServletContext、HttpSession、ServletRequest的域(Map)
    • -------------------------------------3个监听器,主要监听他们的域中的变化:添加、替换了、删除了
    • ServletContextAttributeListener
    • HttpSessionAttributeListener:实现在线踢人案例。
    • ServletRequestAttributeListener

    • public void attributeAdded(ServletContextAttributeEvent scab) {
    • 域中来了新同志
    • }

    • public void attributeRemoved(ServletContextAttributeEvent scab) {
    • 同志牺牲了
    • }

    • public void attributeReplaced(ServletContextAttributeEvent scab) {
    • 某个同志被替换了
    • }

    • 感知型监听器:2个。不需要注册监听器。
    • HttpSessionActivationListener:感知自己何时被钝化、何时被活化。
    • HttpSessionBindingListener:感知自己何时被HttpSession绑了和解绑了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值