• Java实现文件上传


    一. 注意事项

    在Web应用中,文件上传和下载功能是非常常用的功能,对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的

    【文件上传的注意事项】

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

    二. 文件上传步骤

    1. 下载jar包

    1-1.需要jar的地址:
    https://mvnrepository.com/artifact/commons-io/commons-io
    https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload
    1-2.在JavaWeb项目中导入jar包
    在这里插入图片描述
    1-3.【注意:使用IDEA导包需要注意修复路径,将lib添加到项目输出目录】
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2. 编写upload.jsp

    【注意:表单如果包含一个文件上传输入项的话
    这个表单的enctype属性就必须设置multipart/form-data】

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

    <form action="${pageContext.request.contextPath}/s"
    method="post" enctype="multipart/form-data">

    <p>上传用户:<input type="text" name="username"></p>
    <p>上传文件:<input type="file" name="file"></p>
    <p><input type="submit"></p>
    </form>

    </body>
    </html>

    3. 代码编写 UploadFileServlet

    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.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 ServletUpload extends javax.servlet.http.HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        <span class="hljs-keyword">try</span> {
    
            <span class="hljs-comment">//1.判断上传的文件是普通表单还是带文件的表单</span>
            <span class="hljs-keyword">if</span> (!ServletFileUpload.isMultipartContent(req)) {
                <span class="hljs-keyword">return</span>;<span class="hljs-comment">//如果是普通文件,直接返回</span>
            }<span class="hljs-comment">//通过if就是带文件的表单</span>
    
            <span class="hljs-comment">//2.创建上传文件的保存路径,建议在WEB-INF路径下</span>
            <span class="hljs-built_in">String</span> uploadPath = <span class="hljs-keyword">this</span>.getServletContext().getRealPath(<span class="hljs-string">"/WEB-INF/upload"</span>);
            File uploadFile = <span class="hljs-keyword">new</span> File(uploadPath);
            <span class="hljs-keyword">if</span> (!uploadFile.exists()) {
                uploadFile.mkdirs();<span class="hljs-comment">//如果保存目录不存在,就创建一个目录</span>
            }
    
            <span class="hljs-comment">//3.创建临时路径</span>
            <span class="hljs-built_in">String</span> tmpPath = <span class="hljs-keyword">this</span>.getServletContext().getRealPath(<span class="hljs-string">"/WEB-INF/tmp"</span>);
            File tmpFile = <span class="hljs-keyword">new</span> File(tmpPath);
            <span class="hljs-keyword">if</span> (!tmpFile.exists()) {
                tmpFile.mkdirs();<span class="hljs-comment">//如果临时目录不存在,就创建一个目录</span>
            }
    
            <span class="hljs-comment">//4.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的;</span>
            DiskFileItemFactory <span class="hljs-keyword">factory</span> = getDiskFileItemFactory(tmpFile);
    
            <span class="hljs-comment">//5.获取ServletFileUpload</span>
            ServletFileUpload upload = getServletFileUpload(<span class="hljs-keyword">factory</span>);
    
            <span class="hljs-comment">//6.处理上传的文件</span>
            <span class="hljs-built_in">String</span> msg = uploadParseRequest(upload, req, uploadPath);
    
            <span class="hljs-comment">//7.servlet请求转发消息</span>
            req.setAttribute(<span class="hljs-string">"msg"</span>,msg);
            req.getRequestDispatcher(<span class="hljs-string">"msg.jsp"</span>).forward(req,resp);
    
        } <span class="hljs-keyword">catch</span> (FileUploadException e) {
            e.printStackTrace();
        }
    }
    
    <span class="hljs-comment">//4.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的;</span>
    public <span class="hljs-keyword">static</span> DiskFileItemFactory getDiskFileItemFactory(File tmpFile) {
        DiskFileItemFactory <span class="hljs-keyword">factory</span> = <span class="hljs-keyword">new</span> DiskFileItemFactory();
        <span class="hljs-comment">//4-1.设置一个缓冲区,当上传文件大于这个缓冲区的时候,将它放在临时文件中</span>
        <span class="hljs-keyword">factory</span>.setSizeThreshold(<span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>);
        <span class="hljs-keyword">factory</span>.setRepository(tmpFile);<span class="hljs-comment">//4-2.临时目录的保存目录</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">factory</span>;
    }
    
    <span class="hljs-comment">//5.获取ServletFileUpload</span>
    public <span class="hljs-keyword">static</span> ServletFileUpload getServletFileUpload(DiskFileItemFactory <span class="hljs-keyword">factory</span>) {
        ServletFileUpload upload = <span class="hljs-keyword">new</span> ServletFileUpload(<span class="hljs-keyword">factory</span>);
        <span class="hljs-comment">//5-1.监听文件上传进度</span>
        upload.setProgressListener(<span class="hljs-keyword">new</span> ProgressListener() {
            <span class="hljs-meta">@Override</span>
            <span class="hljs-comment">//5-2.l:已经读取到文件的大小</span>
            <span class="hljs-comment">//5-3.l1:文件大小</span>
            public <span class="hljs-keyword">void</span> update(long l, long l1, <span class="hljs-built_in">int</span> i) {
                System.out.println(<span class="hljs-string">"总大小:"</span> + l1 + <span class="hljs-string">"	"</span> + <span class="hljs-string">"已上传:"</span> + l);
            }
        });
        upload.setHeaderEncoding(<span class="hljs-string">"utf-8"</span>);<span class="hljs-comment">//5-4.处理乱码问题</span>
        upload.setFileSizeMax(<span class="hljs-number">1024</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">10</span>);<span class="hljs-comment">//5-5.设置单个文件的最大值</span>
        upload.setSizeMax(<span class="hljs-number">1024</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">10</span>);<span class="hljs-comment">//5-6.设置总共能够上传文件的大小</span>
        <span class="hljs-keyword">return</span> upload;
    }
    
    <span class="hljs-comment">//6.处理上传的文件</span>
    public <span class="hljs-keyword">static</span> <span class="hljs-built_in">String</span> uploadParseRequest(ServletFileUpload upload, HttpServletRequest req, <span class="hljs-built_in">String</span> uploadPath)
            throws FileUploadException, IOException {
        <span class="hljs-built_in">String</span> msg = <span class="hljs-string">""</span>;
    
        <span class="hljs-comment">//6-1.把前端请求解析,封装成一个FileItem对象</span>
        <span class="hljs-built_in">List</span>&lt;FileItem&gt; fileItems = upload.parseRequest(req);
        <span class="hljs-keyword">for</span> (FileItem fileItem : fileItems) {
            <span class="hljs-keyword">if</span> (fileItem.isFormField()) {<span class="hljs-comment">//6-2.判断上传的文件是普通的表单还是带文件的表单</span>
                <span class="hljs-built_in">String</span> name = fileItem.getFieldName();
                <span class="hljs-built_in">String</span> value = fileItem.getString(<span class="hljs-string">"utf-8"</span>);<span class="hljs-comment">//6-3.处理 乱码</span>
            } <span class="hljs-keyword">else</span> {<span class="hljs-comment">//6-4.判断它是上传文件</span>
    
                <span class="hljs-comment">//6-5.拿到文件名字</span>
                <span class="hljs-built_in">String</span> uploadFileName = fileItem.getName();
                System.out.println(<span class="hljs-string">"上传的文件名:"</span> + uploadFileName);
                <span class="hljs-keyword">if</span> (uploadFileName.trim().equals(<span class="hljs-string">""</span>) || uploadFileName == <span class="hljs-keyword">null</span>) {
                    <span class="hljs-keyword">continue</span>;
                }
    
                <span class="hljs-comment">//6-6.获得上传文件名</span>
                <span class="hljs-built_in">String</span> fileName = uploadFileName.substring(uploadFileName.lastIndexOf(<span class="hljs-string">"/"</span>) + <span class="hljs-number">1</span>);
                <span class="hljs-comment">//6-7.获得文件的后缀名</span>
                <span class="hljs-built_in">String</span> fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(<span class="hljs-string">"."</span>) + <span class="hljs-number">1</span>);
                System.out.println(<span class="hljs-string">"文件信息 [文件名:"</span> + fileName + <span class="hljs-string">"---文件类型"</span> + fileExtName + <span class="hljs-string">"]"</span>);
                <span class="hljs-comment">//6-8.使用UUID(唯一识别的通用码),保证文件名唯一</span>
                <span class="hljs-built_in">String</span> uuidPath = UUID.randomUUID().toString();
                <span class="hljs-comment">//6-9.文件真实存在的路径 realPath</span>
                <span class="hljs-built_in">String</span> realPath = uploadPath + <span class="hljs-string">"/"</span> + uuidPath;
                <span class="hljs-comment">//6-10.给每个文件创建一个对应的文件夹</span>
                File realPathFile = <span class="hljs-keyword">new</span> File(realPath);
                <span class="hljs-keyword">if</span> (!realPathFile.exists()) {
                    realPathFile.mkdir();
                }
    
                <span class="hljs-comment">//6-11.获得文件上传的流</span>
                InputStream inputStream = fileItem.getInputStream();
                <span class="hljs-comment">//6-12.创建一个文件输出流</span>
                <span class="hljs-comment">//6-13.realPath = 真实的文件夹;</span>
                <span class="hljs-comment">//6-14.差了一个文件; 加上输出文件的名字+"/"+uuidFileName</span>
                FileOutputStream fos = <span class="hljs-keyword">new</span> FileOutputStream(realPath + <span class="hljs-string">"/"</span> + fileName);
                <span class="hljs-comment">//6-15.创建一个缓冲区</span>
                byte[] buffer = <span class="hljs-keyword">new</span> byte[<span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>];
                <span class="hljs-comment">//6-16.判断是否读取完毕</span>
                <span class="hljs-built_in">int</span> len = <span class="hljs-number">0</span>;
                <span class="hljs-comment">//6-17.如果大于0说明还存在数据;</span>
                <span class="hljs-keyword">while</span> ((len = inputStream.read(buffer)) &gt; <span class="hljs-number">0</span>) {
                    fos.write(buffer, <span class="hljs-number">0</span>, len);
                }
    
                <span class="hljs-comment">//6-18.关闭流</span>
                fos.close();
                inputStream.close();
    
                msg = <span class="hljs-string">"文件上传成功!"</span>;
                fileItem.delete();<span class="hljs-comment">//6-19.上传成功,清除临时文件</span>
            }
        }
        <span class="hljs-keyword">return</span> msg;
    }
    
    
    <span class="hljs-meta">@Override</span>
    protected <span class="hljs-keyword">void</span> doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
    }
    

    }

    4. 编写msg.jsp

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

    5. 配置web.xml

       <servlet>
            <servlet-name>ServletFileUpload</servlet-name>
            <servlet-class>com.sz.ServletUpload</servlet-class>
        </servlet>
    
    <span class="hljs-tag">&lt;<span class="hljs-name">servlet-mapping</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">servlet-name</span>&gt;</span>ServletFileUpload<span class="hljs-tag">&lt;/<span class="hljs-name">servlet-name</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">url-pattern</span>&gt;</span>/s<span class="hljs-tag">&lt;/<span class="hljs-name">url-pattern</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">servlet-mapping</span>&gt;</span>
    

  • 相关阅读:
    NOIP 2012 文化之旅
    史上最全的各种C++ STL容器全解析
    详解C++ STL map 容器
    详解C++ STL priority_queue 容器
    浅谈C++ STL stack 容器
    浅谈C++ STL queue 容器
    浅谈C++ STL vector 容器
    CF1185F Two Pizzas
    浅谈C++ STL deque 容器
    详解C++ STL multiset 容器
  • 原文地址:https://www.cnblogs.com/edda/p/13328312.html
Copyright © 2020-2023  润新知