文件上传及拓展

该博客介绍了如何使用Apache的FileUpload组件处理POST方式上传的文件,包括设置上传文件的大小限制、创建临时文件存储、解析上传请求并保存文件到指定目录。同时,文章提及了文件上传的安全性和处理乱码问题的方法。
摘要由CSDN通过智能技术生成
<%--表单上传文件
    get:上传文件大小有限制
    post:没有限制
    --%>
<form action="" enctype="multipart/form-data" method="post">
    上传用户:<input type="text" name="username"><br>

    <p><input type="file"/></p>
    <p><input type="file"/></p>
    <p><input type="submit">|<input type="reset"> </p>
</form>
public class UploadFileServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String msg = "";
        //        判断上传的文件是普通表单 还是带文件表单
        if (!ServletFileUpload.isMultipartContent(req)) {
            return;//终止方法运行,说明这是一个普通的表单,直接返回
        }
//        创建上传文件的保存路径,建议在WEB-INF路径,安全,用户无法直接访问上传的文件;
        try {
            String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");//获得全局的上下文,真实的地址
            File uploadFile = new File(uploadPath);
            if (!uploadFile.exists()) {
                uploadFile.mkdir();//创建这个目录
            }
//        缓存。临时文件
//        临时文件假如超过了预期的大小,我们就把他放到一个临时文件中,过几天自动删除,或者提醒用户转存为永久文件
            String tmpPath = this.getServletContext().getRealPath("/WEB-INF/temp");
            File tmpfile = new File(tmpPath);
            if (!tmpfile.exists()) {
                tmpfile.mkdir();//创建这个临时目录
            }

            //        1.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制
            DiskFileItemFactory factory = getDiskFileItemfactory(tmpfile);
            //        2、获取ServletFileUpload
            ServletFileUpload upload = getServletFileUpload(factory);
            //        3、处理上传文件
            msg = uploadParseRequest(upload, req, uploadPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        req.setAttribute("msg", msg);
        req.getRequestDispatcher("info.jsp").forward(req, resp);

    }


    //        1、处理上传的文件,一般需要通过流来获取,我们可以使用request.getInputStream(),原生态的文件上传流获取,十分麻烦
//        但是我们都建议使用Apach的文件上传组件来实现,common-fileupload,它需要依赖于commons-io组件
//        通过这个工厂设置一个缓冲区, 当上传的文件大于这个缓冲区的时候,将他放到临时文件中
    private DiskFileItemFactory getDiskFileItemfactory(File tmpfile) {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setSizeThreshold(1024 * 1024);//缓存区大小为1M
        factory.setRepository(tmpfile);//临时文件保存目录,需要一个File
        return factory;
    }

    //        2、获取ServletFileUpload
    private 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);
//        设置总共能够上传文件的大小
//        1Kb*1024=1M*10=10M
        upload.setSizeMax(1024 * 1024 * 10);
        return upload;
    }


    //3、处理上传文件
    private String uploadParseRequest(ServletFileUpload upload, HttpServletRequest req, String uploadPath) throws IOException {
//        3、处理上传的文件
        //把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
        List<FileItem> fileItems = null;
        String msg = "";
        try {
            fileItems = upload.parseRequest(req);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        for (FileItem fileItem : fileItems) {
            if (fileItem.isFormField()) {
//            getFileName指的是前端表单控件的name;
                String name = fileItem.getFieldName();
                String value = fileItem.getString("utf-8");
//   =========================处理文件=========================
//                    拿到文件的名字
                String uploadFileName = fileItem.getName();
//                    可能存在文件名不合法的情况
                if (uploadFileName.trim().equals("") || uploadFileName == null) {
                    continue;
                }
//                    获得上传的文件名 /images/girl/pao.png
                String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
//                    获得文件的后缀名
                String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                /*
                 * 如果文件后缀名fileName 不是我们所需要的
                 * 就直接return,不处理,告诉用户文件类型不对
                 * */
//                    可以使用UUID(唯一识别的通用码),保证文件名唯一
//                    UUID.randomUUID(),最忌生成一个唯一识别的通用码;
//                    网络传输中的东西 都需要序列化
//                    POJO,实体类,如果想要在多个电脑上运行,传输--->需要把对象都序列化了
//                    JNT = Java Native Interface
//                    implement Serializable:标记接口,JVM--->Java栈 本地方法栈 native--->C++

                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;

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不想当个程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值