Objective
Recently strict security, resulting in the original exposed S3 can not be used, do not allow the public S3, temporary compromise is to do their own jump. The file download function needs to be implemented in SPRINGMVC.
About the design of file storage
File storage is often used as an object store, and the industry standard is AWS S3, which is about seven cattle in the country. If you do not want to self-build, it is convenient to use this third-party storage. However, there is a need to note where to write.
Security issues
Just like this one, the permissions issue is probably the object storage must have. S3 privileges are particularly complex and can authenticate user access, specify IP access, specify IAM role access, specify third-party login such as Facebook,google authentication, set up their own authentication, here refers to Cognito.
Robustness of address paths
Review code to find a few serious problems, address problems are particularly important, is simply a bug. First, the DB stored file path should not contain the prefix of the domain name, such as the rectification of the image storage will result in the previous DB data can not be used. The db can only store relative paths, that is, when the type prefix is specified, the part of the path changes. . Then you need a domain name , for the public address, need a domain name to maintain, rather than directly specify the current file server. A public S3, for example, might be this: Https://mybucket.s3.amazonaws.com/keyprefix/key. If we change the bucket of S3, then this address is discarded, which is very likely to happen. Therefore, using one of our own domain names to point to S3 can block this detail. Similarly, if the address of the file server is written, the public file will be invalidated when the file server changes.
How to download files using SPRINGMVC
We can simply HttpServletResponse write our file stream in the OutputStream, so that we can implement the file download. But it feels a bit too straightforward, and it's recommended to use spring's responseentity.
@RequestMapping(Value ="/static/filename") PublicResponseentity<inputstreamresource> (httpservletresponse response) {FinalObjectmetadata objectmetadata = S3object.Getobjectmetadata();returnResponseentity.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()));}
- The core of the problem is returning
ResponseEntity<InputStreamResource>
ResponseEntityIt's SPRINGMVC. Unified Package Return value response information
InputStreamResourceIs the result set that receives an input stream InputStream
- You can then set the browser cache, which is very important for users to refresh the page
- For pictures and JS, you need to set contenttype for PNG or JS, etc.
Springmvc,springboot File Download