SpringMVC之 文件上传和下载

1. 文件上传

1.1 前端注意事项

文件上传操作,前端的表单项需要如下三项设置:

(1)input标签的type属性应设置为file,并且注意不要在input标签中设置value属性,因为这可能导致文件上传不成功;

(2)请求方式为 method="post" ;

(3)enctype="multipart/form-data"。

1.2 后端注意事项

文件上传操作,后端需要注意:

(1)可以在项目的配置文件 application.properties或application.yml中设置文件大小限制,以避免上传过大的文件导致服务器资源耗尽,例如:

(2)后端需要写一个处理上传文件的处理器,把接收到的文件保存到服务器指定目录下等其他操作。

1.3 前后端完整示例程序

1.3.1 前端

html 复制代码
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>文件上传和下载</title>
</head>
<body>
<form action="/file/upload" method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="username"/><br/>
    头 像 :<input type="file" name="headerImg" /><br/>
    生活照:<input type="file" name="lifeImages" multiple></br>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

1.3.2 后端

html 复制代码
package com.shg.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Paths;

@Controller
public class PageTestController {
    
    @RequestMapping(value = "/file/upload", method = RequestMethod.POST)
    @ResponseBody
    public String fileUpload(@RequestParam(value = "headerImg") MultipartFile file,
                             @RequestParam(value = "lifeImages") MultipartFile[] lifeImages,
                             @RequestParam(value = "username") String userName) throws IOException {
        System.out.println("用户名:" + userName);
        System.out.println("头像 - 文件名称:" + file.getOriginalFilename());
        file.transferTo(Paths.get("D:\\tempPic\\" + file.getOriginalFilename()));

        for (MultipartFile lifeImage : lifeImages) {
            System.out.println("生活照 - 文件名称:" + lifeImage.getOriginalFilename());
            lifeImage.transferTo(Paths.get("D:\\tempPic\\" + file.getOriginalFilename()));
        }
        return "success";
    }
}

2. 文件下载

文件下载的写法比较固定,代码如下:

java 复制代码
package com.shg.springmvc.controller;

import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@RestController
public class ResponseTestController {


    /**
     * 问题一:如果文件名称中包含中文,那么浏览器会乱码
     * 问题二:如果下载的文件比较大,会oom(内存溢出)
     *
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public ResponseEntity<InputStreamResource> response_02() throws IOException {

        // 获取要下载的文件流
        String filePath = "D:\\tempPic\\生活照3.jpg";
        File file = new File(filePath);
        FileInputStream fileInputStream = new FileInputStream(file);

        // 解决问题一:使用URLEncoder.encode()方法对文件名称进行编码
        String fileName = URLEncoder.encode("你好啊.jpg", StandardCharsets.UTF_8);

        // 解决问题二:为了避免一次性读取文件过大,导致内存溢出,可以使用 InputStreamResource 来读取文件(将文件流包装成Resource对象)
        InputStreamResource inputStreamResource = new InputStreamResource(fileInputStream);

        return ResponseEntity.ok()
                // 设置响应头,告诉浏览器如何处理
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName)
                // 下载文件的大小
                .contentLength(file.length())
                // 内容类型:流
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                // 响应体
                .body(inputStreamResource);
    }
}
相关推荐
代码探秘者2 小时前
【算法】吃透18种Java 算法快速读写模板
数据结构·数据库·python·算法·spring
空空潍2 小时前
Spring AI 实战系列(三):多模型共存+双版本流式输出
java·人工智能·spring
pupudawang2 小时前
Spring EL 表达式的简单介绍和使用
java·后端·spring
jiankeljx2 小时前
Spring Initializr创建springboot项目,提示java 错误 无效的源发行版:16
java·spring boot·spring
skiy2 小时前
springboot+全局异常处理
java·spring boot·spring
心勤则明3 小时前
使用SpringAIAlibaba给上下文“瘦身”
java·人工智能·spring
YMWM_3 小时前
python3中的装饰器介绍及其应用场景
java·后端·spring
大阿明3 小时前
Spring.factories
java·数据库·spring
菜鸟程序员专写BUG3 小时前
SpringBoot 事务失效报错全集|rollback不生效/事务不回滚/传播机制踩坑全解决
java·spring boot·spring
空空潍4 小时前
Spring AI 实战系列(四):Prompt工程深度实战
java·人工智能·spring·prompt