Loading

Javaweb文件上传——详细可见Java I/O

文件上传的前端必要参数

get方法上传文件有大小限制,post无限制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form action="${pageContext.request.contextPath }/upload.do" enctype="multipart/form-data" method="post" >
    上传用户:<input type="text" name="username"><br/>
    <input type="file" name="file1"><br/>
    <input type="file" name="file2">
    <input type="submit"> | <input type="reset">
  </form>
  </body>
</html>

文件上传请求处理

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("进入servlet...............");
        FileMothed fileMothed = new FileMothed();
        //若返回值为true则是带文件上传的表单;返回值为false则是普通表单。
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;//终止运行
        }

        //创建上传文件的保存路径,建议放在WEB-INF下,安全,用户无法直接访问上传的文件
        String realPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(realPath);
        if (!uploadFile.exists()) {
            uploadFile.mkdir();//创建这个目录
        }
        //缓存,临时文件
        //临时文件,加入文件超过了预期的大小,我们就把它放到一个临时文件中,过几天自动删除,或提醒用户转存为永久
        String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
        File file = new File(tmpPath);
        if (!file.exists()){
            file.mkdir();//创建这个临时文件夹
        }
        //处理上传的文件,一般都需要通过流来获取,我可以通过request.getInputStream();原生太的文件上传流获取,但十分麻烦
        //建议使用Apache的文件上传组件来实现,common-fileupload它需要依赖于commons-io组件
        //1.创建DiskFileItemFactory对象,处理文件上传的路径或者大小限制(可以封装为单独的方法)
        DiskFileItemFactory factory = fileMothed.getDiskFileItemFactory(file);
        /*ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象,
        在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象
        所以,我们需要在进行解析工作之前构造好DiskFileItemFactory对象
        通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性
        * */
        //2.获取ServletFileUpload
        ServletFileUpload fileUpload = fileMothed.getServletFileUpload(factory);

        //3.处理上传文件
        String msg = null;
        try {
            msg = fileMothed.uploadFile(request, realPath, fileUpload);
            //转发
            request.setAttribute("msg", msg);
            request.getRequestDispatcher("/info.jsp").forward(request, response);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }

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

文件上传方法体

public class FileMothed{

    public static DiskFileItemFactory getDiskFileItemFactory(File file){
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //通过该工厂设置一个缓冲区大小,当文件上传的大小超过这个缓冲区的时候,将其放入到临时文件目录下
        factory.setSizeThreshold(1024*1024);//缓存大小1M
        factory.setRepository(file);//零食文件 的保存目录,需要传入一个File
        return factory;
    }

    public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory){
        ServletFileUpload upload = new ServletFileUpload(factory);
        //监听文件上传进度、
        upload.setProgressListener(new ProgressListener() {
            @Override
            public void update(long pBytesRead, long pContentLength, int i) {
                //pBytesRead:已经读取到的文件大小
                //pContentLength:文件大小
                System.out.println("总大小:"+pContentLength+"已上传:"+pBytesRead);
            }

        });
        //处理乱码问题
        upload.setHeaderEncoding("UTF-8");
        //设置单个文件的最大值
        upload.setFileSizeMax(1024*1024*10);
        //设置总共能够上传文件的大小
        //1024=1kb*1024=1M*10=10M
        upload.setSizeMax(1024*1024*100);

        return upload;
    }

    public String uploadFile(HttpServletRequest request, String uploadPath, ServletFileUpload upload) throws IOException, FileUploadException {
        String msg = "";
        //把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
        //ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象
        try {
            List<FileItem> fileItems = upload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) {//如果是普通的输入表单
                    String fieldName = fileItem.getFieldName();
                    //处理乱码
                    String value = fileItem.getString("UTF-8");
                    System.out.println(fieldName + ":" + value);
                } else {//文件情况下
                    //文件
                    //===========处理文件============
                    String uploadFileName = fileItem.getName();
                    System.out.println("uploadFileName:" + uploadFileName);
                    //可能存在文件名不合法的情况
                    //去掉首尾空格
                    if (uploadFileName == null || "".equals(uploadFileName.trim())) {
                        continue;
                    }
                    //获取上传的文件名
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                    //获取文件的后缀名
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                    //如果文件后缀名fileExtName不是我们所需要的,就直接return,不处理,告诉用户文件类型不对

                    //可以使用UUID(统一识别的通用码),保证文件名唯一
                    //UUID.randomUUID() 随机生一个唯一识别的通用码
                    //网络从传输中的东西,都需要序列化
                    //implements java.io.Serializable 标记接口  JVM本地方法栈--调用》C++
                    String uuidPath = UUID.randomUUID().toString();

                    //===========存放地址============
                    String realPath = uploadPath + "/" + uuidPath;
                    File realPathFile = new File(realPath);
                    if (!realPathFile.exists()) {
                        realPathFile.mkdir();
                    }
                    //===========文件传输============
                    InputStream inputStream = fileItem.getInputStream();
                    FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
                    byte[] buffer = new byte[1024 * 1024];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    fos.close();
                    inputStream.close();
                    msg = "上传成功~";
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
            msg = "上传失败~";
        }
        return msg;
    }
}
posted @ 2022-03-15 21:26  Cn_FallTime  阅读(36)  评论(0编辑  收藏  举报