前言

最近严查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()));
}
  1. 问题核心在于返回ResponseEntity<InputStreamResource>
  2. ResponseEntity是SpringMVC里统一封装的返回值response信息
  3. InputStreamResource则是接收一个输入流InputStream的结果集
  4. 然后可以设置浏览器缓存,这个对用户刷新页面挺重要的
  5. 对于图片和js等,需要设置contentType为png或者js等

SpringMVC,SpringBoot文件下载相关推荐

  1. 基于 Nginx XSendfile + SpringMVC 进行文件下载

    转自:http://denger.iteye.com/blog/1014066 基于 Nginx XSendfile + SpringMVC 进行文件下载 PS:经过实际测试,通过 nginx 提供文 ...

  2. Spring SpringMVC SpringBoot SpringCloud概念及关系

    一.Spring SpringMVC SpringBoot SpringCloud概念.关系及区别 Spring主要是基于IOC反转Beans管理Bean类,主要依存于SSH框架(Struts+Spr ...

  3. SpringMVC中文件下载

    3. SpringMVC中文件下载 3.1 文件下载的流程 # springmvc中文件下载1. 定义用户将服务器中文件下载到自己本地计算机中过程称之为文件下载2. 开发文件下载1). 定位系统中哪些 ...

  4. SpringMVC 实现文件下载

    SpringMVC 实现文件下载有两种方式: 常规方法 // 下载后的文件名称String filename = new String("xxx.dox","ISO885 ...

  5. Spring SpringMVC SpringBoot SpringCloud概念、关系及区别

    一.正面解读: Spring主要是基于IOC反转Beans管理Bean类,主要依存于SSH框架(Struts+Spring+Hibernate)这个MVC框架,所以定位很明确,Struts主要负责表示 ...

  6. [转]Spring SpringMVC SpringBoot SpringCloud概念、关系及区别

     一.正面解读: Spring主要是基于IOC反转Beans管理Bean类,主要依存于SSH框架(Struts+Spring+Hibernate)这个MVC框架,所以定位很明确,Struts主要负 ...

  7. spring+springmvc+springboot 常用注解

    springmvc: @ControllerAdvice:注解内部使用@ExceptionHandler.@InitBinder.@ModelAttribute注解的方法应用到所有的 @Request ...

  8. spring-mvc springboot 使用MockMvc对controller进行测试

    网上基本都是参考官方的使用方式,使用了import static,个人感觉这种方式特别不好,代码提示性不友好.所以在此进行说明,也方便自己以后使用. 1. 引入spring-test相关jar包,sp ...

  9. springMVC实现文件下载(附带Servlet方式)

    一.Servlet实现方式 import java.io.File; import java.io.IOException; import java.io.OutputStream;import ja ...

最新文章

  1. javaweb基础(35)_jdbc处理oracl大数据
  2. android中设置Animation 动画效果
  3. 湖南大学第十四届ACM程序设计新生杯(重现赛)L-The Digits String (矩阵快速幂)
  4. 新书出版:《Android深度探索(卷1):HAL与驱动开发》
  5. 程序员的算法课(5)-动态规划算法
  6. centos php7.0 mysql,如何在centos7.3系统下安装php7.0
  7. windows批量修改文件后缀名
  8. i510300h和i79750h参数对比哪个好?
  9. java中lookup函数怎么用,excel Lookup查表函数的使用方法
  10. Ubuntu 访问共享文件夹
  11. 解决Ubuntu16.04 wineQQ和wps office 不能输入中文的问题
  12. 人类简史-读书笔记之历史演变图
  13. unity 关闭所有日志输出
  14. 各类游戏对应服务端架构
  15. 如何在Word中创建和打印标签
  16. 前端工程化-基于Taro的Web端Monorepo架构改造
  17. 如何给一个 HTAP 数据库做基准测试?StoneDB学术分享会第4期
  18. 逻辑与和逻辑或的执行顺序
  19. 看了彭于晏解封后的照片,有网友瞬间觉得自己配得上他了
  20. 30个常用Python实现,新手必备!

热门文章

  1. Tomcat-简易使用教程
  2. Java反射机制应用实践
  3. 图解GitHub和SourceTree入门教程
  4. 【LaTeX】E喵的LaTeX新手入门教程(1)准备篇
  5. 获取指定目录下的所有文件名
  6. Java.util包中常用的类
  7. Android开发中遇到的问题(二)——新建android工程的时候eclipse没有生成MainActivity和layout布局...
  8. Script:GridControl Repository Health Check
  9. springcloud config 分布式配置中心
  10. RxJS/Cycle.js 与 React/Vue 相比更适用于什么样的应用场景?