• 使用COS组件实现文件上传 转


    这是一个Servlet应用。。
    首先是web.xml
    [xhtml] view plaincopyprint?

        《?xml version="1.0" encoding="UTF-8"?》 
        《web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
            http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"》 
            《servlet》 
                《servlet-name》UploadServelt《/servlet-name》 
                《servlet-class》com.jadyer.servlet.UploadServelt《/servlet-class》 
                《!-- 指定所上传的文件,在上传成功后,保存在硬盘中的位置 --》 
                《init-param》 
                    《param-name》savePath《/param-name》 
                    《param-value》D://mydata//upload《/param-value》 
                《/init-param》 
            《/servlet》 
            《servlet-mapping》 
                《servlet-name》UploadServelt《/servlet-name》 
                《url-pattern》/servlet/UploadServelt《/url-pattern》 
            《/servlet-mapping》 
         
            《welcome-file-list》 
                《welcome-file》upload.jsp《/welcome-file》 
            《/welcome-file-list》 
        《/web-app》 
        《!-- 
        曾有网友拿COS跟commons-fileupload和jspSmartUpload进行试验对比,试验过程如下 
        分别上传2MB、20MB、45MB、200MB的文件,并测试三种组件的花费时间,测试结果如下 
        文件小于2MB时,COS和FileUpload的上传速度差不多,但jspSmartUpload已显出弱势 
        随着文件的增大,FileUpload和SmartUpload的上传速度明显不如COS 
        当文件200MB时,SmartUpload已经不堪重负而崩溃 
        而此时COS所花费的时间比FileUpload要少了20多秒 
        毫无疑问,试验结果,COS的性能,当之无愧位居第一 
        --》 

    然后是用于收集所上传的文件信息的upload.jsp页面

    [xhtml] view plaincopyprint?

        《%@ page language="java" pageEncoding="UTF-8"%》 
         
        《form action="《%=request.getContextPath()%》/servlet/UploadServelt" enctype="multipart/form-data" method="POST"》 
            用户:《input type="text" name="username"》《br/》 
            密码:《input type="password" name="password"》《br/》 
            性别:《input type="radio" name="sex" value="woman" checked》女   
                 《input type="radio" name="sex" value="man"》男《br/》 
            喜好:《input type="checkbox" name="like" value="sleep"》睡觉   
                 《input type="checkbox" name="like" value="coding" checked》写代码   
                 《input type="checkbox" name="like" value="eat"》吃饭《br/》 
            附件:《input type="file" name="file11"》《br/》 
            附件:《input type="file" name="file22"》《br/》 
            附件:《input type="file" name="file33"》《br/》 
                 《input type="submit" value="我要上传"》 
        《/form》 

    接着是自定义的用于解决上传的文件名冲突的命名策略类

    [java] view plaincopyprint?

        package com.jadyer.util; 
         
        import java.io.File; 
        import java.util.Date; 
         
        import com.oreilly.servlet.multipart.FileRenamePolicy; 
         
         
        public class RandomFileNamePolicy implements FileRenamePolicy { 
            public File rename(File file) { 
                 
                int index = file.getName().lastIndexOf("."); //获取文件名中【.】的下标 
                String body = file.getName().substring(0, index); //表示文件名的主题,即【abcd】 
                String postfix = ""; //表示文件名的后缀,即【.ccc】 
                String timer = ""; //代表当前系统时间的数字 
                 
                //如果该文件的名字中,没有【.】的话,那么lastIndexOf(".")将返回-1 
                if (index != -1) { 
                    timer = new Date().getTime() + ""; //在文件的名字前面,添加的表示当前系统时间的数字 
                    postfix = file.getName().substring(index); //获取到文件名当中的【.ccc】 
                } else { 
                    timer = new Date().getTime() + ""; 
                    postfix = ""; //如果lastIndexOf(".")返回-1,说明该文件名中没有【.】即没有后缀 
               
                 
                String newName = body + timer + postfix; //构造新的文件名 
                return new File(file.getParent(), newName); //返回重命名后的文件 
           
       

    最后是用来处理文件上传的核心操作的Servlet

    [java] view plaincopyprint?

        package com.jadyer.servlet; 
         
        import java.io.File; 
        import java.io.IOException; 
        import java.util.Enumeration; 
         
        import javax.servlet.ServletConfig; 
        import javax.servlet.ServletException; 
        import javax.servlet.http.HttpServlet; 
        import javax.servlet.http.HttpServletRequest; 
        import javax.servlet.http.HttpServletResponse; 
         
        import com.jadyer.util.RandomFileNamePolicy; 
        import com.oreilly.servlet.MultipartRequest; 
         
         
        public class UploadServelt extends HttpServlet { 
            private static final long serialVersionUID = -7946856825034537432L; 
             
            private String savePath; 
         
            public void init(ServletConfig config) { 
                //取得web.xml中配置的savePath参数的值 
                savePath = config.getInitParameter("savePath"); 
           
         
            public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
                //指定所上传的文件,上传成功后,在硬盘上的保存位置 
                String saveDirectory = this.savePath; 
                 
                //如果所指定的文件夹,在硬盘上不存在的话,则创建该文件夹 
                File fileDirectory = new File(saveDirectory); 
                if(fileDirectory.exists()){ 
                    System.out.println("提示:" + saveDirectory + "目录已存在"); 
                }else{ 
                    //fileDirectory.mkdir();//此时如果使用mkdir()方法,文件夹将创建失败 
                    //因为我们在web.xml中指定的《init-param-value》的值,包含父目录 
                    fileDirectory.mkdirs(); 
                    System.out.println("成功创建" + saveDirectory + "文件夹"); 
               
         
                //限定所上传文件的合计大小,默认为1MB。这里设置的不是单个文件,而是上传的所有文件的总大小 
                int maxPostSize = 8 * 1024 * 1024; 
                 
                //可能会出现不同用户,上传同名文件的现象,所以我们应该采取某种手段,以解决文件名称冲突的问题 
                //在COS中有一个默认的命名策略DefaultFileRenamePolicy,只要存在重名现象,它就会在文件名后面加上1.2.3..等以示区分 
                //DefaultFileRenamePolicy dfrp = new DefaultFileRenamePolicy(); 
                //MultipartRequest multi = new MultipartRequest(request, saveDirectory, maxPostSize, "UTF-8", dfrp); 
                 
                //本人测试的结果却是:若未显式new DefaultFileRenamePolicy(),此时若上传同名文件,则先前的文件会被后面上传的文件覆盖掉 
                //MultipartRequest multi = new MultipartRequest(request, saveDirectory, maxPostSize, "UTF-8"); 
                 
                //我们也可以自定义命名策略文件。。我这里的解决办法是:文件名 + 时间戳 + 文件后缀 
                //在COS中自定义命名策略文件时,只需要实现FileRenamePolicy接口,并重写其rename(File file)方法即可 
                RandomFileNamePolicy rfnp = new RandomFileNamePolicy(); 
                 
                //完成文件上传 
                MultipartRequest multi = new MultipartRequest(request, saveDirectory, maxPostSize, "UTF-8", rfnp); 
                 
                //输出所上传的文件的信息 
                Enumeration fileNames = multi.getFileNames(); 
                while(fileNames.hasMoreElements()){ 
                    String fileName = (String)fileNames.nextElement(); 
                    if(null != multi.getFile(fileName)){ 
                        String lastFileName = multi.getFilesystemName(fileName); 
                        System.out.println("上传的文件: " + saveDirectory + "//" + lastFileName); 
                   
               
                 
                //输出所提交的表单中其它文本输入域的值 
                Enumeration formValue = multi.getParameterNames(); 
                while(formValue.hasMoreElements()){ 
                    String param = (String)formValue.nextElement(); 
                    String value = multi.getParameter(param); 
                    System.out.println(value); 
               
                //若知道前台表单输入域的name值,便可使用下面代码,更省事 
                System.out.println("用户:" + multi.getParameter("username")); 
                System.out.println("密码:" + multi.getParameter("password")); 
                System.out.println("性别:" + multi.getParameter("sex")); 
                for(String like : multi.getParameterValues("like")){ 
                    System.out.println("喜好:" + like); 
               
           
         
       
         
        //public Enumeration getFileNames() 
        //返回包含了所有上传的文件名称的一个Enumeration对象 
        //在Enumeration对象里面储存的是前台表单中《input type="file" name=""》里面的name值 
         
        //public File getFile(String name) 
        //返回存储在服务器上的指定name的File对象。该name是《input type="file" name=""》的name值 
        //若服务器上不存在该文件或者未上传该文件到服务器上,则返回null 
         
        //public String getFilesystemName(String name) 
        //返回所上传的文件,在服务器上的真正文件名。该name是《input type="file" name=""》的name值 
        //如果在上传文件时,未指定FileRenamePolicy命名策略文件,则返回的是该文件上传之前的原始名称 
        //若服务器上不存在该文件或者未上传该文件到服务器上,则返回null 
         
        //public String getOriginalFileName(String name) 
        //返回所上传的文件,在命名策略文件生效前的文件名。该name是《input type="file" name=""》的name值 
        //说白了,就是你上传的文件的本地的原始名字,而不是在上传到服务器之后,为解决同名现象而被重命名后的名字 
         
        //public Enumeration getParameterNames() 
        //返回前台表单中,除文件输入域外的,其它文本输入域的所有参数值 
        //在Enumeration对象里面,储存的是前台表单中的《input type="除file外" name=""》里面的name值 
         
        //public String getParameter(String name) 
        //返回前台表单中,文本输入域的值。该name是表单中《input type="除file外" name=""》里的name值 
        //如果前台表单中的name参数,对应有多个值,比如《input type="checkbox"》 
        //那么此时,该方法将只会输出这多个值中的最后一个值 
        //所以,对于类似《input type="checkbox"》而言,更推荐getParameterValues(String name)方法 
         
         
         
         
        //com.oreilly.servlet.MultipartRequest.MultipartRequest主要负责文件上传的处理 
        //MultipartRequest类共有8个构造函数,可参考官方文档,以下是对构造函数中参数的简要说明 
        //saveDirectory--指定所上传文件,在服务器端的存储目录 
        //maxPostSize----限制上传文件的合计大小。默认为1MB 
        //encoding-------解决上传文件名称的乱码问题 
        //policy---------解决上传文件名称的重名问题 
         
         
         
         
        //这里必须声明一点:MultipartRequest构造方法中的maxPostSize参数,网上存在一定的误解 
        //接触COS,是很偶然的:周三,QQ上,突然想要写一段代码,实现的是在两个JSP中上传一个图片 
        //要求:代码尽量少。原本我对IO流就没那么熟练,于是条件反射的就想用commons-fileupload组件 
        //结果,还是觉得不行,要求代码要尽量少啊。我一寻思,既如此,jspSmartUpload就也不行了 
        //可是要我自己去写IO的那些东西,又有些不情愿,于是就琢磨着到网上找找其它的文件上传组件 
        //很快就在oschina.net发现了COS组件,当时看到那个Demo,不禁眼前一亮,这组件太给力了 
        //于是决定好好研究研究它,随之就去CSDN搜索COS的相关文章,竟然少得可怜,让我大吃一惊 
        //反倒是commons-fileupload如日中天,莫非COS宣传不力??于是赶紧探索COS的前世今生 
        //没想到COS竟然是大名鼎鼎的O'Rrilly公司开发的一款用于HTTP上传文件的OpenSource组件 
        //太赞了!!大家都知道:O'Reilly公司的书是非常闻名的 
        //没想到O'Reilly竟然也开发了一个上传组件,还是开源的,也是为开源事业做出了贡献啊,赞!! 
        //于是在COS主页:http://www.servlets.com/cos将其发行包下载下来 
        //COS下载地址为:http://www.servlets.com/cos/cos-26Dec2008.zip 
        //发现COS的最后一次更新,是2008年12月26日 
        //真巧了,这一天正是毛主席的生日啊,而且我也是在2010年12月26日那天开始自学Java的。。 
        //好了,不扯了,言归正传 
        //网上所有我看到的COS使用的例子,都对maxPostSize参数存在一定的误解,说的都不够严密 
        //int maxPostSize = 5 * 4 * 1024 * 1024; 
        //网上部分人对这行代码的解释是:限定所上传文件的单个大小最大为4MB,且最多只能上传5个文件 
        //当时第一反应:这COS也忒棒了吧,这么注重细节,连这个都封装好了?? 
        //紧接着又一想:貌似不对呀,为何不单独定义一个变量,来限定上传文件的个数呢? 
        //像这样都封装到maxPostSize中,貌似不太便于升级和维护啊,这样也未免太懒些了吧 
        //伴随着这个疑问,我也就开始步步测试,结果发现:此乃误解!! 
        //通过查看COS的源码,在MultipartRequest.java的第70行,发现是这样定义的 
        //private static final int DEFAULT_MAX_POST_SIZE = 1024 * 1024;  // 1 Meg 
        //这说明了:COS组件的本意,是要用该参数来限定所上传文件的合计大小!! 
        //而且在COS主页中,已经对其进行了说明,请参见http://www.servlets.com/cos/faq.html 
        //在该页面中,有这样一段话:The default maximum is 1 Meg。。这不就是很好的说明嘛 
        //今天,我曾试图翻译http://www.servlets.com/cos/faq.html里的文档 
        //因为,这份FAQ写的并不是太难,结果翻译到了一半,发现:这么做,意义不大。于是停止了翻译 
        //好了,关于maxPostSize参数的说明,就到这里吧 
        //我想说的是:人,要对自己负责,最直接的体现,就是对自己写的代码负责 
        //我想说的是:在网上获得到的代码,自己一定要重新运行测试一遍 
        //我想说的是:毕竟,人家把代码写到了网上,说明此人不那么吝啬,这是值得肯定和赞许的 
        //我想说的是:但作为普通老百姓的咱们,人家没有义务对你负责,这你要知道 
        //我想说的是:不要觉得凡是网上的代码,就全部都是正确的,所以毛主席说的好:没有实践就没有发言权 
        //我想说的是:同样,我博客的所有代码,虽已经过我的亲自测试,但未免会由于某些JDK环境等因素导致失效 
        //我想说的是:所以,如果哪位网友发现,我的某些代码不合时宜,还望不吝指出:jadyer@yeah.net 
         
  • 相关阅读:
    LF.51.Insert In Binary Search Tree
    Use Array To Implement Queue With Size(bounded)
    Use LinkedList to implement Queue
    Use LinkedList to Implement Stack
    LT.11.Search Range In Binary Search Tree
    Odoo 12开发之后台视图 – 设计用户界面 ###
    Odoo 之业务逻辑
    Odoo开发之记录集 – 使用模型数据
    odoo 之 结构化应用数据
    odoo之数据导入导出以及模块数据
  • 原文地址:https://www.cnblogs.com/luckForever/p/7254466.html
Copyright © 2020-2023  润新知