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 ...
随机推荐
- CSS 去掉inline-block间隙的几种方法
最近做移动端页面时,经常会用到inline-block元素来布局,但无可避免都会遇到一个问题,就是inline-block元素之间的间隙.这些间隙会导致一些布局上的问题,需要把间隙去掉.对于inlin ...
- php解决json_encode输出GB2312中文问题 (数组)
在 php 中使用 json_encode() 内置函数(php > 5.2)可以使用得 php 中数据可以与其它语言很好的传递并且使用它. 这个函数的功能是将数值转换成json数据存储格式. ...
- 树上操作[HAOI 2015]
树链剖分裸题: 树剖点这里:传送门 代码: #include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') ...
- vue2 watch引用类型 失败原因
vue中watch基本用法: new Vue({ el: '#t1', data: { a: { b: 1, c: 2 }, }, methods: { ch() { this.a.d=5 //不打印 ...
- Center OS 7 安装 $$
资料来自网络,收集整理做个备忘 1. 安装Python # yum install python-setuptools && easy_install pip 2. 安装$$ # pi ...
- java基础只关键字final
final关键字简述 final关键字是在编写java程序中出现频率和很高的关键字,如果想要更好的编写java程序,那么掌握final关键字的运用是非常必要的.让我们先看一下final关键字可以修饰的 ...
- git for windows上传项目到github
软件:git for windows 账户:github账户 1.第一步创建自己的github账号,并创建自己的project,创建完毕之后url如下 https://github.com/ft110 ...
- ul li自适应居中导航
<BODY> <div class="box"> <ul class="nav"> <li>邮箱管理</l ...
- 使用腾讯云无服务器云函数(SCF)分析天气数据
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:李想 无服务器云函数(SCF)是腾讯云提供的Serverless执行环境,也是国内首款FaaS(Function as a Service ...
- PHP连接LDAP进行登录验证
基于安全性考虑,准备把PHP做的自动化平台加入ldap登录验证,具体做法如下: 了解背景: LDAP 的全称是"轻量级目录访问协议(Lightweight Directory Access ...