文件上传基础实现

文件上传

在这里插入图片描述

  • web-inf目录下的文件不能从外界直接访问需要重定向和转发过去访问,限制某用户上传的文件只能在某用户账号下访问。
  • 文件名不能重复-时间戳+UUID+MD5+位运算(加解密)
  • 支持文件的传输必须在form中设置 enctype=“multipart/form-data”
  • ARP地址解析协议:交换机将本区域的请求作为节点进行分发,请求认为是外部网络
  • 普通项目可以创建module工程,在工程里可以创建servlet等类
    在这里插入图片描述
    在这里插入图片描述

网络传输的东西,都需要序列化

pojo,实体类,想在多个电脑上运行,需要传输将对象序列化

JNI =java native interface

implements java.io.Serializable:标记接口jvm识别后会做些事务,java–>java栈,本地方法栈 jvm–>c++>OS

实现步骤:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //判断上传文件时普通表单还是文件表单
    if (!ServletFileUpload.isMultipartContent(req)) { //true为文件表单,false为普通表单
        return; //终止访问运行,从栈中弹出。
    }
    //创建上传文件的保存路径,在web-inf路径下,安全,用户无法直接访问上传的文件
    String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
    File uploadFiles = new File(uploadPath);
    if (!uploadFiles.exists()) {
        uploadFiles.mkdirs(); //创建这个目录
    }
    //缓存,临时文件
    //若上传文件大小超过预期,则放到这个临时文件中,几天后自动删除或转为永久
    String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
    File tmpFiles = new File(tmpPath);
    if (!tmpFiles.exists()) {
        tmpFiles.mkdirs(); //创建这个目录
    }

    //处理上传文件,通过流来获取,可以使用req.getInputStream();原生态的文件上传流获取,需要解析,比较麻烦
    //用apache的文件上传组件commons-fileupload-1.4.jar来实现,依赖于commons-fileupload-1.4.jar包
    try {
        //创建DiskFileItemFactory对象,处理文件上传路径和大小限制
        DiskFileItemFactory diskFileItemFactory = getDiskFileItemFactory(tmpFiles);
        //创建ServletFileUpload对象,需要DiskFileItemFactory对象
        ServletFileUpload upload = getServletFileUpload(diskFileItemFactory);
        //处理上传文件
        String msg = uploadParseRequest(upload, req, uploadPath);
        //请求转发出去
        req.setAttribute("msg",msg);
        req.getRequestDispatcher("info.jsp").forward(req,resp);
    } catch (FileUploadException e) {
        e.printStackTrace();
    }
}
  • 需要DiskFileItemFactory、ServletFileUpload等对象
//创建DiskFileItemFactory对象,处理文件上传路径和大小限制
public static DiskFileItemFactory getDiskFileItemFactory(File tmpFiles){
    DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
    //以下可以不设置,有默认值
    //设置DiskFileItemFactory对象文件上传路径为临时路径
    diskFileItemFactory.setRepository(tmpFiles);
    //设置DiskFileItemFactory对象缓冲区大小限制为1M
    diskFileItemFactory.setSizeThreshold(1024 * 1024);
    return diskFileItemFactory;
}
public static ServletFileUpload getServletFileUpload(DiskFileItemFactory diskFileItemFactory){
    //创建ServletFileUpload对象,需要DiskFileItemFactory对象
    ServletFileUpload upload = new ServletFileUpload(diskFileItemFactory);
    //以下可以不设置,有默认值
    //监听文件上传进度
    upload.setProgressListener(new ProgressListener() {
        //pContentLength预期文件字节大小
        //pBytesRead已经读取的文件字节大小
        @Override
        public void update(long pBytesRead, long pContentLength, int pItems) {
            System.out.println("总文件大小为:" + pContentLength + "。已经传输了" + pBytesRead);
        }
    });
    //设置文件编码
    upload.setHeaderEncoding("utf-8");
    //设置单个文件的最大值
    upload.setFileSizeMax(1024 * 1024 * 100);
    //设置总共能上传文件的大小
    upload.setSizeMax(1024 * 1024 * 100);
    return upload;
}
  • 利用ServletFileUpload对请求进行解析为 类型为FileItem的List集合,对其进行遍历,若是文件类型则利用创建好的路径(唯一文件名)用输入输出流进行传输保存
public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest req,String uploadPath) throws FileUploadException, IOException {
    //把前端请求解析封装为一个个FileItems对象,需要ServletFileUpload来解析
    List<FileItem> fileItems = upload.parseRequest(req);
    String msg = "文件上传失败";
    //遍历这个fileItems对象
    for (FileItem fileItem : fileItems) {
        //判断上传的文件值普通文本框还是文件
        if (fileItem.isFormField()) {
            //getFieldName前端控件的name属性
            String name = fileItem.getFieldName();
            try {
                //name属性对应额value值,并处理乱码
                String value = fileItem.getString("utf-8");
                System.out.println("name:" + name + ",value=" + value);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else {
            //处理文件
            String itemName = fileItem.getName();
            System.out.println("itemname=" + itemName);
            //可能存在文件名不合法的情况
            if (itemName.trim().equals("") || itemName == null) {
                continue;
            }
            //获得上传的文件名  /xx/aa.png
            String filename = itemName.substring(itemName.lastIndexOf("/") + 1);
            //获得上传的文件的后缀名
            String fileextname = itemName.substring(itemName.lastIndexOf(".") + 1);
                /*若fileextname不符合要求直接return;
                告诉用户文件类型不合要求*/
            System.out.println("文件信息:filename=" + filename + "文件后缀名" + fileextname);
            //上传文件夹的唯一识别名
            //uuid与时间戳,硬件的信息有关,所以不可能相同
            String uuid = UUID.randomUUID().toString();
            //存放地址uploadPath
            //文件真实存放位置realPath
            String realPath = uploadPath + "/" + uuid;
            //给每个文件创建一个文件夹
            File realFile = new File(realPath);
            if (!realFile.exists()) {
                realFile.mkdirs();
            }
            //文件传输
            InputStream is = null;
            FileOutputStream fos = null;
            //获得文件上传的输入流
            is = fileItem.getInputStream();
            //创建文件输出流
            //realPath是真实的文件夹
            //差了一个文件及输出的文件夹+"/"+文件名
            fos = new FileOutputStream(realPath + "/" + itemName);
            //创建一个缓存区
            byte[] bytes = new byte[1024 * 1024];
            //判断是否读取完毕
            int len = 0;
            //若不等于-1则还有数据
            while ((len = is.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }
            msg = "文件上传成功!";
            //关闭流资源
            is.close();
            fos.close();
            //清除临时文件
            fileItem.delete();
        }
    }
    return msg;
}
  • fileUpload.jsp上传页面设置让浏览器支持文件上传的控件和设置表单提交类型。
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>功能界面</title>
</head>
<body>
<%--
上传图片只能用post,get请求有大小限制4kb

--%>

<form action="${pageContext.request.contextPath}/upload.do" 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" name="submit" value="提交">|
    <input type="reset" name="reset" value="重置">
</form>
</body>
</html>
  • 结果页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>结果显示</title>
</head>
<body>

文件上传结果:${msg}
</body>
</html>
  • 注意文件上传的目录设置。

web-inf目录下的文件不能从外界直接访问需要重定向和转发过去访问,限制某用户上传的文件只能在某用户账号下访问。

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值