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);
    }
}
相关推荐
雨中飘荡的记忆11 小时前
Spring AI Gateway:从入门到实战,打造智能AI服务网关
人工智能·spring·gateway
a程序小傲12 小时前
得物Java面试被问:RocketMQ的消息轨迹追踪实现
java·linux·spring·面试·职场和发展·rocketmq·java-rocketmq
青春男大12 小时前
Redis和RedisTemplate快速上手
java·数据库·redis·后端·spring·缓存
风景的人生13 小时前
请求参数相关注解
spring·mvc
不吃香菜学java14 小时前
springboot左脚踩右脚螺旋升天系列-整合开发
java·spring boot·后端·spring·ssm
科威舟的代码笔记16 小时前
SpringBoot配置文件加载顺序:一场配置界的权力游戏
java·spring boot·后端·spring
血小板要健康16 小时前
Spring IoC & DI (下)
java·前端·spring boot·后端·spring·servlet·java-ee
马猴烧酒.17 小时前
【智能协图云图库|第七天】 空间模块初始化
java·数据库·后端·sql·spring·tomcat
一只程序熊17 小时前
SpringBoot class java.lang.String cannot be cast to class java.lang.Long
spring·mybatis
短剑重铸之日17 小时前
《SpringCloud实用版》 Config + Bus + Nacos 配置中心终极方案
后端·spring·spring cloud