Java 文件上传

文件上传的代码编写

用了两个上传的jar包,commons-fileupload.jar和commons-io.jar

package com.zpchcbd;

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.*;
import java.util.List;
import java.util.UUID;


public class UploadServlet extends HttpServlet {


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


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        DiskFileItemFactory diskFileItemFactory = initDiskFileItemFactory();
        ServletFileUpload servletFileUpload = initServletFileUpload(diskFileItemFactory);
        uploadFileRequest(servletFileUpload, req);
    }


    public DiskFileItemFactory initDiskFileItemFactory(){
        // common-upload实例化要用到的对象
        DiskFileItemFactory factory = new DiskFileItemFactory();
        return factory;
    }


    public ServletFileUpload initServletFileUpload(DiskFileItemFactory factory){
        ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
        servletFileUpload.setHeaderEncoding("utf-8");
        servletFileUpload.setProgressListener(new ProgressListener() {
            @Override
            public void update(long l, long l1, int i) {
                System.out.println("已上传字节: " + l);
            }
        });
        return servletFileUpload;
    }


    public void uploadFileRequest(ServletFileUpload servletFileUpload, HttpServletRequest req){
        // 判断存储的文件夹是否存在
        String uploadPath = getServletContext().getRealPath("/WEB-INF/upload");
        File file = new File(uploadPath);
        if (!file.exists()){
            file.mkdir();
        }


        // 判断整个数据包是否是Multipart类型
        if (ServletFileUpload.isMultipartContent(req)){


            // 解析上传的请求包
            try {
                // 解析请求包
                List<FileItem> files = servletFileUpload.parseRequest(req);


                // 遍历请求包中的内容
                for (FileItem fileItem : files) {
                    // 判断表单是不是文件类型
                    if (!fileItem.isFormField()){
                        // 是文件类型的处理

                        // 获取表单中的文件名
                        String fileUploadName = fileItem.getName();

                        // 判断文件名是否合法
                        if (fileUploadName.equals("")){
                            continue;
                        }

                        // 处理文件名的名称和合法后缀名
                        String fileName = fileUploadName.substring(fileUploadName.lastIndexOf("/")+1);
                        String fileExtention = fileUploadName.substring(fileUploadName.lastIndexOf(".")+1);
                        String[] allowType = {"jpg", "png", "bmp", "gif", "txt"};
                        boolean flag = false;
                        for (String s : allowType) {
                            if (fileExtention.equals(s)) {
                                flag = true;
                                break;
                            }
                        }

                        // 进行判断后缀名的合法性
                        System.out.println("文件名称: " + fileName);
                        System.out.println("文件后缀: " + fileExtention);

                        if (!flag){
                            throw new Exception("文件后缀名有误,请重新上传!");
                        }

                        // 拼接存储到磁盘的文件的文件名
                        String filePath = uploadPath + "/" + UUID.randomUUID();

                        // 为了防止文件覆盖,所以为每一个文件都创建一个随机的uuid的文件夹来进行存储文件
                        File f = new File(filePath);
                        if (!f.exists()){
                            f.mkdir();
                        }

                        // 获取每个字段为file的输入流
                        InputStream is = fileItem.getInputStream();

                        // 获取磁盘上的输出流,写入内容
                        OutputStream os = new FileOutputStream(filePath + "/" + fileUploadName);

                        // 写入文件
                        byte[] bytes = new byte[1024];
                        int len = -1;
                        while ((len = is.read(bytes)) != -1) {
                            os.write(bytes, 0, len);
                        }

                        // 关闭流
                        os.close();
                        is.close();

                        // 清除缓存文件
                        fileItem.delete();
                    }else{
                        // 不是文件类型的处理
                        throw new Exception("上传失败,请重新上传!");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    }
}

CVE-2020-1938的利用

这是在内网中很多漏洞,自己同样通过它解决了很多问题!

X

posted @ 2021-05-04 15:11  zpchcbd  阅读(114)  评论(0)    收藏  举报