JavaWeb 之 19.文件上传和下载


## 文件上传和下载 ##

**增强HttpServletRequest对象**
    
    1.装饰者模式
        * 需求:Connection的接口(SUN公司提供的),实现类是数据库的生成商提供的实现类。增强MySQL提供Connection接口的实现类。(不知道实现叫什么名字)
        
        * Connection conn = .....        SUN提供的
        * 使用的MySQL的数据库(导入驱动包:包含Connection接口的实现类    MySQLConnection    )

        class MySQLConnection implements Connection{
            public Statement createStatement(){
                // 实现完成了
            }
            public void close(){
                // MySQL的实现类也实现了该方法 销毁链接
            }
        }
            
        * 装饰者的模式        是你还有你,一切拜托你
        // 是你
        class MyConnection implements Connection{
            // 还有你
            private Connection conn;
            
            public MyConnection(Connection conn){
                this.conn = conn;
            }
        
            // 一切拜托你
            public Statement createStatement(){
                // 调用MySQLConnection中的createStatement()方法
                return conn.createStatement();
            }

            // 增强该方法
            public void close(){
                // MySQL的实现类也实现了该方法 销毁链接
                // conn.close();
                // 自己写
                归还链接
            }
            ... 
        }
        
        MyConnecton con = new MyConnection(new MySQLConnection());
        con.createStatement();    -- 相当于 MySQLConnection.createStatement();
    
    2.request.getParameter("username");解决该方法中文乱码的问题。    
        * 分析怎么做?装饰者增强
        
        HttpServletRequest 接口-- 谁提供的(SUN公司提供的)        
        Tomcat服务器访问Servlet的时候,服务器创建了两个对象(request,response)服务器提交的实现类。

        class TomcatRequest implements HttpServletRequest{
            publiuc String getParameter(String name){
                // 实现获取参数的值
                return "";
            }
            ...
            ...
        }
        
        HttpServletRequestWrapper类底层实现原理:
        
        class HttpServletRequestWrapper implements HttpServletRequest{
            private HttpServletRequest request;
            
            public HttpServletRequestWrapper(HttpServletRequest request){
                this.request = request;
            }
            
            // 空实现
            publiuc String getParameter(String name){
                // 自己逻辑
                return request.getParameter(name);
            }
            
            public String getQueryString(){
                return request.getQueryString();
            }
            public String getQueryString(){
                return request.getQueryString();
            }
            public String getQueryString(){
                return request.getQueryString();
            }
            ...
            ...
            ...
            ...
        }
        
        * SUN公司提供了一个类HttpServletRequestWrapper类
        * 自己编写一个类,继承HttpServletRequestWrapper,只需要关注增强的方法。
        
    
**文件上传的概述和原理**
    
    1.文件上传概述:客户端(需要文件的输入项),服务器:把本地的文件保存到服务器端。
    2.百度网盘  上传图片  
    3.想在JavaWeb阶段实现文件上传
        * 客户端
            * <input type="file">
            * 做文件上传的三点注意事项:
                * 需要一个表单,method属性必须是post
                * <input type="file" name="myfile" > name必须指定。
                * 表单上有一个属性:enctype=multipart/form-data
            
        * 服务器端
            * IO的读写操作
        

**Fileupload组件(文件上传组件)**
    
    1.JSPSmartUpload    -- 文件上传的组件(不写,过时了)。适合Model1时代
    2.FileUpload组件       --  适合Model2时代,把提交到Servlet里面,可以做文件上传。
    3.导入jar包。
        * 到入两个jar包。
            * commons-fileupload-1.2.1.jar
            * commons-io-1.4.jar

    4.编写文件上传
 

**文件上传的入门**
    
    1.第一步:编写客户端(提交方式是post,file的name属性必须指定,enctype="multipart/form-data"
    2.第二步:编写后台程序
    
    如果是普通的文本项:
    fileItem.isFormField()
    获取name的名称: fileItem.getFieldName();
    获取用户输入的值: fileItem.getString("UTF-8")
    
    如果是文件上传项:
    先获取文件的名称: fileItem.getName();
    获取文件的输入流: fileItem.getInputStream()
    
**说一些问题**

    1.在文件上传时,传统request.getParameter()获取不到内容
    
    只能用:
        String name = fileItem.getFieldName();
        // 获取用户输入的值
        String value = fileItem.getString();
    
    2.如果你使用IE6浏览器,上传文件的代码有问题。
        * 如果使用的IE6,获取文件的内容:d:/aa/boy3.jpg


**FileUpload核心类**

**DiskFileItemFactory类**
    
    1.DiskFileItemFactory类  -- 磁盘文件项工厂类
    2.方法
        * DiskFileItemFactory() 
        * DiskFileItemFactory(int sizeThreshold, java.io.File repository) 
            * sizeThreshold   : 设置缓冲区的大小,默认值是10K
            * repository      : 如果缓冲区大小小于上传文件的大小,产生临时文件,临时文件保存repository目录下。

        * void setSizeThreshold(int sizeThreshold)         --  设置缓冲区的大小
        * void setRepository(java.io.File repository)         -- 设置临时文件存放位置
    

**ServletFileUpload类**    

    1.方法:
        *  static boolean isMultipartContent(javax.servlet.http.HttpServletRequest request)     -- 判断表单是否是enctype="multipart/form-data",如果是返回true,如果不是返回false
                
        * java.util.List     parseRequest(javax.servlet.http.HttpServletRequest request)         -- 返回List集合。泛型是FIleItem(文件项)
        
        * void setFileSizeMax(long fileSizeMax)                 -- 设置上传的文件(单个文件)的大小
        * void setSizeMax(long sizeMax)                         -- 设置上传文件(所有的文件)的总大小
        * void setHeaderEncoding(java.lang.String encoding)     -- 设置上传文件的名称的编码
        
        * setProgressListener(ProgressListener pListener)        -- 上传的时候都有进度条。
        
**FileItem类**

    1.文件项:封装就的表单的部分。
    2.方法
        * boolean isFormField()                 -- 判断当前的FileItem对象是普通表单项还是文件上传项
        * java.lang.String getFieldName()         -- 返回表单中name的名称(name="filedesc")就是filedes
        * java.lang.String getString()                     -- 获取表单中普通项的值
        * java.lang.String getString(String encoding)     -- 获取表单中普通项的值(使用编码 UTF-8)
        
        * java.lang.String getName()                     -- 获取文件的名称
        * java.io.InputStream     getInputStream()         -- 获取文件的输入流
        * void delete()                                 -- 删除临时文件(在流关闭后执行)
 

**重要方法**

    * isMultipartContent()            -- 表单的enctyp是否正确
    * setHeaderEncoding()            -- 上传文件的中文名称乱码的问题
    
    * isFormField()                    -- 判断是否普通或者上传项
    * getFieldName()                -- 获取是普通项name的名称(filedesc)
    * getString(String encoding)     -- 获取是普通项name属性的值
    * getName()                     -- 获取上传文件项的文件名称
    * getInputStream()                 -- 获取文件的输入流
    

**多文件上传(js控制)**

    * 需要js知识。
    

**文件的扩展**
    
    1.文件存放的问题
        * 上传的文件保存的路径的问题。存放在WebRoot目录下的文件,直接被访问。
            * 存放图片(静态资源)
        * 存放在WEB-INF目录下不能被直接访问。
            * 视频的网站
    
    2.文件名重名的问题
        * 产生覆盖的效果。
        * 上传的文件时候,把文件的名称转成唯一的文件名。(UUID)
    
    3.如果上传文件的文件夹都是一个,一个文件夹下的文件过多。
        * 在一个文件夹下的文件过多的问题。
            * 给一个用户一个文件夹。
            * 规定文件夹中的文件的总数量。
            * 规定多长时间换文件夹。
            * 根据算法目录分离。
                * 文件已经产生的唯一的文件名。int code = filename.hashCode();
                代码:
                int code = filename.hashCode();
                // 和0xf进行&操作
                int dir1 = code & 0xf;
                // 把code右移4位
                int dir2 = (code >>> 4) & 0xf;
                return "/"+dir1+"/"+dir2;
                        
**文件的下载**
    
    1.传统文件下载哪种方式
        * 超链接下载
            * 如果浏览器可以解析的文件,默认打开了。
            * 如果浏览器不能解析文件,弹出下载的窗口。

        * 后台的程序下载
            * 从服务器向客户端进行下载。(找response对象)
            * 两个头一个流
            * 两个头:需要设置两个响应的头信息
                * Content-Type : text/html;charset=UTF-8
                * Content-Dispotition : attachment;filename= 文件的名称     以附件的形式打开文件
            * 一个流
                * 需要下载的文件的输入流
                * 再response输出流,把文件输出到浏览器端。


**文件下载的扩展(队列,树形结构遍历)**
    
    1.在磁盘上指定一个目录,作为根目录,目录包含一些文件,获取目录下所有的文件,显示到页面上,并且提供下载。
    2.需求:遍历根目录下的所有的文件进行下载。
        
**中文文件的下载的问题**
    
    1.先判断浏览器,决定使用什么编码,来把filename编了。
    2.怎么判断是用的什么浏览器?
        * 获取请求头的信息(User-agent)
        * 使用request获取头信息,进行判断。
    
**文件上传(数据保存到数据库中)**

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值