Web 基础26 文件上传概述及其入门案例

1.1 文件上传概述

  • 文件上传
    • 用户将本地文件通过网络上传至服务器的过程
  • 应用场景
    • 相亲网站的照片上传
    • 招聘网站的简历上传
  • 文件上传的技术
名称 描述
jspSmartUpload 应用在jsp上的文件上传和文件下载的组件
fileupload 应用在java上的文件上传技术,由Apache开源组织提供
servlet3.0 提供了文件上传的技术
Struts 提供了文件上传的技术
  • 文件上传的条件
    • 需要有一个表单
    • 表单的method属性的值必须设置为post
    • 表单的enctype属性的值需要设置为multipart/form-data
    • 表单需要有一个input标签
      • input标签type属性的值需要设置为file
      • input标签需要有name属性和值

1.2 JSP编写

  • 一些属性的注释
    • enctype:encode type 编码类型:属性规定了发送服务器之前如何对表单数据进行编码
    • application/x-www-form-urlencoded %WE%RT 默认对表单数据进行url编码,不能用于文件上传
    • multipart/form-data:表单数据有多个部分组成:既有文本数据,还有文件,图片这些二进制数据设置之后,浏览器会将文件以二进制的方式上传,可以实现多种类型的文
      件上传
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>文件上传</h1>
    
    <form action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data">
        文件信息:<input type="text" name="info"/>
        <br />
        用户名:<input type="text" name="username"/>
        <br />
        文件:<input type="file" name="file01" />
        <br />
        文件2:<input type="file" name="file02" />
        <br />
        <input type="submit" value="上传"/>
    </form>
</body>
</html>

1.3 Servlet的编写

  • 编写流程
    • 创建一个磁盘文件的工厂对象
    • 创建文件上传的核心对象
    • 通过核心对象解析请求对象得到一个集合对象,他里面包含所有的表单项对象
    • 遍历这个集合对象,得到每一个表单项,判断他是否是普通表单项
    • 如果是普通的表单项,获取他的name和value的值
    • 如果不是,创建IO流传输
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取表单所提交的数据
        //创建磁盘文件的工厂对象
        DiskFileItemFactory dfif = new DiskFileItemFactory();
        //创建文件上传的核心对象
        ServletFileUpload upload = new ServletFileUpload(dfif);
        //解析请求对象,获取表单所提交的数据
        List<FileItem> items = null;
        try {
            items = upload.parseRequest(request);
        } catch (FileUploadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        //遍历集合对象
        if(items != null) {
            for (FileItem fileItem : items) {
                //判断表单项是否是普通的表单项
                if(fileItem.isFormField()) {
                    //确定是普通的表单项
                    //获取普通表单项name属性的值
                    String fieldName = fileItem.getFieldName();
                    //获取普通表单项value属性的值
                    String fieldValue = fileItem.getString("UTF-8");
                    System.out.println(fieldName + "=" + fieldValue);
                }
                else {
                    //文件上传的表单项
                    //获取文件名称
                    String fileName = fileItem.getName();
                    //获取文件的内容
                    InputStream is = fileItem.getInputStream();
                    /*byte[] bys = new byte[1024];
                    int len = 0;
                    while((len = is.read(bys)) != -1) {
                        System.out.println(new String(bys,0,len));
                    }*/
                    
                    String realPath = getServletContext().getRealPath("/file");
                    File file = new File(realPath);
                    if(!file.exists()) {
                        //目录不存在,则要创建
                        file.mkdirs();
                    }
                    //创建输出流对象
                    OutputStream os = new FileOutputStream(realPath + "/" + fileName);
                    byte[] bys = new byte[1024];
                    int len = 0;
                    while((len = is.read(bys)) != -1) {
                        os.write(bys, 0, len);
                    }
                    
                    os.close();
                    
                }
        
            }
        }
    }

1.4 DiskFileItemFactory的常用API

方法 描述
void setSizeThreshold(int sizeThreshold) 设置缓冲区大小
void setRepository(java.io.File repository) 设置临时目录
DiskFileItemFactory dfif = new DiskFileItemFactory();
// 设置缓冲区大小
dfif.setSizeThreshold(1024 * 1024 * 6);// 6M
// 设置临时目录
String tempPath = getServletContext().getRealPath("/temp");
File temp = new File(tempPath);
if (!temp.exists()) {
    temp.mkdirs();
}

dfif.setRepository(temp);

  • 注意:
    • 如果上传的文件不是很大,先走缓冲区
    • 如果上传文件比较大,超过缓冲区的大小,就不走缓冲区了,他会把文件先上传到临时目录中,再把临时目录中的临时文件复制到file目录中
    • 需要把整个文件上传工作完成之后才把临时文件复制到我们指定的File目录中
    • 需要先把Tomcat关掉才能手动删掉temp里面的文件
    • 临时文件临时目录的作用 是做一些续传的操作

1.5 ServletFileUpload的常用API

方法 描述
static boolean isMultipartContent(javax.servlet.http.HttpServletRequest request) 用来判断表单 link-tap的属性值是否是mutipart 是返回ture 否则返回 false
public void setFileSizeMax(long fileSizeMax) 设置一个请求中单个文件的大小
public void setSizeMax(long sizeMax) 设置一个请求中所有文件的总大小
boolean flag = ServletFileUpload.isMultipartContent(request);
if (!flag) {
    request.setAttribute("msg", "表单提交数据的方式错误!");
    request.getRequestDispatcher("/upload.jsp").forward(request,
            response);
    return;
}

ServletFileUpload upload = new ServletFileUpload(dfif);
// 设置文件的大小
upload.setFileSizeMax(1024 * 1024 * 40);//40M
// 设置请求中所有文件的总大小
upload.setSizeMax(1024 * 1024 * 40);//40M
  • 注意:
    • 工厂对象既可以通过构造方法传递,也可以通过他所对应的set方法传递

1.7 FileItem的常用API

方法 描述
long getSize() 获取表单上传文件的大小
void delete() 删除临时文件
void write(java.io.File file) 直接写一个文件

1.8 上传Servlet 改写

protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
            // 判断表单提交数据的方式是否正确
            boolean flag = ServletFileUpload.isMultipartContent(request);
            if (!flag) {
                request.setAttribute("msg", "表单提交数据的方式错误!");
                request.getRequestDispatcher("/upload.jsp").forward(request,
                        response);
                return;
            }
    
            // 实现文件上传的功能
            DiskFileItemFactory dfif = new DiskFileItemFactory();
            // 设置缓冲区大小
            dfif.setSizeThreshold(1024 * 1024 * 6);// 6M
            // 设置临时目录
            String tempPath = getServletContext().getRealPath("/temp");
            File temp = new File(tempPath);
            if (!temp.exists()) {
                temp.mkdirs();
            }
    
            dfif.setRepository(temp);
    
            ServletFileUpload upload = new ServletFileUpload(dfif);
            // 设置文件的大小
            // upload.setFileSizeMax(1024 * 1024 * 40);//40M
            // 设置请求中所有文件的总大小
            // upload.setSizeMax(1024 * 1024 * 40);//40M
            List<FileItem> items = null;
            try {
                items = upload.parseRequest(request);
            } catch (FileUploadException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (items != null) {
                for (FileItem fileItem : items) {
                    if (fileItem.isFormField()) {
                        String fieldName = fileItem.getFieldName();
                        String fieldValue = fileItem.getString("UTF-8");
                        System.out.println(fieldName + "=" + fieldValue);
                    } else {
                        //获取表单上传文件的大小
                        long size = fileItem.getSize();
                        if(size > 0) {
                            String fileName = fileItem.getName();
                            /*InputStream is = fileItem.getInputStream();
                            String realPath = getServletContext().getRealPath("/file");
                            File file = new File(realPath);
                            if (!file.exists()) {
                                file.mkdirs();
                            }
        
                            OutputStream os = new FileOutputStream(realPath + "/" + fileName);
                            byte[] bys = new byte[1024];
                            int len = 0;
                            while ((len = is.read(bys)) != -1) {
                                os.write(bys, 0, len);
                            }
                            //关闭输入流,删除临时文件需要
                            is.close();
                            os.close();*/
                            String realPath = getServletContext().getRealPath("/file");
                            File file = new File(realPath);
                            if (!file.exists()) {
                                file.mkdirs();
                            }
                            //File uploadFile = new File(file,fileName);
                            try {
                                fileItem.write(new File(file,fileName));
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
        
                        }
                    }
                    //删除临时文件
                    fileItem.delete();
                }
    
            }

    }



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342