• 文件的上传和下载在web应用中是非常常用,也是非常有用的功能。

     例如:发送电子邮件时可以同过上传附件发送文件,OA系统中可以通过上传文件来提交公文,社交网站通过上传图片来自定义头像等等。

     例如:下载实际上只要资源放在用户可访问的目录中用户就可以直接通过地址下载,但是一些资源是存放到数据库中的,还有一些资源需要一定权限才能下载,这里就需要我们通过Servlet来完成下载的功能。

  • 可以说上传和下载是每一个web应用都需要具有的一个功能,所以需要我们掌握。
  • 文件的上传主要分成两个步骤

文件的上传

  用户在页面中选择要上传的文件,然后将请求提交到Servlet

   Servlet收到请求,解析用户上传的文件,然后将文件存储到服务器

创建上传文件的表单

  1. 创建一个form表单

    <formaction=""method="post"enctype="multipart/form-data">
    
        <inputtype="file"name="file"/><br/><br/>
    
        <inputtype="submit"value="上传"/>
    
    </form>
    

      

  文件上传的表单和之前的表单类似,但有以下内容需要注意

   表单的method属性必须为post

  表单的enctype属性必须为multipart/form-data

  上传文件的控件是intput,type属性为file

  该表单打开后是如下效果:

   IE

  Chrome

   火狐

  1. 编写Servelet。
  • 页面的表单控件创建好以后,选中文件点击上传按钮请求将会提交到指定的Servlet来处理。
  • 注意:这里不能再像以前的Servlet中那样,通过request.getParamter()来获取请求参数了,当enctype="multipart/form-data"时,再使用getParamter()获取到内容永远为空。因为浏览器发送请求的方式已经改变。
  • 既然以前的方法不能使用了,这里我们必须要引入一个新的工具来解析请求中的参数和文件,这个工具就是commons-fileupload。
  • commons-fileupload是Apache开发的一款专门用来处理上传的工具,它的作用就是可以从request对象中解析出,用户发送的请求参数和上传文件的流。
  • commons-fileupload包依赖commons-io,两个包需要同时导入。
  • 核心类:

commons-fileupload。

  1.DiskFileItemFactory

  • 工厂类,用于创建ServletFileUpload,设置缓存等
  • 该类一般直接使用构造器直接创建实例
  • 方法:

     public void setSizeThreshold(int sizeThreshold)

    用于设置缓存文件的大小(默认值10kb)

    public void setRepository(File repository)

    用于设置缓存文件位置(默认系统缓存目录)

  2.ServletFileUpload  

  • 该类用于解析request对象从而获取用户发送的请求参数(包括普通参数和文件参数)
  • 该类需要调用有参构造器创建实例,构造器中需要一个DiskFileItemFactory作为参数
  • 方法:

    public List<FileItem> parseRequest(HttpServletRequest request)

    解析request对象,获取请求参数,返回的是一个List,List中保存的是一个FileItem对象,一个对象代表一个请求参数。

    public void setFileSizeMax(long fileSizeMax)

    设置单个文件的大小限制,单位为B

    如果上传文件超出限制,会在parseRequest()抛出异常

    FileSizeLimitExceededException。

    public void setSizeMax(long sizeMax)

    限制请求内容的总大小,单位为B

    如果上传文件超出限制,会在parseRequest()抛出异常

    SizeLimitExceededException。

  3.FileItem

  • 该类用于封装用户发送的参数和文件,也就是用户发送来的信息将会被封装成一个FileItem对象,我们通过该对象获取请求参数或上传文件的信息。
  • 该类不用我们手动创建,由ServletFileItem解析request后返回。
  • 方法:

    String getFieldName()

    获取表单项的名字,也就是input当中的name属性的值。

    String getName();

    获取上传的文件名,普通的请求参数为null。

    String getString(String encoding);

    获取内容

    若为文件,将文件的流转换为字符串。

    若为请求参数,则获取请求参数的value。

    encoding参数需要指定一个字符集

    boolean isFormField();

    判断当前的FileItem封装的是普通请求参数,还是一个文件。

    如果为普通参数返回:true

    如果为文件参数返回:false

    String getContentType();

    获取上传文件的MIME类型

    long getSize();

    获取内容的大小

  • 实例代码,创建一个Servlet并在doPost()方法中编写如下代码:

    //创建工厂类
    
    DiskFileItemFactory factory = new DiskFileItemFactory();
    
    //创建请求解析器
    
    ServletFileUpload fileUpload = new ServletFileUpload(factory);
    
    //设置上传单个文件的的大小
    
    fileUpload.setFileSizeMax(1024*1024*3);
    
    //设置上传总文件的大小
    
    fileUpload.setSizeMax(1024*1024*3*10);
    
    //设置响应内容的编码
    
    response.setContentType("text/html;charset=utf-8");
    
    try {
    
        //解析请求信息,获取FileItem的集合
    
        List<FileItem> items = fileUpload.parseRequest(request);
    
        //遍历集合
    
        for (FileItem fileItem : items) {
    
           //如果是普通的表单项
    
           if(fileItem.isFormField()){
    
           //获取参数名
    
               String fieldName = fileItem.getFieldName();
    
           //获取参数值
    
               String value = fileItem.getString("utf-8");
    
               System.out.println(fieldName+" = "+value);
    
        //如果是文件表单项
    
            }else{
    
           //获取文件名
    
               String fileName = fileItem.getName();
    
           //获取上传路径
    
               String realPath = getServletContext().getRealPath("/WEB-INF/upload");
    
           //检查upload文件夹是否存在,如果不存在则创建
    
               File f = new File(realPath);
    
           if(!f.exists()){
    
                   f.mkdir();
    
               };
    
           //为避免重名生成一个uuid作为文件名的前缀
    
               String prefix = UUID.randomUUID().toString().replace("-", "");
    
           //将文件写入到服务器中
    
               fileItem.write(new File(realPath+"/"+prefix+"_"+fileName));
    
           //清楚文件缓存
    
               fileItem.delete();
    
            }
    
    }
    
    } catch (Exception e) {
    
        if(e instanceof SizeLimitExceededException){
    
           //文件总大小超出限制
    
           response.getWriter().print("上传文件的总大小不能超过30M");
    
        }elseif(e instanceof FileSizeLimitExceededException){
    
           //单个文件大小超出限制
    
           response.getWriter().print("上传单个文件的大小不能超过3M");
    
        }
    
    }
    
    response.getWriter().print("上传成功");
    

      

java文件的上传的更多相关文章

  1. java 文件的上传和下载

    主要介绍使用 smartupload.jar 包中的方法对文件的上传和下载.上传时文件是存放在服务器中,我用的是tamcat. 首先建立一个servlet 类,对文件的操作 package com.d ...

  2. java文件夹上传下载控件分享

    用过浏览器的开发人员都对大文件上传与下载比较困扰,之前遇到了一个需要在JAVA.MyEclipse环境下大文件上传的问题,无奈之下自己开发了一套文件上传控件,在这里分享一下.希望能对你有所帮助. 以下 ...

  3. java文件分片上传,断点续传

    百度的webUploader的前端开源插件实现的大文件分片上传功能 前端部分 前端页面代码如下,只需要修改自己的文件上传地址接口地址: <!DOCTYPE html> <html l ...

  4. java文件断点续传上传下载解决方案

    这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数 下面直接贴代码吧,一些难懂的我大部分都加上注释了: 上传文件实体类: 看得 ...

  5. Java 文件本地上传、下载和预览的实现

    以下方法为通用版本 实测图片和pdf 都没有问题 上传方法需要前端配合post请求 ,下载前端用a标签就可以,预览 前端使用ifrme标签   ,就可以实现基本功能... 1.文件本地上传 publi ...

  6. java 下载文件的两种方式和java文件的上传

    一:以网络的方式下载文件 try { // path是指欲下载的文件的路径. File file = new File(path); // 以流的形式下载文件. InputStream fis = n ...

  7. java文件夹上传下载组件

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...

  8. java文件夹上传

    我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 首先我们需要了解的是上传文件三要素: 1.表单提交方式:post (get方式提交有大小 ...

  9. [Pulgin] 利用swfupload实现java文件批量上传

    URL:http://blog.csdn.net/xuweilinjijis/article/details/8876305 之前在网上找过很多相关资料,很多所谓的批量上传都是忽悠人的,真正的批量上传 ...

随机推荐

  1. 「国家集训队」middle

    「国家集训队」middle 传送门 按照中位数题的套路,二分答案 \(mid\),序列中 \(\ge mid\) 记为 \(1\),\(< mid\) 的记为 \(-1\) 然后只要存在一个区间 ...

  2. 集成PHP应用和SOLR

    集成 PHP 应用和 Solr 搜索引擎 您的评价:          收藏该经验       你为什么需要搜索引擎?单纯数据库不够用?如果你只是创建小网站,数据库就够了.但当你创建中性或大型应用的时 ...

  3. NB-IoT的介绍最终版 !看明白了吗?(转自 top-iot)

    标签: NB-IOT 1  1G-2G-3G-4G-5G 不解释,看图,看看NB-IoT在哪里? 2  NB-IoT标准化历程 3GPP NB-IoT的标准化始于2015年9月,于2016年7月R13 ...

  4. springMVC的 Converter转换器 和 Formatter

    Converter转换器 spring的Converter是可以将一种类型转换成另一种类型的一个对象, 自定义Converter需要实现Converter接口 日期转换器 import java.te ...

  5. 【剑指Offer面试编程题】题目1507:不用加减乘除做加法--九度OJ

    题目描述: 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入为两个整数m和n(1<=m,n<=10 ...

  6. 最简单、最常用的一些Git命令

    ---------------------------------------------------------------------------------------------------- ...

  7. 学习笔记(13)- decaNLP训练WikiSQL

    将自然语言转为sql语句,达到对话查询报表的效果. 参考资料 参考1 https://mp.weixin.qq.com/s/i7WAFjQHK1NGVACR8x3v0A 语义解析.SQL查询生成与语义 ...

  8. 浅谈区块链和p2p网络

    最近对区块链产生了兴趣就去了解了一下,分享一下.... 首先要先了解一下什么叫做区块链: 区块链:简单来说就是一种基于分布式数据存储.点对点传输.共识机制.加密算法等计算机技术的新型应用模式. 相信说 ...

  9. Mysql 锁定 读情况

    在一个事务中,标准的SELECT语句是不会加锁,但是有两种情况例外. SELECT ... LOCK IN SHARE MODE SELECT ... FOR UPDATE SELECT ... LO ...

  10. 「NOIP2017」逛公园

    传送门 Luogu 解题思路 考虑 \(\text{DP}\). 设 \(f[u][k]\) 表示从 \(u\) 到 \(n\) 走过不超过 \(Mindis(u, n) + k\) 距离的方案数. ...