当前位置: 首页 > news >正文

SpringMVC实现文件的上传和下载

1. 文件的下载

下面代码只需要设置服务器文件名(getRealPath("/static/img/1.jpg"))和下载到本地的文件名("attachment;filename=1.jpg")

关于ServletContext.getRealPath()

ServletContext.getRealPath("") 获取到的是项目部署到服务器后的项目根路径。

ServletContext.getRealPath("文件名或文件夹名") 获取到的是项目部署到服务器后某文件或文件夹的路径。

String photoPath1 = servletContext.getRealPath("");

F:\JavaProject\SpringMVC\springMVC-demo04\target\springMVC-demo04\

String photoPath = servletContext.getRealPath("photo");

F:\JavaProject\SpringMVC\springMVC-demo04\target\springMVC-demo04\photo

 @RequestMapping("/testDown")
    public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
        //获取ServletContext对象
        ServletContext servletContext = session.getServletContext();
        //获取服务器中文件的真实路径
        String realPath = servletContext.getRealPath("/static/img/1.jpg");
        //创建输入流
        InputStream is = new FileInputStream(realPath);
        //创建字节数组
 //is.available()获取输入流的文件全部的字节
        byte[] bytes = new byte[is.available()];
        //将流读到字节数组中
        is.read(bytes);
        //创建HttpHeaders对象设置响应头信息
        MultiValueMap<String, String> headers = new HttpHeaders();
        //设置要下载方式以及下载文件的名字
        headers.add("Content-Disposition", "attachment;filename=1.jpg");
        //设置响应状态码
        HttpStatus statusCode = HttpStatus.OK;
        //创建ResponseEntity对象
        //bytes 响应体
        //headers响应头
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
        //关闭输入流
        is.close();
        return responseEntity;
    }

2. 文件的上传

文件上传要求form表单的请求方式必须为post,并且添加属性enctype=“multipart/form-data”

SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息

<form method="post" th:action="@{/testUp}" enctype="multipart/form-data">
    <input type="file" name="photo">
    <input type="submit" value="上传">
</form>

1. 添加依赖 在SpringMVC的配置文件中添加配置:

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

2. 在SpringMVC的配置文件中添加配置

必须通过文件解析器的解析才能将通过表单上传的文件转换为MultipartFile对象

<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

3. 控制器方法

在Windows下的路径分隔符和Linux下的路径分隔符是不一样的,当直接使用绝对路径时,跨平台会暴出“No such file or diretory”的异常。

关于File.separator

比如说要在temp目录下建立一个test.txt文件,在Windows下应该这么写:
File file1 = new File ("C:\tmp\test.txt");
在Linux下则是这样的:
File file2 = new File ("/tmp/test.txt");

如果要考虑跨平台,则最好是这么写:
File myFile = new File("C:" + File.separator + "tmp" + File.separator, "test.txt");

File类有几个类似separator的静态字段,都是与系统相关的,在编程时应尽量使用。

重名问题(UUID)
先通过 substring来截取后缀名

再将uuid与后缀名结合

@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
    //获取上传的文件的文件名
    String fileName = photo.getOriginalFilename();
    //处理文件重名问题
    String hzName = fileName.substring(fileName.lastIndexOf("."));
    fileName = UUID.randomUUID().toString() + hzName;
    //获取服务器中photo目录的路径
    ServletContext servletContext = session.getServletContext();
    String photoPath = servletContext.getRealPath("photo");
    File file = new File(photoPath);
    if(!file.exists()){
        file.mkdir();
    }
    String finalPath = photoPath + File.separator + fileName;
    //实现上传功能
    photo.transferTo(new File(finalPath));
    return "success";
}

相关文章:

  • Android 系统jni到hal层回调代码
  • 初入算法(2)—— 进入算法世界
  • 运行谷歌开源BERT程序时遇到的bug修改记录
  • 算法学习入门
  • 【SSM】spring核心思想——IOC和DI
  • 自由的程序员应该学会自由地控制空间-----动态内存管理
  • [架构之路-51]:架构师 - 用系统化、结构化思维解决复杂难搞的软件故障问题 - 马克思主义哲学在软件系统中的应用
  • 【面试题】JavaScript数组切片方法有哪些?
  • 【PyTorch深度学习项目实战100例】—— 基于CNN卷积神经网络实现中文手写汉字识别 | 第60例
  • HarmonyOS系统中内核实现UART串口通信方法
  • Selenium4.0+Python三种元素等待方式介绍 及 元素等待封装
  • django梳理
  • 嵌入式软件调试的发展历程
  • PT_连续型随机变量/分布函数/概率密度
  • Python告别pip手动安装模块,实现全自动安装第三方库,彻底解放你的双手
  • 78. Subsets
  • CentOS 7 防火墙操作
  • Docker入门(二) - Dockerfile
  • JAVA 学习IO流
  • Java方法详解
  • nodejs调试方法
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • TypeScript迭代器
  • Vue.js-Day01
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 基于 Babel 的 npm 包最小化设置
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 区块链共识机制优缺点对比都是什么
  • 使用Gradle第一次构建Java程序
  • 手写一个CommonJS打包工具(一)
  • 学习笔记TF060:图像语音结合,看图说话
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • ​第20课 在Android Native开发中加入新的C++类
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • (0)Nginx 功能特性
  • (03)光刻——半导体电路的绘制
  • (31)对象的克隆
  • (C#)一个最简单的链表类
  • (C语言)二分查找 超详细
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (附源码)计算机毕业设计ssm电影分享网站
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (全注解开发)学习Spring-MVC的第三天
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)创业家杂志:UCWEB天使第一步
  • (转)负载均衡,回话保持,cookie
  • (转)为C# Windows服务添加安装程序
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .bat批处理(十一):替换字符串中包含百分号%的子串