Skip to content

需要的包:commons-fileupload使用说明

参考博客

1. 创建文件上传表单

<form action="/UploadFile" method="post" enctype="multipart/form-data">
    文件上传
    <input type="file" name="any"><br>
    <button type="submit">上传</button>
</form>

方法必须是post,一定要有enctype="multipart/form-data"type="file"

还有一种方法是构造表单:

<input type="file" id="blog" placeholder="选择文件"/>
<button @click="uploadBlog">上传博客</button>

uploadBlog: function () {
    let file = document.getElementById('blog').files[0]
    let param = new FormData()
    param.append('any', file)
    console.log(param.get('any'))
    this.$axios.post('/api/blog/blog/UploadFile3', param, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
    })
}

2. 编写servlet

package servlet;

import exception.ContentTypeException;
import exception.UploadFileException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

@WebServlet("/UploadFile")
public class UploadFile extends HttpServlet {

    private static final String UPLOAD_DIRECTORY = "D:/logs/uploadFiles";

    //内存临界值 - 超过后将产生临时文件并存储于临时目录中
    private static final int MEM_SIZE = 1024 *1024 * 2;
    //最大请文件大小
    private static final long MAX_FILE_SIZE = 1024 *1024 * 40;
    //最大请求值 (包含文件和表单数据)
    private static final long MAX_REQUEST_SIZE = 1024 *1024 * 50;


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //是否为多媒体类型
        if (!ServletFileUpload.isMultipartContent(req)){
            throw new ContentTypeException("请求内容类型错误");
        }

        // 配置上传参数
        DiskFileItemFactory dfif = new DiskFileItemFactory();
        dfif.setDefaultCharset("UTF-8");
        dfif.setSizeThreshold(MEM_SIZE);
        //临时存储目录
        dfif.setRepository(new File(System.getProperty("java.io.tmpdir")));

        ServletFileUpload sfu = new ServletFileUpload();
        sfu.setFileItemFactory(dfif);
        sfu.setFileSizeMax(MAX_FILE_SIZE);
        sfu.setHeaderEncoding("UTF-8");
        sfu.setSizeMax(MAX_REQUEST_SIZE);

        // 构造临时路径来存储上传的文件
        File uploadDir = new File(UPLOAD_DIRECTORY);
        if (!uploadDir.exists()){
            if (!uploadDir.mkdir()){
                throw new FileNotFoundException("无法创建文件夹");
            }
        }

        try {
            //迭代表单数据
            List<FileItem> fileItems = sfu.parseRequest(req);

            //处理不在表单中的字段,即文件
            if (fileItems != null && fileItems.size() > 0){
                for (FileItem fileItem: fileItems){
                    if (!fileItem.isFormField()){
                        //正常化文件名
                        String fileName = new File(fileItem.getName()).getName();
                        String filePath = UPLOAD_DIRECTORY + File.separator + fileName;
                        File storeFile = new File(filePath);

                        System.out.println(filePath);
                        //写文件
                        fileItem.write(storeFile);
                    }
                }
            }
        }catch (Exception e){
            throw new UploadFileException(e.getMessage());
        }

        //不设置这个会导致乱码
        resp.setContentType("text/html");
        String data = "上传成功";
        resp.getWriter().write(data);
    }
}

3. 已知缺陷

不能重复上传二进制文件。