Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the ways to download files in SpringBoot

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail the ways of downloading files in SpringBoot. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.

Document source

Here, take GridFS as an example. The main demonstration is the file downloaded from mongo. If it is a file on the local server, the frontend can directly obtain the stream via the file path, as shown below:

InputStream in = new FileInputStream (System.getProperty ("user.dir") + filePath)

Next, we will demonstrate the use of GridFsTemplate to download the file. In fact, the configuration of mongo has already been posted in the previous article. Here we will directly paste the code, without explaining the details.

@ Service@Slf4jpublic class MongoConfig extends AbstractMongoConfiguration {@ Autowired private MongoTemplate mongoTemplate; @ Autowired private GridFSBucket gridFSBucket; @ Override public MongoClient mongoClient () {MongoClient mongoClient = getMongoClient (); return mongoClient;} public MongoClient getMongoClient () {/ / MongoDB address list List serverAddresses = new ArrayList (); serverAddresses.add (new ServerAddress ("10.1.61.101 Autowired private GridFSBucket gridFSBucket; 27017")) / / connection authentication MongoCredential credential = MongoCredential.createCredential ("root", "admin", "Root_123" .toCharArray ()); MongoClientOptions.Builder builder = MongoClientOptions.builder (); / / maximum number of connections builder.connectionsPerHost (10); / / minimum number of connections builder.minConnectionsPerHost (0); / / timeout builder.connectTimeout (1000003) / / the maximum waiting time builder.maxWaitTime (5000) before a thread successfully obtains an available database; / / the maximum number of blocks that a thread becomes available with the number of rides of connectionsPerHost. All threads after this number of rides will get an exception in time. Eg.connectionsPerHost = 10 and threadsAllowedToBlockForConnectionMultiplier=5, a maximum of 50 thread levels per link, recommended configuration is 5 builder.threadsAllowedToBlockForConnectionMultiplier (5) / / maximum idle time builder.maxConnectionIdleTime (1000: 10); / / set the maximum lifetime of pool connections. Builder.maxConnectionLifeTime (1000 / 10); / / connection timeout builder.socketTimeout (1000 / 10); MongoClientOptions myOptions = builder.build (); MongoClient mongoClient = new MongoClient (serverAddresses, credential, myOptions); return mongoClient;} @ Override protected String getDatabaseName () {return "notifyTest" } / * get another database * @ return * / public String getFilesDataBaseName () {return "notifyFiles";} / * used to switch different databases * @ return * / public MongoDbFactory getDbFactory (String dataBaseName) {MongoDbFactory dbFactory = null; try {dbFactory = new SimpleMongoDbFactory (getMongoClient (), dataBaseName) } catch (Exception e) {log.error ("Get mongo client have an error, please check reason...", e.getMessage ());} return dbFactory;} / * get file storage module * @ return * / public GridFsTemplate getGridFS () {return new GridFsTemplate (getDbFactory (getFilesDataBaseName ()), mongoTemplate.getConverter () } @ Bean public GridFSBucket getGridFSBuckets () {MongoDatabase db = getDbFactory (getFilesDataBaseName ()). GetDb (); return GridFSBuckets.create (db);} / * convert GridFSFile to GridFsResource * @ param gridFsFile * @ return * / public GridFsResource convertGridFSFile2Resource (GridFSFile gridFsFile) {GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream (gridFsFile.getObjectId ()) in order to solve the class changes returned by the findOne method after springBoot2.0 Return new GridFsResource (gridFsFile, gridFSDownloadStream);}}

Compared with the previous configuration, the two new methods are mainly added to deal with SpringBoot2.x. The findOne () method of GridFsTemplate returns the change from GridFSDBFile to GridFSFile, so the previous GridFSDBFile operation stream cannot be used when downloading the file, so the conversion operation is added.

File download

Post the download implementation of the two ways respectively.

1. OutputStream form @ RequestMapping (value = "/ download2", method = RequestMethod.GET) public void downLoad2 (HttpServletResponse response, String id) {userService.download2 (response, id);}

The controller layer is just a test, so it is very simple. Because it is in the form of a stream, there is no need to specify the output format. Let's take a look at the service layer implementation.

/ * download the file * @ param response * @ param id * / @ Override public void download2 (HttpServletResponse response, String id) {GridFsTemplate gridFsTemplate = new GridFsTemplate (mongoConfig.getDbFactory (mongoConfig.getFilesDataBaseName ()), mongoTemplate.getConverter ()) in OutputStream format / / since the findOne method returns from GridFSDBFile to GridFSFile after springBoot is upgraded to 2.x, the download becomes slightly cumbersome GridFSFile gridFSFile = gridFsTemplate.findOne (new Query (Criteria.where ("_ id"). Is (id)); String fileName = gridFSFile.getFilename (); GridFsResource gridFsResource = mongoConfig.convertGridFSFile2Resource (gridFSFile); / / timing long startTime = System.currentTimeMillis () from here InputStream in = null; OutputStream out = null; try {/ / Chinese needs to be transcoded here fileName = new String (fileName.getBytes ("utf-8"), "ISO-8859-1"); / / tell the browser to pop up the download dialog response.setHeader ("Content-Disposition", "attachment;filename=" + fileName) Byte [] buffer = new byte [1024]; int len; / / get the output stream out = response.getOutputStream (); in = gridFsResource.getInputStream (); while ((len = in.read (buffer)) > 0) {out.write (buffer, 0, len) } catch (IOException e) {log.error ("transfer in error.");} finally {try {if (null! = in) in.close (); if (null! = out) out.close () Log.info ("download file with stream total time: {}", System.currentTimeMillis ()-startTime);} catch (IOException e) {log.error ("close IO error.");}

You can see that the length is long, and the comments are already in the code.

2. ResponseEntity form @ RequestMapping (value = "/ download", method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public Object downLoad (String id) {return userService.download (id);}

Controller needs to specify the output format application/octet-stream, indicating that the file is downloaded as a stream. Take a look at the service layer below.

/ * download the file * @ param id * @ return * / @ Override public ResponseEntity download (String id) {GridFsTemplate gridFsTemplate = new GridFsTemplate (mongoConfig.getDbFactory (mongoConfig.getFilesDataBaseName ()), mongoTemplate.getConverter ()) in ResponseEntity format / / since the findOne method returns from GridFSDBFile to GridFSFile after springBoot is upgraded to 2.x, the download becomes slightly cumbersome GridFSFile gridFSFile = gridFsTemplate.findOne (new Query (Criteria.where ("_ id"). Is (id)); String fileName = gridFSFile.getFilename (); GridFsResource gridFsResource = mongoConfig.convertGridFSFile2Resource (gridFSFile); / / timing long startTime = System.currentTimeMillis () from here Try {InputStream in = gridFsResource.getInputStream (); / / request body byte [] body = IOUtils.toByteArray (in); / / request header HttpHeaders httpHeaders = new HttpHeaders (); / / Chinese transcoding fileName = new String ("utf-8"), "ISO-8859-1") / / tell the browser to pop up the download dialog httpHeaders.add ("Content-Disposition", "attachment;filename=" + fileName); ResponseEntity responseEntity = new ResponseEntity (body, httpHeaders, HttpStatus.OK); log.info ("download file total with ResponseEntity time: {}", System.currentTimeMillis ()-startTime); return responseEntity } catch (IOException e) {log.error ("transfer in error.");} return null;}

The above uses the IOUtils utility class, which depends on the following

Comparison of download Speed between two ways of commons-io commons-io 2.4,

After testing, when the file is less than 1m, the speed of the two methods is about the same, and then I tested the 5m file, and the results are as follows:

You can see that the OutputStream is a little slower, and there is no test here when the file is large. In short, I recommend downloading the file in ResponseEntity format.

Later words

If you just want to display a picture under a certain path and do not need to download it, use the following form:

@ RequestMapping (value = "/ application/file/show", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE) public Object downloadFile (@ RequestParam ("path") String filePath) {try {InputStream in = new FileInputStream (System.getProperty ("user.dir") + filePath); byte [] bytes = new byte [in.available ()]; in.read (bytes); return bytes } catch (IOException e) {log.error ("transfer byte error"); return buildMessage (ResultModel.FAIL, "show pic error");}}

Note the available () method above, which returns the number of bytes contained in the input stream so that you can know the number during read and write operations, and whether you can use it depends on whether the available method is implemented in the concrete subclass that implements the abstract class InputStream.

If you implement it, you can get the size, and if you don't implement it, you can't get it.

For example, FileInputStream implements the available method, so you can use new byte [in.available ()]; this way.

However, the InputStream fetched from Socket during network programming does not implement this method, so you cannot create an array in this way.

This is the end of this article on "what are the ways to download files in SpringBoot?". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report