Servlet、SpringMVC、SpringBoot文件上传

1 篇文章 0 订阅
1 篇文章 0 订阅

如下内容,是我在课堂做得笔记。总结出来的!!!

1、文件上传的概述

文件上传是项目开发中最常见的功能之一 。

如果要使用文件上传,必须要有如下东西:

  • 要有一个form标签,method=post请求;
  • form标签的encType属性值必须为multipart/form-data值;
  • form标签中使用<input type=file />添加上传的文件;

2、文件上传,HTTP 协议的说明

在这里插入图片描述
Content-Type: multipart/form-data; boundary=----XXXXXX

  • Content-Type:表示提交的数据类型
  • multipart/form-data:表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器
  • boundary:表示每段数据的分隔符,----XXXXXX是由浏览器每次都随机生成。它就是每段数据的分界符。

3、文件上传的使用

文件上传可以在servlet、SpringMVC、SpringBoot中使用。

使用之前先导入两个 jar 包

或者Maven依赖

<!--引入commons-fileUpload-->
<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.3.2</version>
</dependency>

3.1 在 servlet 中使用文件上传

在commons-fileupload.jar 和 commons-io.jar 包中,我们涉及到的API有哪些?

ServletFileUpload类,用于解析上传的数据

FileItem类,表示每一个表单项

  • boolean ServletFileUpload.isMultipartContent(HttpServletRequest request):判断当前上传的数据格式是否是多段的格式。
  • publicList<FileItem>parseRequest(HttpServletRequestrequest):解析上传的数据
  • boolean FileItem.isFormField():判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。
    • true 表示普通类型的表单项
    • false 表示上传的文件类型
  • String FileItem.getFieldName():获取表单项的 name 属性值
  • String FileItem.getString():获取当前表单项的值。
  • String FileItem.getName():获取上传的文件名
  • void FileItem.write( file ):将上传的文件写到 参数 file 所指向抽硬盘位置 。

前端页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传</title>
</head>
<body>
    <form action="uploadServlet" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="username">
        <br><br>
        头像:<input type="file" name="photo">
        <input type="submit" value="上传">
    </form>
</body>
</html>

后端代码

import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.*;
import java.util.List;

public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        // 1 先判断上传的数据是否多段数据(只有多段的数据,才是文件上传的)
        if (ServletFileUpload.isMultipartContent(req)) {
            // 创建FileItemFactory工厂实现类
            FileItemFactory itemFactory = new DiskFileItemFactory();
            // 创建用于解析上传数据的工具类ServletFileUpload类
            ServletFileUpload upload = new ServletFileUpload(itemFactory);
            try {
                // 解析上传的数据,得到每一个表单项FileItem
                List<FileItem> list = upload.parseRequest(req);
                // 循环判断,每一个表单项,是普通类型,还是上传的文件
                for (FileItem fileItem : list) {
                    if (fileItem.isFormField()) {
                        // 普通类型的表单项
                        String name = fileItem.getFieldName();
                        System.out.println("表单项的name属性值:" + name);
                        String value = fileItem.getString("utf-8");
                        System.out.println("表单项的value属性值:" + value);
                    } else {
                        // 上传的文件
                        System.out.println("表单项的name属性值:" + fileItem.getFieldName());
                        // 上传的文件名
                        String fileName = fileItem.getName();
                        System.out.println(fileName);
                        fileItem.write(new File("D:\\IO\\文件上传\\" + fileName));
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

3.2 在 SpringMVC 中使用文件上传

Spring MVC 为文件上传提供了直接的支持,这种支持是通过即插即用的MultipartResolver实现的。Spring 用Jakarta Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResovler

Spring MVC 上下文中默认没有装配MultipartResovler,因此默认情况下不能处理文件的上传工作,如果想使用Spring 的文件上传功能,需现在上下文中配置MultipartResolver

3.2.1 MultipartFile的常用API
方法名描述
String getName()在多形式返回参数的名称。
String getOriginalFilename()返回原来的文件名在客户端的文件系统。
String getContentType()返回的内容类型的文件。
boolean isEmpty()返回是否上传的文件是空的,也就是说,要么没有文件已在多形式被选定或所选择的文件中没有的内容。
long getSize()返回以字节为单位的文件的大小。
byte[] getBytes()返回该文件的内容作为字节数组。
InputStream getInputStream()返回的InputStream来读取文件的内容。 用户负责关闭该流。
void transferTo(File dest)接收到的文件转移到给定的目标文件。
3.2.2 使用单文件上传,代码如下:

在 spring-mvc.xml 里配置MultipartResolver

<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
      id="multipartResolver">
    <property name="defaultEncoding" value="utf-8"/>
    <!--  defaultEncoding: 必须和用户 JSP 的 pageEncoding 属性一致,以便正确解析表单的内容 -->
    <property name="maxUploadSize" value="1024000"/>
</bean>

FileUploadController.java

import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile;

import java.io.*
import java.util.*;

@Controller
public class FileUploadController {
    /**
     * 跳转页面
     */
    private final String SUCCESS = "success";
    /**
     * 上传文件最大范围
     */
    private final int MAXIMUM_FILE_RANGE = 30000;
    /**
     * 保存的路径
     */
    private final String UPLOAD_DIRECTORY = "D:\\IO";

        @RequestMapping("/singleFileUpload")
    public String singleFileUpload(Map<String, Object> map,
                                   @RequestParam("file") MultipartFile file,
                                   @RequestParam("desc") String desc) {
        // 判断文件是否为空
        if (!file.isEmpty()) {
            try {
                System.out.println(desc);
                // 判断文件目录是否存在,否则自动生成
                File directory = new File(UPLOAD_DIRECTORY);
                // 判断文件或目录是否存在
                if (!directory.exists()) {
                    // 创建一个子目录
                    directory.mkdirs();
                }
                // 文件保存路径
                String filePath = FilenameUtils.concat(UPLOAD_DIRECTORY, file.getOriginalFilename());
                System.out.println(filePath);
                // 转存文件
                file.transferTo(new File(filePath));
                map.put("msg", file.getOriginalFilename());
                map.put("date", new SimpleDateFormat("yyyy-MM-dd EEE HH:mm:ss").format(new Date()));
                System.out.println(map.get("msg"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return SUCCESS;
    }
}

upload.jsp

<h2>单文件上传</h2>
<form action="singleFileUpload" method="post" enctype="multipart/form-data">
    <p> 选择文件:<input type="file" name="file">
    <p> Desc:<input type="text" name="desc"/>
        <input type="submit" value="提交">
</form>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传响应页面</title>
</head>
<body>
<h1>文件${msg}上传成功!</h1>
<h2>上传时间为:${date}</h2>
</body>
</html>

运行结果

页面展示:

在这里插入图片描述
文件上传成功:

在这里插入图片描述

3.2.3 使用多文件上传,代码如下:

在FileUploadController.java里添加以下代码

@RequestMapping("/multipleFileUpload")
public String multipleFileUpload(@RequestParam("files") MultipartFile[] files,
                                 Map<String, Object> map) {
    // 判断file数组不能为空并且长度大于0
    if (files != null && files.length > 0) {
        StringBuilder builder = new StringBuilder();
        //循环获取file数组中得文件
        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];
            //失败跳转视图
            if (file.getSize() > MAXIMUM_FILE_RANGE) {
                map.put("msg", file.getOriginalFilename() + "超过了指定大小");
                map.put("flag", "失败");
            }
            //保存文件
            String filePath = FilenameUtils.concat(UPLOAD_DIRECTORY, file.getOriginalFilename());
            try {
                // 转存文件
                file.transferTo(new File(filePath));
                builder.append(file.getOriginalFilename() + "、");
            } catch (IOException e) {
                e.printStackTrace();
            }
            map.put("msg", Arrays.asList(builder));
            map.put("date", new SimpleDateFormat("yyyy-MM-dd EEE HH:mm:ss").format(new Date()));
        }
    }
    return SUCCESS;
}

在upload.jsp里添加以下代码

<h2>多文件上传</h2>
<form action="multipleFileUpload" method="post" enctype="multipart/form-data">
    <p> 选择文件:<input type="file" name="files">
    <p> 选择文件:<input type="file" name="files">
    <p> 选择文件:<input type="file" name="files">
        <input type="submit" value="提交">
</form>

运行结果

页面展示:

在这里插入图片描述
多文件上传成功:

在这里插入图片描述

说明:
前端表单,多个文件组使用同一个 name 名称:files,后台控制器使用@RequestParam("files") MultipartFile[] files数组来接收。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值