ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javaweb上传文件

2022-02-23 21:32:02  阅读:170  来源: 互联网

标签:文件 String upload 表单 ServletFileUpload 上传 javaweb


目录

1.简述

2.原理讲解

3.代码如下(含注释)

3.1获得DiskFileItemFactory对象

3.2获得ServletFileUpload对象 

 3.3上传文件 

3.4 doPost()

4.运行结果


1.简述

在一个web项目中,用户向工程中上传文件是十分常见的操作,如头像设置、背景图片设置等。服务器在保存用户上传的文件的时候,需要解决以下四个问题:1.用户上传的文件不能直接通过在地址栏输入url去访问;2.用户上传的文件不能被覆盖(在同一个文件夹下的同名文件会被覆盖)。

这篇文章将简单讲解如何在Javaweb项目上传文件并解决上面提到的四个问题

2.原理讲解

上传文件的表单如图所示

 

 

一般在处理上传文件的时候,用流来处理,但是这样的话需要自己实现网络通信底层,太麻烦了,这里使用apache的commons-io组件来完成。

ServletFileUpload类负责处理上传的文件数据,并将表单中的每个输入项封装成FileItem对象。在获取ServletFileUpload对象的时候,需要一个DiskFileItemFactory对象

通过ServletFileUpload对象获得FileItem对象后,遍历所有的FileItem对象,判断每个对象只是简单的表单元素还是包含了文件,若包含了文件,将文件进行处理保存,并转发到上传信息的页面就好了。

3.代码如下(含注释)

3.1获得DiskFileItemFactory对象

    public DiskFileItemFactory getDiskFileItemFactory(File tempFile){
        DiskFileItemFactory factory = new DiskFileItemFactory();
//        为上传文件设置一个大小限定,当文件超过这个大小的时候,缓存在暂存区
        factory.setSizeThreshold(1024*1024); //大小为1M
        factory.setRepository(tempFile); //设置暂存区
        return factory;
    }

3.2获得ServletFileUpload对象 

    public 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);
//        设置总共能够上传文件的大小
        upload.setSizeMax(1024*1024*10);

        return upload;
    }

 3.3上传文件 

public void uploadFile(HttpServletRequest req, HttpServletResponse resp,ServletFileUpload upload, String uploadPath) throws IOException, ServletException {
        String msg = "文件上传失败";

//        把前端请求解析,封装成一个FileItem对象,从ServletFIleUpload对象中获取
        List<FileItem> fileItems = null;
        try {
            fileItems = upload.parseRequest(req);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        for (FileItem fileItem : fileItems) {
//            当前FileItem对象只是一个表单对象
            if(fileItem.isFormField()){
                String name = fileItem.getFieldName(); //获得表单控件的name值
                String value = fileItem.getString("UTF-8");//获得文本,处理乱码
                System.out.println(name+" :"+value);
            }else {
//            当前FileItem包含文件
//                    ===========================处理文件===============================
                String uploadFileName = fileItem.getName();
                if(uploadFileName.trim().equals("") || uploadFileName==null){
                    continue;
                }
                //                获得上传的文件名
                String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/")+1);
//                获得上传的文件后缀
                String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);

//                使用UUID获得一个唯一的识别通用码,保证文件名唯一
//                网络传输中的东西,都需要序列化
//                实体类如果想要在多个电脑上运行,需要进行传输===》使用序列号
                String uuidPath = UUID.randomUUID().toString();

//                ==========================存放地址==========================================
                String readPath = uploadPath+"/"+uuidPath;
//                给每个文件创建也给对应的文件夹
                File realPathFile = new File(readPath);
                if(!realPathFile.exists()){
                    realPathFile.mkdir();
                }

//               ===========================文件传输==========================================
//                获得文件上传的流
                InputStream inputStream = fileItem.getInputStream();
//                创建一个文件输出流
                FileOutputStream fos = new FileOutputStream(readPath+"/"+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 = "文件上传成功";
        }
        req.setAttribute("msg", msg);
        req.getRequestDispatcher("info.jsp").forward(req, resp);
    }

3.4 doPost()

   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        判断上传的文件是普通表单还是带文件的表单
        String msg = "文件上传失败";
        if(!ServletFileUpload.isMultipartContent(req)){
            return;
        }

//        创建上传文件的保存路径,建议放在web-inf路径下以保证安全,用户无法直接访问上传的文件
        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/tmp");
        File tmpFile = new File(tmpPath);
        if(!tmpFile.exists()){
            tmpFile.mkdir();
        }

//        处理上传的文件,一般需要通过流来获取
//        此处使用apache的组件来实现  commons-io

        /*
        * ServletFileUpload负责处理上传的文件数据,并将表单中的每个输入项封装成fileItem对象
        * 在使用ServletFileUpload对象解析请求时需要DIskFileItemFactory对象
        * 所有,需要在进行解析工作前构造好DiskFileItemFactory对象*/

//       1. 创建DiskFileIntemFactory对象,处理文件上传路径或者大小限制
        DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);

//      2。获取ServletFileUpload
        ServletFileUpload upload = getServletFileUpload(factory);

//        3.处理上传文件
        uploadFile(req, resp,upload, uploadPath);
    }

补充:通过表单上传文件,get方法对上传文件的大小有限制,post方法没有限制,所以一般使用post方法。而且使用get方法的话在获取ServletFileUpload时会出错。另外,表单如果包含一个文件上传输入的话,这个表单的enctype属性就必须设置为multipart/form-data。

4.运行结果

通过表单提交了文件后,可以在tomcat目录下找到项目文件夹,在WEB-INF目录下就多出了upload和temp这两个文件夹,上传的文件都保存在这两个文件夹下面。

 

标签:文件,String,upload,表单,ServletFileUpload,上传,javaweb
来源: https://blog.csdn.net/qq_43667170/article/details/123099192

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有