专栏首页Java成神之路JavaWeb_常用功能_01_文件上传

JavaWeb_常用功能_01_文件上传

 一个功能完善的JavaWeb应用,必不可少的一个功能就是文件的上传。无论是用户的头像等,还是用户需要上传的一系列资料,都是通过文件的上传功能实现的。

目前我们实现网站中关于文件的上传功能时,常用的是apache的开源工具common-fileupload以及common-fileupload的依赖包common-io。

下面以一个注册页面的后台程序为例,大致讲解这两个包的使用:

首先,前往apache官网上面下载common-fileupload、common-io这两个包,并放入工程的WEB-INF文件夹的lib目录下。

然后,在网站页面的表单那里设置:

文件选择按钮为:<input type="file"/>

表单数据属性设置为:enctype="multipart/form-data"。因为只有使用enctype="multipart/form-data",表单才会把文件的内容编码到HTML请求中。

原理请移步:http://blog.csdn.net/mazhibinit/article/details/49667511 进行了解。

<form action="upload_do.jsp" method="post" enctype="multipart/form-data">    
   文件上传栏: <input type="file" size="30" name="upload" />
   <input type="submit" value="提交上传" />    
 </form>

   最后,在表单提交的目的jsp文件中使用两个包中的工具类进行文件的提取与保存,一般步骤如下:

1、实例化一个硬盘文件工厂,用来配置上传组件ServletFileUpload的一些基本设定。比如

 DiskFileItemFactory dfif = new DiskFileItemFactory();
 // 定义文件上传时的“运输船”大小。文件是一部分一部分上传的,这里设置为4K。当数据读取到4K则写入硬盘的临时文件夹中,清空运输船继续读取。
    //文件传输完后,再从临时文件夹转存到实际的保存路径下

    dfif.setSizeThreshold(4096);

    // 设置存放临时文件的目录如下:获取完整路径——修改路径新建临时文件夹——把临时文件夹设为工厂的默认目录(则工厂获取的内容会默认存放在这里)
    String realwebbase = request.getSession().getServletContext().getRealPath("/");
    File temp_file = new File(realwebbase+"upload/UploadTemp"); 
    if (!temp_file.exists()) {
        temp_file.mkdirs();
    }
    
    dfif.setRepository(temp_file);

2、用工厂实例化上传组件,则该组件会使用该工厂实例的一系列配置(如:以多大容量为一次上传文件、临时文件存放处等)

 ServletFileUpload sfu = new ServletFileUpload(dfif);
    sfu.setHeaderEncoding("UTF-8");
    // 设置上传文件的最大容量
    sfu.setSizeMax(MAX_SIZE);

3、从request对象中把上传内容提取到一个list中。从上面引用的博文处可以看到,POST+multipart/form-data的效果是form表单内的内容以键值对的形式提交上去。

 List fileList = null;
    try {
        fileList = sfu.parseRequest(request);
    } 
    catch (FileUploadException e) { }

4、用迭代器遍历list对象,提取上传内容。上传内容主要分两种:文本与非文本内容(图片、多媒体文件等)

 Iterator fileItr = fileList.iterator();
    while (fileItr.hasNext()) {            
        FileItem fileItem = (FileItem) fileItr.next();
        if(fileItem.isFormField()){ //第一种上传内容:普通文本,分别获取键名、值内容即可                   
            String name = fileItem.getFieldName();        //获取键值对的键名
            String value = fileItem.getString("UTF-8");   //此处的getString()是指对list的当前元素(键值对)的值,按照参数所指定的解码方式进行解析、获取内容
        }else{ //第二种上传内容:非文本,则需要用到流传输来把内容读取、保存到具体的路径下
            String path = fileItem.getName();  //获取文件的路径名,用于截取扩展名进行文件类型的判断// 得到文件的大小,用于判断文件大小是否合法
            long size = fileItem.getSize();
            if ("".equals(path) || size == 0) {
                out.println("上传的文件无效!");
                out.close();
                return;
            }        
            // 得到去除路径的文件名
            String t_name = path.substring(path.lastIndexOf("/") + 1);
            // 得到文件的扩展名(无扩展名时将得到全名)
            String t_ext = t_name.substring(t_name.lastIndexOf(".") + 1);
            
          
           //遍历允许的扩展名数组,看看上传文件的扩展名是否合法。
            int i = 0;
       boolean errorflag=true;
            while (i < allowedExt.length) {
                if (allowedExt[i].equals(t_ext)){
            errorflag=false;
                    break;
                }
                i=i+1;
            }
            if (errorflag) {
                out.println("请上传合法文件!");
                out.close();
                return;
            }
   // 用uuid+日期作为文件名的一部分来唯一标识文件
            String uuid = UUID.randomUUID().toString(); 
            String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
            //生成最终的文件保存完整路径:目录路径+日期+UUID+ . +扩展名
            String u_name = realwebbase + "upload/" + today + "/" + uuid + "." + t_ext;
            
            try {                        
                File _today_file = new File(realwebbase + "upload/Uploaded/" + _today); //构建文件目录
                if (!_today_file.exists()) {
                    _today_file.mkdirs();
                }
                fileItem.write(new File(u_name)); //把当前list元素的值用write流写到创建好的路径下,即实现文件内容的保存了return;
            } 
            catch (Exception e) {
                e.printStackTrace();
            }
                                    
        }   

5、最后,就是把文件的相对路径信息保存到数据库中去,使文件得以在其他文件中通过相对路径进行引用了。

转自: http://www.cnblogs.com/ygj0930/p/6073505.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java微信公众平台开发_06_素材管理

    shirayner
  • Java微信公众平台开发_04_自定义菜单

    自定义菜单中请求包的数据是Json字符串格式的,请参见:  Java_数据交换_fastJSON_01_用法入门

    shirayner
  • Java微信公众平台开发_02_启用服务器配置

                         见:【  Java微信公众平台开发_01_本地服务器映射外网  】

    shirayner
  • 一文读懂SpringMVC中的文件上传与下载

    这两天研究了一下 SpringMVC 中文件上传与下载,也遇到了一些坑,这里做个总结。

    Wizey
  • PHP如何上传文件和下载,你学会了吗?

    ​ 在 B/S 程序中文件上传已经成为一个常用功能。其目的是客户可以通过浏览器(Browser)将文件上传到服务器(Server)上的指定目录。

    叫我可儿呀
  • 【Spark篇】---Spark中Transformations转换算子

    Spark中默认有两大类算子,Transformation(转换算子),懒执行。action算子,立即执行,有一个action算子 ,就有一个job。

    LhWorld哥陪你聊算法
  • JavaScript中的拷贝(copy)

    如果现有var obj1 = {…}这个对象,想要复制对象obj1,一贯的做法就是obj2 = obj1,这时虽然obj2拥有了obj1的所有属性,但obj2却...

    刘亦枫
  • 实时数仓链路分享:kafka =>SparkStreaming=>kudu集成kerberos

    本文档主要介绍在cdh集成kerberos情况下,sparkstreaming怎么消费kafka数据,并存储在kudu里面

    王知无
  • java spark-streaming接收TCP/Kafka数据

     本文将展示 1、如何使用spark-streaming接入TCP数据并进行过滤; 2、如何使用spark-streaming接入TCP数据并进行wordcou...

    用户1225216
  • [享学Netflix] 十三、Archaius属性抽象Property和PropertyWrapper详解

    上篇文章介绍了Archaius动态属性DynamicProperty,并且通过DynamicPropertyFactory间接的体验了一把它天生的动态性。

    YourBatman

扫码关注云+社区

领取腾讯云代金券