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);
    }
}
相关推荐
BUG指挥官1 小时前
Sa-Token和Spring Security对比
java·后端·spring
geminigoth1 小时前
Spring AI Alibaba 入门开发一(备份)
java·人工智能·spring
xbgRS4 小时前
spring整合mybaits
java·spring·mybatis
ruleslol4 小时前
静态依赖注入 VS 动态依赖查询
spring
墨雨晨曦887 小时前
Spring AI总结
java·人工智能·spring
用户3126874877209 小时前
Spring Boot 异常处理到底怎么玩的?从 DispatcherServlet 到全局兜底的全链路拆解
spring
不才不才不不才9 小时前
Spring 源码系列(17): HandlerMapping 与 HandlerAdapter 两大体系
java·后端·spring
(轻舟已过万重山)10 小时前
第40章 Spring AI 实战:企业级 AI 应用架构
人工智能·spring·架构
he___H1 天前
SpringMVC与异常
springmvc
堕落年代1 天前
Ollama CPU 推理大提示词优化实测报告(细致化数据版)
java·后端·spring