Java文件上传:common-fileupload上传组件

参考转载:

https://www.cnblogs.com/longqingyang/p/5579889.html

原理:

common-fileupload组件利用DiskFileItemFactory工厂方法生成request的表单内容解析器,将表单内容解析成List<FileItem>,然后循环获取处理上传文件的输入流getInputStream()。

该组件依赖commons-io组件。

步骤:

1、检查保存目录以及临时文件保存目录

2、判断提交上来的数据是否是上传表单的数据,即是否是enctype="multipart/form-data"

3、创建DiskFileItemFactory工厂

4、利用工厂创建ServletFileUpload文件上传解析器

5、使用ServletFileUpload解析器解析上传数据,解析结果返回的是List<FileItem>集合,FileItem对应Form表单的输入项

6、循环处理每一个FileItem

7、如果是普通表单输入项,获取表单字段和表单内容

8、如果是文件上传项,获取处理文件名,并getInputStream(),然后保存到保存目录中

代码:

fileupload,jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>fileupload test</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/servlet/uploadHandleServlet" method="post" enctype="multipart/form-data">
        上传用户:<input type="text" name="username"><br>
        上传文件1:<input type="file" name="file1"><br>
        上传文件2:<input type="file" name="file2"><br>
        <input type="submit" value="submit">
    </form>
</body>
</html>
uploadHandleServlet.Java
package servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
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 sun.swing.FilePane;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.List;
import java.util.UUID;

public class uploadHandleServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File saveFile = new File(savePath);
        if (!saveFile.exists() && !saveFile.isDirectory()) {
            System.out.println("目录或者文件不存在");
            saveFile.mkdir();
        }
        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        File tempFile = new File(tempPath);
        if (!tempFile.exists() && !tempFile.isDirectory()) {
            System.out.println("目录或者文件不存在");
            tempFile.mkdir();
        }
        //消息提示
        String message = "";
        try {
            //使用fileupload上传文件
            //1、判断是否为多媒体多部件上传,enctype=multipart/form-data
            if (!ServletFileUpload.isMultipartContent(request)) {
                PrintWriter writer = response.getWriter();
                writer.println("Error: 表单必须写有:enctype=multipart/form-data");
                writer.flush();
                return;
            }
            
            //2、创建一个创建一个DiskFileItemFactory工厂
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            diskFileItemFactory.setSizeThreshold(1024 * 10);//设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
            diskFileItemFactory.setRepository(tempFile);//设置上传时生成的临时文件的保存目录
            
            //3、利用工厂创建文件上传解析器
            ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
            servletFileUpload.setHeaderEncoding("UTF-8");//解决上传文件名的中文乱码
            servletFileUpload.setProgressListener(new ProgressListener() {
                @Override
                public void update(long pBytesRead, long pContentLength, int i) {
                    System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
                }
            });
            servletFileUpload.setFileSizeMax(1024 * 1024);//设置上传单个文件的大小的最大值
            servletFileUpload.setSizeMax(1024 * 1024 * 10);//设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和
            
            //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
            List<FileItem> fileItemList = servletFileUpload.parseRequest(request);
            for (FileItem item : fileItemList) {
                //如果fileitem中封装的是普通输入项的数据
                if (item.isFormField()) {
                    String name = item.getFieldName();
                    String value = item.getString("UTF-8");//解决普通输入项的数据的中文乱码问题
                    System.out.println(name + "  " + value);
                } else {
                    String fileName = item.getName();//如果fileitem中封装的是上传文件,得到上传的文件名称
                    System.out.println("文件名称:" + fileName);
                    if (fileName == null || fileName.trim().equals("")) {
                        continue;
                    }
                    fileName = fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1);//ie浏览器可能带路径
                    String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1);
                    if ("zip".equals(fileExtName) || "rar".equals(fileExtName) || "tar".equals(fileExtName) || "jar".equals(fileExtName)) {
                        request.setAttribute("message", "上传文件类型不符合");
                        request.getRequestDispatcher("/fileupload/message.jsp").forward(request, response);
                        return;
                    }
                    System.out.println("上传文件的扩展名:" + fileExtName);
                    fileName = UUID.randomUUID().toString() + "_" + fileName;
                    System.out.println("保存路径为:" + savePath);

//                    普通IO方式读取
//                    InputStream is = item.getInputStream();
//                    FileOutputStream fos=new FileOutputStream(savePath+File.separator+fileName);
//                    byte[] buffer = new byte[1024];
//                    int length=0;
//                    while ((length = is.read(buffer)) > 0) {
//                        fos.write(buffer,0,length);
//                    }

                    //NIO方式读取
                    InputStream is = item.getInputStream();
                    ReadableByteChannel readChannel = Channels.newChannel(is);
                    FileOutputStream fos = new FileOutputStream(savePath + File.separator + fileName);
                    WritableByteChannel writeChannel = Channels.newChannel(fos);
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int length = 0;
                    while ((length = readChannel.read(buffer)) > 0) {
                        buffer.flip();
                        writeChannel.write(buffer);
                        buffer.clear();
                    }

                    is.close();
                    fos.close();
                    item.delete();
                    message = "文件上传成功";
                }
            }

        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "单个文件超出最大值");
            request.getRequestDispatcher("/fileupload/message.jsp").forward(request, response);
            return;
        } catch (FileUploadBase.SizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "上传文件的总的大小超出限制的最大值!!!");
            request.getRequestDispatcher("/fileupload/message.jsp").forward(request, response);
            return;
        } catch (FileUploadException e) {
            e.printStackTrace();
            message = "文件上传失败";
        } catch (Exception e) {
            e.printStackTrace();
            message = e.getMessage();
        }
        request.setAttribute("message", message);
        request.getRequestDispatcher("/fileupload/message.jsp").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

message.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${requestScope.message}
</body>
</html>

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值