Java使用FileUpload实现文件的上传

一、文件上传的介绍

1.文件上传的实质:文件的拷贝

文件上传:从本地将文件拷贝到服务器磁盘上

  • 客户端:需要编写文件上传表单
  • 服务端:需要编写代码接收上传的文件

二、客户端编码

1.文件上传三要素

  • 表单的提交方式:post(get方式提交数据有大小限制)
  • 表达的enctype属性值:必须设置为 multipart/form-data
    multipart/form-data:多部件文件上传,指表单数据有多部分构成。 既可以有文本数据,也可以有文件等二进制数据。
  • 表单中必须有文件上传项:file,必须有name属性和值

注意:默认情况下,表单的enctype的值是application/x-www-form-urlencoded,不能用于文件上传,只有使用了multipart/form-data,才能完整的传递文件数据

2.代码实例

<%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2021/9/14
  Time: 15:20
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>浏览器文件上传</title>
</head>
<body>
<%--
    客户端实现文件上传的三要素
        1.请求方式是post,因为get方式对文本内容长度有限制
        2.enctype属性的值必须是multipart/form-data
            multipart/form-data是多部件文件上传,指表单中可以有多个部分组成,
            既可以有文本数据,也可以有文件等二进制数据
        3.表单中的表单项必须有文件上传项:file,必须有name属性和值

--%>
<form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/upload">
    <input type="file" name="upload"><br>
    <input type="text" name="name"><br>
    <input type="text" name="password"><br>
    <input type="submit" value="文件上传">
</form>
</body>
</html>

三、服务器端编码

1.上传文件,抓包分析

在这里插入图片描述

2.FileUpload工具类

(1)导入依赖

FileUpload包可以很容易地将文件上传到你的Web应用程序.
IOUtils封装了Java中io的常见操作,使用十分方便 ,需要下载 commons-io-1.4.jar 包 .

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>1.4</version>
</dependency>

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.2.1</version>
</dependency>

(2)FileUpload核心类介绍

类名介绍
DiskFileItemFactory磁盘文件项工厂, 读取文件时相关的配置,比如: 缓存的大小 , 临时目录的位置
ServletFileUplaod文件上传的一个核心类
FileItem代表每一个表单项

(3)API介绍

  • ServletFileUpload
方法说明
isMultipartContent(request)判断是否是一个多部件文件上传的表单
parseRequest(request)解析request获得表单项的集合
setHeaderEncoding(“UTF-8”)设置上传的文件名的编码方式
  • FileItem
方法说明
isFormField()判断是否是普通表单项
getFieldName()获得表单的name属性值
getString()获得表单的value值
getName()获得上传文件的名称
getInputStream()获得上传文件的输入流
delete()删除临时文件

(4)服务器端文件上传编码

package cn.xuguowen.web.servlet;

import cn.xuguowen.utils.UUIDUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

/**
 * @author 徐国文
 * @create 2021-09-14 15:33
 * 服务器端要接收客户端上传的表单数据
 * 但是当前表单中有普通的表达项,也有文件表单项。
 * 解决方式:使用第三方库FileUpload工具类进行文件的上传,保存到服务器端本地磁盘中
 * 本次项目部署在我个人pc上,所以就是保存到我pc的磁盘中
 * 使用FileUpload工具类之前,要先导入jar包/依赖坐标
 */
@WebServlet("/upload")
public class FileUploadServlet extends HttpServlet {
    /**
     * 使用FileUpload工具类完成文件的上传
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        try {
            // 1.创建磁盘文件工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 2.创建文件上传类的对象
            ServletFileUpload upload = new ServletFileUpload(factory);
            // 2.1设置文件上传的编码
            upload.setHeaderEncoding("utf-8");
            // 2.2判断表单是否是多部件文件上传的表单
            boolean multipartContent = upload.isMultipartContent(req);
            System.out.println("表单是否是多部件文件上传表单" + multipartContent);
            // 2.3如果是多部件文件上传表单
            if (multipartContent) {
                // 3.开始解析请求,获取多部件文件上传表单的集合,集合中存储的是每一个表单项
                List<FileItem> list = upload.parseRequest(req);
                if (null != list) {
                    // 4.遍历多不见文件上传表单项集合
                    for (FileItem item : list) {
                        // 5.判断是普通表单项还是文件上传表单项
                        boolean formField = item.isFormField(); // 该方法判断是否是普通表单项
                        if (formField) {
                            // 普通表单项, 当 enctype="multipart/form-data"时, request的getParameter()方法 无法获取参数
                            String fieldName = item.getFieldName(); // 获取表单文本框中name的属性值
                            String value = item.getString("utf-8"); // 获取utf-8编码之后表单文本框中的内容
                            System.out.println(fieldName + " = " + value);
                        } else {
                            // 文件上传表单项
                            String fileName = item.getName();   // 获取文件名
                            // 要避免客户端上传的文件名出现重名情况,所以使用uuid工具类拼接文件名
                            fileName = UUIDUtils.getUUID() + "_" + fileName;
                            // 获取文件输入流对象
                            InputStream is = item.getInputStream();
                            // 创建文件输出流对象,将文件写出到磁盘中
                            FileOutputStream fos = new FileOutputStream("D:\\IdeaProjects\\chapter_five\\lagou_edu_home\\upload\\" + fileName);
                            // 使用工具类拷贝文件
                            IOUtils.copy(is, fos);

                            // 关闭资源
                            fos.close();
                            is.close();
                        }
                    }
                }

            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值