zoukankan      html  css  js  c++  java
  • 使用JavaWeb实现文件的上传和下载

    使用JavaWeb实现文件的上传和下载

    文件上传

    [文件上传的注意事项]

    1.为保证服务器安全,上传文件应该放在外界无法直接访问的目录下, 比如放于WEB-INF目录下。
    2.为防止文件覆盖的现象发生,要为上传文件产生一个唯一 的文件名
    3.要限制上传文件的最大值。
    4.可以限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

    文件上传代码

    1、所需jar包

     <!--文件上传,导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包;-->
        <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.3.3</version>
        </dependency>
        <!--servlet-api导入高版本的-->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.1</version>
        </dependency>
        <!--jsp的依赖-->
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>javax.servlet.jsp-api</artifactId>
          <version>2.3.3</version>
          <scope>provided</scope>
        </dependency>
        <!--JSTL的依赖-->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
        </dependency>
        <!-- standard标签库-->
        <dependency>
          <groupId>taglibs</groupId>
          <artifactId>standard</artifactId>
          <version>1.1.2</version>
        </dependency>
    

    2、index.jsp

    加载服务器地址固定写法:"${pageContext.request.contextPath}/upload.do"

    <html>
    <body>
    <form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post">
        <input type="file" name="file"/>
        <input type="submit" value="upload">
        </form>
    </body>
    </html>
    

    3、FileServlet

    package com.lenovo.servlet;
    
    
    import com.sun.org.apache.xml.internal.res.XMLErrorResources_tr;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.ProgressListener;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    import java.util.UUID;
    
    public class FileServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //判断上传的文件是普通表非还是带文件的表单
            if (!ServletFileUpload.isMultipartContent(request)) {
                return; //终止方法运行说明这是一个普远的表单,直接返回
            }
            //创建上:传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问上传的文件;
            String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
            File uploadFile = new File(uploadPath);
            if (!uploadFile.exists()) {
                uploadFile.mkdir(); //创建这个目录
            }
            //级存,临时文件
            //临时路径,假如文件超过J预期的大小,我们就把他放到一一个临时文件中,过几天自动删除,或者提醒用户转存为承久
            String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
            File file = new File(tmpPath);
            if (!file.exists()) {
                file.mkdir(); //创建这个临时目录
            }
            //处理上传的文件,一般 都需要通过流来获取,我们可以使request. getInputstream(),原生态的文件上传流获取,十分麻烦
            //但是我们都建议使用Apache的文件上:传组件米实现,common-fileupload, 它需要依赖于commons-io组件:
            /*
            ServletFileUpload负责处理上传的文件数据并将表单中每个输入项封装成- - 个FileItem对象。
            在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象。
            所以,我们需要在进行解析工作前构造好DiskFileItemFactory对象。
            通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性。
            */
            try {
                //1.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的;
                DiskFileItemFactory factory = getDiskFileItemFactory(file);
                //2.获取ServletFileUpload
                ServletFileUpload upload = getServletFileUpload(factory);
                //3.处理上传的文件
    
                String msg = uploadParseRequest(upload, request, uploadPath);
                //servlet请求转发消息
                request.setAttribute("msg", msg);
                request.getRequestDispatcher("info.jsp").forward(request, response);
    
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
        }
    
        public static DiskFileItemFactory getDiskFileItemFactory(File file) {
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件中;
            factory.setSizeThreshold(1024 * 1024); //缓存区大小为1M
            factory.setRepository(file);//临时目录的保存目录,需要一个File
            return factory;
        }
    
        public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
            ServletFileUpload upload = new ServletFileUpload(factory);
            //监听文件上传进度;
            upload.setProgressListener(new ProgressListener() {
                @Override
                //pBytesRead:已经读取到的文件大小
                //pContentlength :文件大小
                public void update(long pBytesRead, long pContentLength, int pItems) {
                    System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead);
                }
            });
            //处理乱码问题
            upload.setHeaderEncoding("UTF-8");
            //设置单个文件的最大值
            upload.setFileSizeMax(1024 * 1024 * 10);
            //设置总共能够上传文件的大小
            //1024=1kb*1024=1M*10=10M
            upload.setSizeMax(1024 * 1024 * 10);
            return upload;
        }
    
        public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath)
                throws FileUploadException, IOException {
            String msg = "";
            //3.把前端请求解析,封装成一个FileItem对象
            List<FileItem> fileItems = upload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) { //判断上传的文件是普通的表单还是带文件的表单
                    //getFieldName指的是前端表单控件的name;
                    String name = fileItem.getFieldName();
                    String value = fileItem.getString("UTF-8"); //处理乱码
                    System.out.println(name + ":" + value);
                } else { //判断它是上传的文件
                    /*====================处理文件========================*/
                    //拿到文件名字
                    String uploadFileName = fileItem.getName();
                    System.out.println("上传的文件名: " + uploadFileName);
                    if (uploadFileName.trim().equals("") || uploadFileName == null) {
                        continue;
                    }
                    //获得上传的文件名/images/girl/paojie. png
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                    //获得文件的后缀名
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                    /*
                    如果文件后缀名fileExtName 不是我们所需要的
                    就直接return,不处理,告诉用户文件类型不对。
                    */
                    System.out.println("文件信息[件名: " + fileName + "---文件类型" + fileExtName + "]");
                    //可以使用UUID (唯一识别的通用码),保证文件名唯一;
                    //UUID. randomUUID(),随机生一个唯一识别的通 用码;
                    String uuidPath = UUID.randomUUID().toString();
                    /*==================处理文件完-=======================*/
                    //存到哪? uploadPath
                    //文件真实存在的路径realPath
                    String realPath = uploadPath + "/" + uuidPath;
                    //给每个文件创建一个对应的文件夹
                    File realPathFile = new File(realPath);
                    if (!realPathFile.exists()) {
                        realPathFile.mkdir();
                    }
                    /*====================存放地址完毕-========================*/
                    //获得文件上传的流
                    InputStream inputStream = fileItem.getInputStream();
                    //创建一个文件输出流
                    //realPath =真实的文件夹;
                    //差了一个文件;加上输出文件的名字+"/"+uuidFileName
                    FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
                    //创建一个缓冲区
                    byte[] buffer = new byte[1024 * 1024];
                    //判断是否读取完毕
                    int len = 0;
                    //如果大于0说明还存在数据;
                    while ((len = inputStream.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    //关闭流
                    fos.close();
                    inputStream.close();
                    msg = "文件上传成功!";
                    fileItem.delete(); //上传成功,清除临时文件
                    /*====================文件传输完==========================*/
                }
            }
            return msg;
        }
    }
    

    4、web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0"
             metadata-complete="true">
        <servlet>
            <servlet-name>FileServlet</servlet-name>
            <servlet-class>com.lenovo.servlet.FileServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>FileServlet</servlet-name>
            <url-pattern>/upload.do</url-pattern>
        </servlet-mapping>
    
    
    </web-app>
    

    5、info.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    ${msg}
    </body>
    </html>
    

    6、将文件从本地传至服务器

    文件下载

    1、步骤

    1. 要获取下载文件的路径
    2. 下载的文件名是啥?
    3. 设置想办法让浏览器能够支持(Content-Disposition) 下载我们需要的东西,中文文件
      名URLEncoder . encode编码,否则有可能乱码
    4. .获取下载文件的输入流
    5. 创建缓冲区
    6. 获取0utputStream对象
    7. 将FileOutputStream流写入到buffer缓中区,使用Outputstream将缓冲区中的数据
      输出到客户端!

    2、例题

    public class FileServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 1.要获取下载文件的路径
            String realPath = "D:\Project\IdeaProject\javaweb-01-servlet\response\src\main\resource\西贝.jpg";
            System.out.println("下载文件的路径: " + realPath);
            // 2.下载的文件名是啥?
            String fileName = realPath.substring(realPath.lastIndexOf("\") + 1);
            // 3.设置想办法让浏览器能够支持(Content -Disposition)下载我们需要的东西,中文文件名URLEncoder . encode编码,否则有可能乱码
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            // 4.获取下载文件的输入流
            FileInputStream in = new FileInputStream(realPath);
            // 5.创建缓冲区
            int len = 0;
            byte[] buffer = new byte[1024];
            // 6.获取0utputStream对象
            ServletOutputStream out = resp.getOutputStream();
            // 7.将FileOutputStream流 写入到buffer缓冲区,使用Outputstream将缓冲区中的数据输出到客户端!
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            in.close();
            out.close();
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

    视频学习取自:狂神说Java

  • 相关阅读:
    Excel Rendering Limitations
    Output Caching and VaryByParam, VaryByCustom
    ajaxToolkit:AutoCompleteExtender 使用键值对
    Sql Server 2005 存储过程分页
    WEB前端优化
    processModel Element in Machine.config
    如何监测虚拟内存
    MemoryLimit Tuning (ASP.NET v1.1)
    缓存之SqlDependency
    SQL产生随机字符串
  • 原文地址:https://www.cnblogs.com/zhuchengbo/p/12182725.html
Copyright © 2011-2022 走看看