JavaWeb文件上传

9 篇文章 0 订阅
6 篇文章 0 订阅

JavaWeb处理文件上传

1.简述

在一个项目中,文件上传功能是十分常见的,经常要使用到,像最平常的就有设置账号头像。但是要完成这一功能,要解决哪些问题呢?怎样才可以实现这一功能呢?下面我就用一个具体示例来详细讲解一下吧~

2.文件上传分析

  1. 前端分析:普通表单提交默认 enctype =“application/x-www-form-urlencoded”,而要上传文件类型的表单需要设置enctype=“multipart/form-data”(它不对字符进行编码,用于发送二进制的文件),所以后端接收时不能再使用request.getParameter(),而是用request.getInputStream()解析二进制流,得到ServletInputStream对象。另外,表单提交方式必须为post
  2. 后端分析:首先,要判断表单类型是否符合文件类型表单;其次,要创建上传的文件的存取路径;最后,就是使用fileUpload组件,实现文件上传。

3.示例讲解

说明:本次的示例用到的环境是maven+tomcat 9,tomcat 9以上的tomcat版本不适用,因为和fileUpload组件还不兼容。(这是因为fileUpload组件的ServletFileUpload包到了tomcat 10之后就找不到了,还没有更新修改)

3.1、导包

使用fileUpload组件需要引入两个jar包:

  • commons-fileUpload.jar
  • commons-io.jar

3.2、前端代码

测试页面index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>uploadFile test</title>
</head>
<body>

<form method="post" action="/upload.do" enctype="multipart/form-data">
    上传用户:<input type="text" name="username"><br>
    <p><input type="file" name="file1"></p>
    <p><input type="file" name="file2"></p>
    <p><input type="submit">|<input type="reset"></p>
</form>

</body>
</html>

测试结果页面message.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传</title>
</head>
<body>

<h1 align="center">${msg}</h1> <!--msg后端返回-->

</body>
</html>

3.3、后端代码

里面有很多拓展的功能代码块,标志着(可选)的代码可自行删去,看起来代码量就少了

总结下来就点:

  1. 判断上传的文件是普通表单还是带文件的表单
  2. 创新上传的文件保存的路径
  3. 设置缓存
  4. 处理上传的文件(重点掌握
  5. 请求转发结果消息
public class FileServlet 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 {

        //1.判断上传的文件是普通表单还是带文件的表单
        if (!ServletFileUpload.isMultipartContent(req)) {
            return;//这是一个普通表单,直接返回终止方法运行
        }

        //2.创新上传的文件保存的路径 保存在WEB-INF路径下(因为安全,用户是无法直接访问到这个目录下的文件的)
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()) {
            uploadFile.mkdir();//如果这个文件目录不存在,则创建它
        }

        //3.设置缓存,存放临时文件(即文件超过预期大小的话,则放在临时文件下,过几天会自动删除,或者提醒用户转为永久文件)
        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        File tempFile = new File(tempPath);
        if (!tempFile.exists()) {
            uploadFile.mkdir();
        }

        //4.处理上传的文件  使用现有的Apache的文件上传组件(commons-fileupload 依赖)来实现
        //4.1 创建DiskFileItemFactory对象 (处理文件上传路径或者大小限制)
        DiskFileItemFactory factory = getDiskFileItemFactory(tempFile);
        //4.2 工厂得到ServletFileUpload文件上传类
        ServletFileUpload upload = new ServletFileUpload(factory);
        //4.3 处理上传的文件
        String msg = uploadParseRequest(upload,req,uploadPath);

        //5.请求转发消息,返回运行结果
        req.setAttribute("msg",msg);
        req.getRequestDispatcher("/message.jsp").forward(req,resp);
    }

    //获得经过自己的一些要求处理后的DiskFileItemFactory对象 factory
    public static DiskFileItemFactory getDiskFileItemFactory(File file){
        //创建DiskFileItemFactory对象 (处理文件上传路径或者大小限制)
        DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setSizeThreshold(1024*1024);//设置缓存区大小(可选)
        factory.setRepository(file);//这个是为缓存区大小设置一个仓库 即目录文件(可选)
        return factory;
    }

    //处理上传的文件,返回一个处理结果字符穿
    public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest req,String uploadPath){
        String msg = "";
        //1. 监听文件文件上传进度(可选)
        upload.setProgressListener(new ProgressListener() {
            public void update(long l1, long l, int i) {
                System.out.println("已上传:"+l1+"  总大小:"+l);
            }
        });
        //2. 处理一些要上传的文件的约束(可选)
        upload.setHeaderEncoding("UTF-8");//文件编码
        upload.setFileSizeMax(1024*1024*2);//单个文件最大值
        upload.setSizeMax(1024*1024*10);//总文件大小
        //3 处理上传的文件(核心块)
        //把前端请求解析,封装成一个FileItem对象
        List<FileItem> fileItems = null;
        try {
            fileItems = upload.parseRequest(req);
            for (FileItem fileItem : fileItems) {
                //过滤掉大小不符合的文件
                if (fileItem.getSize() > upload.getFileSizeMax()){
                    msg = "文件上传失败!文件大小大于10M";
                    continue;
                }
                //判断上传表单控件的 是type=text 还是type=file
                if (fileItem.isFormField()){//type=text
                    String name = fileItem.getFieldName();//获取表单控件的名字
                    String value = fileItem.getString("UTF-8");//获取值,处理乱码
                    System.out.println(name+": "+value);
                }else {//type=file
                    String uploadFileName = fileItem.getName();//获取上传文件名字(是带有路径在的)
                    System.out.println("上传的文件名:"+uploadFileName);
                    //可能存在文件名不合法的情况
                    if (uploadFileName == null || uploadFileName.trim().equals("")){
                        msg = "文件上传失败!文件名不符合规范";
                        continue;
                    }
                    //截取上传的文件名
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/")+1);//从最后一个/后开始截取
                    //截取后缀名
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);//从最后一个.后开始截取
                    //可以使用UUID(唯一标识的通用码),保证文件名唯一
                    String uuidPath = UUID.randomUUID().toString();//生成一共随机的uuid
                    //创建存放目录
                    String realPath= uploadPath+"/"+uuidPath;
                    //给每个文件创建一个对应的文件夹
                    File realFile = new File(realPath);
                    if (!realFile.exists()){
                        realFile.mkdirs();
                    }
                    //文件传输,写入磁盘
                    fileItem.write(new File(realPath,fileName + "." + fileExtName));
                    msg = "文件上传成功!";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return msg;
    }
 }

**注意:**不要忘了Servlet的注册噢~


以上就是关于文件上传的全部内容啦~内容并不多,拿上代码去自己电脑测试学习去吧,对于示例代码有报错的可以提问出来帮你解决哦!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值