javascript
SpringMVC,SpringBoot文件下载
前言
最近嚴(yán)查security, 導(dǎo)致原來暴露出去的s3不能用了,不允許public的s3,暫時的折中方案是自己做跳轉(zhuǎn)。于是需要在SpringMVC中實現(xiàn)文件下載功能。
關(guān)于文件存儲的設(shè)計
文件存儲通常用作對象存儲,業(yè)界標(biāo)準(zhǔn)就是AWS s3, 國內(nèi)的七牛也差不多。不想自建的話,采用這種第三方存儲是很方便的。但是,有寫地方需要注意。
安全問題
就像這次整改遇到的,權(quán)限問題大概是對象存儲必須具備的。s3的權(quán)限特別多和復(fù)雜,可以做到認(rèn)證user訪問; 指定ip訪問; 指定IAM Role訪問; 指定第三方登陸比如Facebook,google的認(rèn)證,設(shè)置自己的認(rèn)證,這里是指Cognito。
地址路徑的健壯性
review代碼的時候發(fā)現(xiàn)了幾個嚴(yán)重的問題,地址問題尤為重要,簡直就是bug一樣。首先,db存儲的文件路徑不應(yīng)該包含域名前綴,像這次整改圖片存儲就導(dǎo)致以前db里的數(shù)據(jù)不能用了。db只能存儲相對路徑,即當(dāng)指定改類型前綴后,變化的部分路徑。。 然后就是 需要一個域名,對于公開的地址,需要一個域名來維護(hù),而不是直接指定當(dāng)前的文件服務(wù)器。比如一個公開的s3可能是這樣的:https://mybucket.s3.amazonaws.com/keyprefix/key. 如果我們變更了s3的bucket,那么這個地址就廢棄了,這個很有可能發(fā)生的。因此,用一個我們自己的域名指向s3可以屏蔽這個細(xì)節(jié)。同理,如果寫死了文件服務(wù)器的地址,當(dāng)文件服務(wù)器變更的時候,公開的文件將全部失效。
如何使用SpringMVC下載文件
我們可以簡單的在HttpServletResponse的OutputStream里寫入我們的文件流,這樣就可以實現(xiàn)文件下載。但這個做法感覺有點太直接了,推薦使用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())); }總結(jié)
以上是生活随笔為你收集整理的SpringMVC,SpringBoot文件下载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工程实战-ES6环境配置
- 下一篇: Spring Boot中Starter是