SpringMVC,SpringBoot文件下载
前言
最近严查security, 导致原来暴露出去的s3不能用了,不允许public的s3,暂时的折中方案是自己做跳转。于是需要在SpringMVC中实现文件下载功能。
关于文件存储的设计
文件存储通常用作对象存储,业界标准就是AWS s3, 国内的七牛也差不多。不想自建的话,采用这种第三方存储是很方便的。但是,有写地方需要注意。
安全问题
就像这次整改遇到的,权限问题大概是对象存储必须具备的。s3的权限特别多和复杂,可以做到认证user访问; 指定ip访问; 指定IAM Role访问; 指定第三方登陆比如Facebook,google的认证,设置自己的认证,这里是指Cognito。
地址路径的健壮性
review代码的时候发现了几个严重的问题,地址问题尤为重要,简直就是bug一样。首先,db存储的文件路径不应该包含域名前缀,像这次整改图片存储就导致以前db里的数据不能用了。db只能存储相对路径,即当指定改类型前缀后,变化的部分路径。。 然后就是 需要一个域名,对于公开的地址,需要一个域名来维护,而不是直接指定当前的文件服务器。比如一个公开的s3可能是这样的:https://mybucket.s3.amazonaws.com/keyprefix/key. 如果我们变更了s3的bucket,那么这个地址就废弃了,这个很有可能发生的。因此,用一个我们自己的域名指向s3可以屏蔽这个细节。同理,如果写死了文件服务器的地址,当文件服务器变更的时候,公开的文件将全部失效。
如何使用SpringMVC下载文件
我们可以简单的在HttpServletResponse
的OutputStream里写入我们的文件流,这样就可以实现文件下载。但这个做法感觉有点太直接了,推荐使用Spring的ResponseEntity来做。
@RequestMapping(value = "/static/filename")
public ResponseEntity<InputStreamResource>(HttpServletResponse response) {
final ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
return ResponseEntity.ok()
.header("Access-Control-Allow-Origin", "*")
.cacheControl(CacheControl.maxAge(maxAge, TimeUnit.DAYS).cachePublic())
.allow(HttpMethod.GET, HttpMethod.OPTIONS)
.contentLength(objectMetadata.getContentLength())
.contentType(MediaType.valueOf(objectMetadata.getContentType()))
.body(new InputStreamResource(s3Object.getObjectContent()));
}
- 问题核心在于返回
ResponseEntity<InputStreamResource>
ResponseEntity
是SpringMVC里统一封装的返回值response信息InputStreamResource
则是接收一个输入流InputStream的结果集- 然后可以设置浏览器缓存,这个对用户刷新页面挺重要的
- 对于图片和js等,需要设置contentType为png或者js等
SpringMVC,SpringBoot文件下载的更多相关文章
- spring springMvc spring-boot spring-cloud分别是什么
本文来源于:克己习礼成仁 的<spring springMvc spring-boot spring-cloud分别是什么> 什么是spring 关于spring的定义无论是从官方还是 ...
- springmvc springboot 跨域问题(CORS)
官方文档:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html springmvc s ...
- 基于 Nginx XSendfile + SpringMVC 进行文件下载
转自:http://denger.iteye.com/blog/1014066 基于 Nginx XSendfile + SpringMVC 进行文件下载 PS:经过实际测试,通过 nginx 提供文 ...
- SpringMVC实现文件下载的两种方式及多文件下载
1.传统方法 @RequestMapping("/download") public String download( String fileName ,String filePa ...
- springmvc/springboot开发restful API
非rest的url写法: 查询 GET /user/query?name=tom 详情 GET /user/getinfo? 创建 POST /user/create?name=tom 修改 POST ...
- Spring SpringMVC SpringBoot SpringCloud 注解整理大全
Spring SpringMVC SpringBoot SpringCloud 注解整理 才开的博客所以放了一篇以前整理的文档,如果有需要添加修改的地方欢迎指正,我会修改的φ(๑˃∀˂๑)♪ Spri ...
- 开发者说:Sentinel 流控功能在 SpringMVC/SpringBoot 上的实践
从用户的视角来感受一个开源项目的成长,是我们推出「开发者说」专栏的初衷,即在开发者进行开源项目选型时,提供更为立体的项目信息.专栏所有内容均来自作者原创/投稿,本文是「开发者说」的第6篇,作者 Jas ...
- springmvc实现文件下载
springmvc实现文件下载 使用springmvc实现文件下载有两种方式,都需要设置response的Content-Disposition为attachment;filename=test2.p ...
- SpringMVC & SpringBoot小记
SpringMVC 1.SpringMVC常用注解 https://blog.csdn.net/lipinganq/article/details/79155072 :@Component.@Serv ...
随机推荐
- JS中事件绑定的三种方式
以下是搜集的在JS中事件绑定的三种方式. 1. HTML onclick attribute <button type="button" id="upl ...
- 搭建PHP本地服务器(XAMPP)
1.下载XAMPP集成包 https://www.apachefriends.org/download.html2.启动前修改配置文件httpd.conf的端口号,例如:Listen 80803.启动 ...
- ES6(三)数组的扩展
1.Array.form ES6中,Array.from = function(items,mapfn,thisArg) { } Array.from 用于将 类数组 和 可遍历对象(实现了It ...
- glimmer 3.02安装小记
wget http://www.cbcb.umd.edu/software/glimmer/glimmer302.tar.gz tar xzfglimmer302.tar.gz cd glimmer3 ...
- MySQL优化三 表结构优化
由于MySQL数据库是基于行(Row)存储的数据库,而数据库操作 IO 的时候是以 page(block)的方式,也就是说,如果我们每条记录所占用的空间量减小,就会使每个page中可存放的数据行数增大 ...
- 页面刷新vuex数据消失问题解决方案 之 vuex中间件
之前我写了一篇用ES6 Proxy方案解决数据同步的文章 页面刷新vuex数据消失问题解决方案. 今天和同事沟通这个vuex数据还原问题,我说我的方法很奇异.聊着聊着,同事咋不用 store.sub ...
- Winform跨窗体操作控件(使用委托)
Winform跨窗体操作控件是winform开发中很常见的形式,最常见且简单有效的方式便是使用委托的方式来进行操作,下面我将通过一个小实例来说明如何使用委托跨窗体实现控件操作. 实例介绍:两个窗体,F ...
- MySQL 基础命令
的说法啊打发 第1章 SQL语句 mysql版本:针对mysql-5.6.36 版本 (5.7会有一些变动) 1.1 常用命令 # 查看数据库 mysql> show databases; sh ...
- linux上配置bochs,搭建基于X86架构操作系统的开发环境
学习操作系统最好的方法就是自己编写新的操作系统,或者修改已有的操作系统.但是如果在真机上完成这个过程,调试会成为一个很大的问题.利用虚拟机来完成,可以使调试过程变得简单,而且能节约很多开关机的时间. ...
- Java学习笔记17(面向对象十:综合案例)
在面向对象这个专题的最后 结合前面多篇文章,用到了面向对象的很多方面知识,做了一个简单的案例: 饭店案例: package hotel; /* * 酒店的员工类 * 员工共同特点:姓名,工号,工作方法 ...