JavaWeb-文件上传案例

使用fileupload组件完成文件的上传应用

1)需求:

Ⅰ。上传

  > 在upload.jsp页面上使用jQuery实现"新增一个附件",”删除附件“,但至少需要保留一个。

  > 对文件的扩展名和文件的大小进行验证,以下的规则是可配置的,而不是写死在程序中的

   >>文件的扩展名必须为.pptx,docx,doc

   >>每个文件的大小不能超过1M

   >>总的文件大小不能超过5M

  > 若验证失败,则在upload.jsp页面上显示错误信息:

    >> 若某一个文件不符合要求:xxx文件扩展名不合法或xxx文件大小超过1M

    >> 总的文件大小不能超过5M

  > 若验证通过,则进行文件的上传操作

    >>文件上传,并给一个不能和其他文件重复的名字,但扩展名不变

    >>在对应的数据表中添加一条记录

    id  file_name  file_path  file_desc

 

jsp页面:

 

<%--
  Created by IntelliJ IDEA.
  User: dell
  Date: 2019/7/22
  Time: 10:19
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="/jQuery/jquery-3.4.0.min.js"></script>
    <script type="text/javascript">
        $(function () {
            var i =2;

            $("#addFile").click(function () {
                $(this).parent().parent().before("<tr class='file'><td>File"
                    + i +":</td><td><input type='file' name='file"
                    + i +"'></td></tr><tr class='desc'><td>Desc"
                    + i +":</td><td><input type='text' name='desc"
                    + i +"'><input type='button' id='delete"
                    + i +"' value='删除'></input></td></tr>");
                i++;
                //获取删除按钮
                $("#delete" + (i-1)).click(function () {
                   var $tr = $(this).parent().parent();
                   $tr.prev("tr").remove();
                   $tr.remove();

                   //对i重新排序
                   $(".file").each(function (index) {
                       var n = index +1;
                       $(this).find("td:first").text("File" + n);
                       $(this).find("td:last input").attr("name","file"+n);
                   })
                    $(".desc").each(function (index) {
                        var n = index +1;
                        $(this).find("td:first").text("Desc" + n);
                        $(this).find("td:last input").attr("name","desc"+n);
                    })
                    i--;
                });

            });
        })
    </script>
</head>
<body>

    <font color="red">${msg }</font>
    <br><br>
    <form action="/FileUploadServlet" method="post" enctype="multipart/form-data">
        <input type="hidden" id="fileNum" name="fileNum" value="1">

        <table>
            <tr class="file">
                <td>File1:</td>
                <td><input type="file" name="file1"></td>
            </tr>
            <tr class="desc">
                <td>Desc1:</td>
                <td><input type="text" name="desc1"></td>
            </tr>
            <tr>
                <td><input type="submit" id="submit" value="提交"></td>
                <td><input type="button" id="addFile" value="新增一个附件"></td>
            </tr>
        </table>
    </form>
</body>
</html>

  

配置文件:

exts=pptx,docx,doc
file.max.size=1048576
total.file.max.size=5242880

  

配置文件实例化的类

package entity;

import java.util.HashMap;
import java.util.Map;

public class FileUploadAppProperties {
    private Map<String,String> properties = new HashMap<>();

    private FileUploadAppProperties(){}

    private static FileUploadAppProperties instance = new FileUploadAppProperties();

    public static FileUploadAppProperties getInstance(){
        return instance;
    }

    public void addProperties(String propertyName,String propertyValue){
        properties.put(propertyName,propertyValue);
    }

    public String getProperty(String propertyName){
        return properties.get(propertyName);
    }
}

  

 监听:

package listener;

import entity.FileUploadAppProperties;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;

public class FileUploadAppListener implements ServletContextListener {
    public FileUploadAppListener() {
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        InputStream in = getClass().getClassLoader().getResourceAsStream("WEB-INF/upload.properties");
        Properties properties = new Properties();

        try {
            properties.load(in);

            for (Map.Entry<Object,Object> prop: properties.entrySet()
                 ) {
                String propertyName = (String) prop.getKey();
                String propertyValue = (String) prop.getValue();
                FileUploadAppProperties.getInstance().addProperties(propertyName,propertyValue);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }
}

  

Servlet

package servlet;

import entity.FileUploadAppProperties;
import entity.FileUploadBean;
import exception.InvalidExtNameException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
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.*;
import java.util.*;

public class FileUploadServlet extends HttpServlet {

    private static final String FILE_PATH = "/WEB-INF/files/";

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String path = null;

            ServletFileUpload upload = getServletFileUpload();

            try {
                //把需要上传的FileItem都放入到该Map中
                //键:文件的待存放的路径,值:对应的FileItem对象
                Map<String,FileItem> uploadFiles = new HashMap<String,FileItem>();

                //解析请求,得到FileItem的集合
                List<FileItem> items = upload.parseRequest(req);

                //1.构建FileUploadBean的集合,同时填充uploadFiles
                List<FileUploadBean> beans = buildFileUploadBeans(items,uploadFiles);
                
                //2.校验扩展名
                vaidateExtName(beans);

                //3.校验文件的大小:在解析时,已经校验了,我们只需要通过异常得到结果

                //4.进行文件的上传操作
                upload(uploadFiles);

                //5.把上传的信息保存到数据库中
                saveBeans(beans);

                path = "/upload/success.jsp";
            } catch (Exception e) {
                e.printStackTrace();
                path = "/upload/upload.jsp";
                req.setAttribute("msg",e.getMessage());
            }
            req.getRequestDispatcher(path).forward(req,resp);

    }

    private ServletFileUpload getServletFileUpload() {
        String exts = FileUploadAppProperties.getInstance().getProperty("exts");
        String fileMaxSize = FileUploadAppProperties.getInstance().getProperty("file.max.size");
        String totalFileMaxSize = FileUploadAppProperties.getInstance().getProperty("total.file.max.size");

        DiskFileItemFactory factory = new DiskFileItemFactory();

        factory.setSizeThreshold(1024 * 500);
        File tempDirectory = new File("d:\\tempDirectory");
        factory.setRepository(tempDirectory);
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setSizeMax(Integer.parseInt(totalFileMaxSize));
        upload.setFileSizeMax(Integer.parseInt(fileMaxSize));
        return  upload;
    }

    private void saveBeans(List<FileUploadBean> beans) {
    }

    /**
     * 校验扩展名是否合法
     * @param beans
     */
    private void vaidateExtName(List<FileUploadBean> beans) {
        String exts = FileUploadAppProperties.getInstance().getProperty("exts");
        List<String> extList = Arrays.asList(exts.split(","));

        for (FileUploadBean bean : beans
             ) {
            String fileName = bean.getFileName();
            String extName = fileName.substring(fileName.lastIndexOf(".")+1);
            if (!extList.contains(extName)){
                throw new InvalidExtNameException(fileName + "扩展名不合法");
            }
        }
    }


    /**
     * 利用传入的FileItem的集合,构建FileUploadBean的集合,同时填充uploadFiles
     * FileUploadBean对象封装了:id,fileName,file'P'ath,fileDesc
     * uploadFiles:Map<String,FileItem>类型,存放文件域类型的FileItem。键:待保存的文件的名字,值:FileItem对象
     * 构建过程:
     * 1.遍历FileItem的集合,得到desc的Map<String,string>,键:desc的fieldName(desc1,desc2...),
     *
     * 2.遍历FileItem的集合,得到文件域额那些FileItem对象,构建对应的key(desc1...)来获取其desc,构建的FileUploadBean对象,并填充beans和uploadFiles。
     * @param items
     * @param uploadFiles
     * @return
     */
    private List<FileUploadBean> buildFileUploadBeans(List<FileItem> items, Map<String, FileItem> uploadFiles) {

        List<FileUploadBean> beans = new ArrayList<>();

        //1.遍历FileItem的集合,先得到desc的Map<String,string>,其中键:fieldName(desc1,desc2...),
        //值表单域对应字段的值
        Map<String,String> descs  = new HashMap<>();

        for (FileItem item : items
             ) {
            if (item.isFormField())
            descs.put(item.getFieldName(),item.getString());
        }


        //2.遍历FileItem的集合,得到文件域的FileItem对象
        //每得到一个FileItem对象都创建一个FileUploadBean对象
        //得到fileName,构建filePath,从1的Map中得到当前FileItem对应的那个desc。
        //使用fileName后面的数字去匹配
        for (FileItem item : items
        ) {
            if (!item.isFormField()){
                String fieldName = item.getFieldName();
                String index = fieldName.substring(fieldName.length()-1);

                String fileName = item.getName();
                String desc = descs.get("desc" + index);
                String filePath = getFilePath(fileName);

                FileUploadBean bean = new FileUploadBean(fileName,filePath,desc);
                 beans.add(bean);

                 uploadFiles.put(filePath,item);
            }

        }


        return beans;
    }

    /**
     * 根据指定的文件名构建一个随机的文件名
     * 1.构建的文件的文件名的扩展名和给定的文件的扩展名一致
     * 2.利用ServletContext的getRealPath方法获取的绝对路径
     * 3.利用Random和当前的系统时间构建随机的文件的名字
     * @param fileName
     * @return
     */
    private String getFilePath(String fileName) {
        String extName = fileName.substring(fileName.lastIndexOf("."));
        Random random = new Random();
        int randomNumber = random.nextInt(100000);

        String filePath = getServletContext().getRealPath(FILE_PATH)+"\\" + System.currentTimeMillis()+ randomNumber + extName;

        return filePath;
    }

    /**
     * 文件上传前的准备工作,得到filePath和InputStream
     * @param uploadFiles
     * @throws IOException
     */
    private void upload(Map<String, FileItem> uploadFiles) throws IOException {

        for (Map.Entry<String,FileItem> uploadFile : uploadFiles.entrySet()
             ) {
            String filePath = uploadFile.getKey();
            FileItem item = uploadFile.getValue();

            upload(filePath,item.getInputStream());
        }
    }

    /**
     * 文件上传的io方法
     * @param filePath
     * @param inputStream
     * @throws IOException
     */
    private void upload(String filePath, InputStream inputStream) throws IOException {
        OutputStream out = new FileOutputStream(filePath);
        byte[] buffer = new byte[1024];
        int len = 0;

        while ((len = inputStream.read(buffer))!=-1){
            out.write(buffer,0,len);
        }
        inputStream.close();
        out.close();
    }
}

  

异常:

package exception;

public class InvalidExtNameException extends RuntimeException {

    public InvalidExtNameException(String msg){
        super(msg);
    }

}

  

 

posted @ 2019-07-22 14:29  鸿森  阅读(364)  评论(0编辑  收藏  举报