day15 - Java Web文件上传与下载

主要内容:
Apache fileupload实现文件上传
Java Web应用文件下载实现


Apache fileupload实现文件上传

Java Web应用实现用户的文件上传通常使用Apache的fileload开源组件,commons-fileupload.jar 和 commons-io.jar是核心的API.

upload实现文件上传的过程

1.1 upload实现文件上传的过程

文件上传主要用到的组件有: FileItemFactory, ServletFileUpload, DiskFileItem,下面会一一介绍这几个组件.

DiskFileItemFactory组件

DiskFileItemFactory是FileItemFactory接口默认实现,此类将请求信息实体中的每一个项目封装成单独的DiskFileItem (FileItem接口的实现)

DiskFileItemFactory组件的常用属性

static final int DEFAULT_SIZE_THRESHOLD: 将文件保存到内存还是磁盘临时目录的默认临界值,值为10240(10KB);
private File respository: 用于配置在创建文件项目时,当文件项目大于临界值时使用的临时文件夹,默认采用系统默认的临时文件目录,可以通过系统属性java.io.tmpdir获取;
private int sizeThreshold: 用于保存将文件保存在内存还是磁盘临时文件夹的临界值.

DiskFileItemFactory组件的构造方法

构造方法:
// 以默认临界值和系统临时目录构造工厂对象
public DiskFileItemFactory()
// 以参数方式设置临界值和系统临时目录构造工厂对象
public DiskFileItemFactory(int sizeThreshold, File respositoty)

ServletFileUpload组件

ServletFileUpload类是Apache文件上传组件处理文件上传的核心高级类,最核心的功能是使用parseRequest(HttpServletRequest)方法把表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List<FileItem>列表的形式返回.

servletFileUpload组件的构造方法

// 构造一个未初始化的实例,需要在解析请求之前先调用setFileItemFactory()方法设置fileItemFactory属性
public ServletFileUpload()
// 构造一个实例,并根据参数指定的FileItemFactory对象设置fileItemFactory属性
public ServletFileUpload(FileItemFactory fileItemFactory)

servletFileUpload组件的一些主要方法

// 将form表单项转换为FileItem实例并存储到List中返回
ListparseRequest(javax.servlet.http.HttpServletRequest req)
// 设置所有上传数据的最大上限,以字节为单位
setSizeMax(long sizeMax)
// 设置单个文件上传文件的最大上限
setFileSizeMax(long fileSizeMax)
// 设置编码格式
setHeaderEncoding(String encoding)

DiskFileItem组件

DiskFileItem类是FileItem接口的实现类,用来封装单个表单字段元素的数据,对于文件上传而言只处理实际是File对象的写入操作.

DiskFileItem组件的主要方法

boolean isFormField() // 判断是文件还是普通表单元素
String getName() // 获取文件上传字段中的文件名
String getFieldName() //获取表单字段元素描述头name属性值
void write(File file) //写入目标文件
String getContentType() //获取上传文件得类型字符串描述
boolean isInMemory() //判断文件时存储在内存还是临时文件中
void delete() //用来清空FileItem类对象中存放的主体内容
InputStream getInputStream()
long getSize() //返回该上传文件的大小

Web同步上传表单要求

1.2 Web同步上传表单要求

文件上传代码实现

jsp部分代码:

  <body>
  <h2>选择文件后点击上传按钮上传您的文件</h2>
  <form action="file/FileUploadServlet" method="post" enctype="multipart/form-data">
    文件:<input name="file" type="file"><br>
    年龄:<input name="age" type="text" value="23"><br>
    <input type="submit" value="上传">
  </form>
  </body>

Servlet部分代码:

public class FileUploadServlet extends HttpServlet {
    private String uploadSaveDir;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //上传文件保存的目录
        uploadSaveDir = this.getServletContext().getRealPath("/WEB-INF/uploadsFiles/");

        //创建默认属性设置的磁盘文件项工厂对象
        DiskFileItemFactory factory = new DiskFileItemFactory();

        //构建ServletFileUpload组件
        ServletFileUpload fileUpload = new ServletFileUpload();
        //设置使用的FileItemFactory
        fileUpload.setFileItemFactory(factory);
        //设置相关属性
        fileUpload.setFileSizeMax(1024*20);
        fileUpload.setHeaderEncoding("utf-8");

        //获取FileItemFactory所有文件项 FileItem
        List<FileItem> itemList = null;

        try {
            itemList = fileUpload.parseRequest(req);

            //遍历List
            for(FileItem fileItem:itemList){
                //如果是文件对象就保存到磁盘
                if(fileItem.isFormField() == false){

                    System.out.println("文件名称: "+ fileItem.getName());
                    System.out.println("字段名称: "+fileItem.getFieldName());
                    System.out.println("文件大小: "+fileItem.getSize());
                    System.out.println("文件类型是: "+fileItem.getContentType());
                    File target = new File(uploadSaveDir + fileItem.getName()+ new Date().getTime());
                    fileItem.write(target);
                }
                fileItem.delete(); //释放item内容主体
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Java Web应用文件下载实现基本原理

服务器端:
设置响应头信息,相应内容为文件流,告知Web用户(浏览器)是文件下载。

客户端:
客户端浏览器获取服务器响应内容,自动识别为文件下载,启动浏览器下载程序,下载完成的文件保存到客户机磁盘上。

服务器端下载请求处理

文件下载过程中,主要是服务器端对请求的处理的部分。

获取下载请求的文件的id参数

根据id查找目标文件建立文件对象,判断文件是否存在

基于目标文件建立文件输入流读取文件到内存

设置响应头内容,告知浏览器是文件响应方式

输出文件到客户浏览器,处理异常关闭文件流

核心代码

客户端代码

菜鸡的我遇到的坑:href之后的url在连接参数的时候不能加空格...不然传到服务器是识别不出来的,我太难了

<body>
    <h2>资源下载列表</h2>
    <a href="file/DownloadServlet?fileId=RELEASE-NOTES.txt">Readme</a><br>
    <a href="file/DownloadServlet?fileId=LICENSE.txt">License</a><br>
    <a href="file/DownloadServlet?fileId=LICENSE2.txt">License2</a><br>
</body>

服务器端代码

public class DownloadServlet extends HttpServlet {
    private String dir; //下载文件所在的父目录

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取下载链接的文件id参数
        String id = req.getParameter("fileId");
        dir = getServletContext().getRealPath("/WEB-INF/downloads/");

        //建立下载的目标文件
        File target = new File(dir+id);
        InputStream inputStream = null;
        ServletOutputStream outputStream = null;

        if(target.exists()){
            inputStream = new FileInputStream(target);

            //设置文件临时存储的缓冲区
            byte[] datas = new byte[102400];
            //获取字节的计数器
            int count = 0;

            resp.setHeader("Content-Type","text/plain");
            //设置响应头内容,告知浏览器本次响应是文件下载
            resp.setHeader("Content-Disposition",
                    "attachment;filename="+ URLEncoder.encode(target.getName(),"UTF-8"));

            //获取响应给服务器的文件输出流
            outputStream = resp.getOutputStream();

            //读取文件到缓冲区,响应发送输出流到客户端浏览器
            while ((count = inputStream.read(datas, 0, datas.length))>0){
                //输出到客户端
                outputStream.write(datas,0,count);
            }

            outputStream.flush();
            outputStream.close();
            inputStream.close();
        }else {
            //如果不存在,定位到提示页面
            resp.sendRedirect("../tip.jsp");
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 文件上传 1. Servlet3.0 新的APIPart接口 1.1 展示层 - 前台JSP 前台页面比较简单, ...
    一叶知休阅读 3,712评论 0 0
  • 如果表单里面包括上传文件的 input 标签 这个时候就不能用beanUtils 1、文件上传的原理分析 1.1...
    神豪VS勇士赢阅读 4,657评论 0 1
  • 一、文件上传介绍 要将客户端(浏览器)大数据存储到服务器端,不将数据直接存储到数据库中,而是要将数据存储到服务器所...
    圣贤与无赖阅读 4,829评论 0 16
  • 什么是文件上传 为什么使用文件上传 文件上传原理分析 上传文件注意事项 1,请求方式必须是post. 2,需要使用...
    持续进步者阅读 8,286评论 0 5
  • 晴! 早上打卡吃了两份蒸饺,发现自己撑死!(为什么要以为自己一份蒸饺吃不饱,作死的节奏) 书法课考试,感觉这么大的...
    LOM5阅读 1,053评论 0 0