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);
    }
}
相关推荐
若鱼19191 小时前
SpringBoot4.0新特性-Observability让生产环境更易于观测
java·spring
跳动的梦想家h1 小时前
环境配置 + AI 提效双管齐下
java·vue.js·spring
独断万古他化2 小时前
【Spring 原理】Bean 的作用域与生命周期
java·后端·spring
vx1_Biye_Design3 小时前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
Hx_Ma163 小时前
SpringBoot数据源自动管理
java·spring boot·spring
java1234_小锋4 小时前
Java高频面试题:Spring和SpringBoot的关系和区别?
java·spring boot·spring
梵得儿SHI4 小时前
(第十篇)Spring AI 核心技术攻坚全梳理:企业级能力矩阵 + 四大技术栈攻坚 + 性能优化 Checklist + 实战项目预告
java·人工智能·spring·rag·企业级ai应用·springai技术体系·多模态和安全防护
逍遥德5 小时前
Sring事务详解之02.如何使用编程式事务?
java·服务器·数据库·后端·sql·spring
老毛肚13 小时前
MyBatis插件原理及Spring集成
java·spring·mybatis
shuair21 小时前
redis缓存预热、缓存击穿、缓存穿透、缓存雪崩
redis·spring·缓存