好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

SpringBoot 集成MongoDB实现文件上传功能

前言

记录下 SpringBoot 集成 MongoDB 实现文件上传的步骤 MongoDB - 5.0.6 安装包

链接: https://pan.baidu.com/s/1_7nJDe3ndraNyo3vGWOXhg?pwd=i4cv 
提取码: i4cv 

环境

SpringBoot - 2.5.12
MongoDB - 5.0.6

代码实现

pom.xml

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<dependency>

     <groupId>org.springframework.boot</groupId>

     <artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!-- mongodb -->

<dependency>

     <groupId>org.springframework.boot</groupId>

     <artifactId>spring-boot-starter-data-mongodb</artifactId>

</dependency>

<!-- lombok -->

<dependency>

     <groupId>org.projectlombok</groupId>

     <artifactId>lombok</artifactId>

</dependency>

<!-- hutool -->

<dependency>

     <groupId>cn.hutool</groupId>

     <artifactId>hutool-all</artifactId>

     <version> 4.5 . 1 </version>

</dependency>

application.yml

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

server:

   port: 31091

 

spring:

   servlet:

     multipart:

       max-file-size: 100MB

   data:

     mongodb:

       host: 127.0 . 0.1

       port: 27017

       database: admin

       username: root

       password: sunday

 

fileUploadService:

   impl: fileMongoServiceImpl

MongoConfig.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import com.mongodb.client.MongoClient;

import com.mongodb.client.MongoDatabase;

import com.mongodb.client.gridfs.GridFSBucket;

import com.mongodb.client.gridfs.GridFSBuckets;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

 

/**

  * @Description MongoDB配置类

  */

@Configuration

public class MongoConfig {

     /**

      * 数据库配置信息

      */

     @Value ( "${spring.data.mongodb.database}" )

     private String db;

 

     /**

      * GridFSBucket用于打开下载流

      * @param mongoClient

      * @return

      */

     @Bean

     public GridFSBucket getGridFSBucket(MongoClient mongoClient){

         MongoDatabase mongoDatabase = mongoClient.getDatabase(db);

         return GridFSBuckets.create(mongoDatabase);

     }

}

FileUploadController.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

import com.coisini.mongodb.model.ResponseMessage;

import com.coisini.mongodb.service.FileUploadService;

import com.coisini.mongodb.vo.FileExportVo;

import lombok.extern.slf4j.Slf4j;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import java.util.List;

import java.util.Objects;

/**

  * @Description 文件上传接口

  */

@Slf4j

@RestController

@RequestMapping ( "/file" )

public class FileUploadController {

     /**

      * 文件上传实现类

      */

     @Resource (name= "${fileUploadService.impl}" )

     private FileUploadService fileUploadService;

      * 文件上传

      * @param file

      * @return

     @PostMapping ( "/upload" )

     public ResponseMessage<?> uploadFile( @RequestParam (value = "file" ) MultipartFile file) {

         try {

             return ResponseMessage.ok( "上传成功" , fileUploadService.uploadFile(file));

         } catch (Exception e) {

             log.error( "文件上传失败:" , e);

             return ResponseMessage.error(e.getMessage());

         }

     }

      * 多文件上传

      * @param files

     @PostMapping ( "/uploadFiles" )

     public ResponseMessage<?> uploadFile( @RequestParam (value = "files" ) List<MultipartFile> files) {

             return ResponseMessage.ok( "上传成功" , fileUploadService.uploadFiles(files));

      * 文件下载

      * @param fileId

     @GetMapping ( "/download/{fileId}" )

     public ResponseEntity<Object> fileDownload( @PathVariable (name = "fileId" ) String fileId) {

         FileExportVo fileExportVo = fileUploadService.downloadFile(fileId);

         if (Objects.nonNull(fileExportVo)) {

             return ResponseEntity.ok()

                     .header(HttpHeaders.CONTENT_DISPOSITION, "fileName=\"" + fileExportVo.getFileName() + "\"" )

                     .header(HttpHeaders.CONTENT_TYPE, fileExportVo.getContentType())

                     .header(HttpHeaders.CONTENT_LENGTH, fileExportVo.getFileSize() + "" ).header( "Connection" , "close" )

                     .body(fileExportVo.getData());

         } else {

             return ResponseEntity.status(HttpStatus.NOT_FOUND).body( "file does not exist" );

      * 文件删除

     @DeleteMapping ( "/remove/{fileId}" )

     public ResponseMessage<?> removeFile( @PathVariable (name = "fileId" ) String fileId) {

         fileUploadService.removeFile(fileId);

         return ResponseMessage.ok( "删除成功" );

}

FileUploadService.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

import com.coisini.mongodb.vo.FileExportVo;

import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**

  * @Description 文件上传接口

  */

public interface FileUploadService {

     /**

      * 文件上传

      * @param file

      * @return

      */

     FileExportVo uploadFile(MultipartFile file) throws Exception;

     /**

      * 多文件上传

      * @param files

      * @return

      */

     List<FileExportVo> uploadFiles(List<MultipartFile> files);

     /**

      * 文件下载

      * @param fileId

      * @return

      */

     FileExportVo downloadFile(String fileId);

     /**

      * 文件删除

      * @param fileId

      */

     void removeFile(String fileId);

}

FileMongoServiceImpl.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

import cn.hutool.core.io.IoUtil;

import cn.hutool.core.util.IdUtil;

import com.coisini.mongodb.model.MongoFile;

import com.coisini.mongodb.repository.MongoFileRepository;

import com.coisini.mongodb.service.FileUploadService;

import com.coisini.mongodb.util.MD5Util;

import com.coisini.mongodb.vo.FileExportVo;

import com.mongodb.client.gridfs.GridFSBucket;

import com.mongodb.client.gridfs.GridFSDownloadStream;

import com.mongodb.client.gridfs.model.GridFSFile;

import lombok.RequiredArgsConstructor;

import lombok.extern.slf4j.Slf4j;

import org.bson.types.Binary;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.data.mongodb.core.query.Criteria;

import org.springframework.data.mongodb.core.query.Query;

import org.springframework.data.mongodb.gridfs.GridFsResource;

import org.springframework.data.mongodb.gridfs.GridFsTemplate;

import org.springframework.stereotype.Service;

import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

import java.io.InputStream;

import java.util.Date;

import java.util.List;

import java.util.Objects;

import java.util.Optional;

import java.util.stream.Collectors;

/**

  * @Description MongoDB文件上传实现类

  */

@Slf4j

@Service ( "fileMongoServiceImpl" )

@RequiredArgsConstructor (onConstructor = @__ ( @Autowired ))

public class FileMongoServiceImpl implements FileUploadService {

     private final MongoFileRepository mongoFileRepository;

     private final MongoTemplate mongoTemplate;

     private final GridFsTemplate gridFsTemplate;

     private final GridFSBucket gridFSBucket;

     /**

      * 多文件上传

      * @param files

      * @return

      */

     @Override

     public List<FileExportVo> uploadFiles(List<MultipartFile> files) {

         return files.stream().map(file -> {

             try {

                 return this .uploadFile(file);

             } catch (Exception e) {

                 log.error( "文件上传失败" , e);

                 return null ;

             }

         }).filter(Objects::nonNull).collect(Collectors.toList());

     }

     /**

      * 文件上传

      * @param file

      * @return

      * @throws Exception

      */

     @Override

     public FileExportVo uploadFile(MultipartFile file) throws Exception {

         if (file.getSize() > 16777216 ) {

             return this .saveGridFsFile(file);

         } else {

             return this .saveBinaryFile(file);

         }

     }

     /**

      * 文件下载

      * @param fileId

      * @return

      */

     @Override

     public FileExportVo downloadFile(String fileId) {

         Optional<MongoFile> option = this .getBinaryFileById(fileId);

         if (option.isPresent()) {

             MongoFile mongoFile = option.get();

             if (Objects.isNull(mongoFile.getContent())){

                 option = this .getGridFsFileById(fileId);

             }

         }

         return option.map(FileExportVo:: new ).orElse( null );

     }

     /**

      * 文件删除

      * @param fileId

      */

     @Override

     public void removeFile(String fileId) {

         Optional<MongoFile> option = this .getBinaryFileById(fileId);

         if (option.isPresent()) {

             if (Objects.nonNull(option.get().getGridFsId())) {

                 this .removeGridFsFile(fileId);

             } else {

                 this .removeBinaryFile(fileId);

             }

         }

     }

     /**

      * 删除Binary文件

      * @param fileId

      */

     public void removeBinaryFile(String fileId) {

         mongoFileRepository.deleteById(fileId);

     }

     /**

      * 删除GridFs文件

      * @param fileId

      */

     public void removeGridFsFile(String fileId) {

         // TODO 根据id查询文件

         MongoFile mongoFile = mongoTemplate.findById(fileId, MongoFile. class );

         if (Objects.nonNull(mongoFile)){

             // TODO 根据文件ID删除fs.files和fs.chunks中的记录

             Query deleteFileQuery = new Query().addCriteria(Criteria.where( "filename" ).is(mongoFile.getGridFsId()));

             gridFsTemplate.delete(deleteFileQuery);

             // TODO 删除集合mongoFile中的数据

             Query deleteQuery = new Query(Criteria.where( "id" ).is(fileId));

             mongoTemplate.remove(deleteQuery, MongoFile. class );

         }

     }

     /**

      * 保存Binary文件(小文件)

      * @param file

      * @return

      * @throws Exception

      */

     public FileExportVo saveBinaryFile(MultipartFile file) throws Exception {

         String suffix = getFileSuffix(file);

         MongoFile mongoFile = mongoFileRepository.save(

                 MongoFile.builder()

                         .fileName(file.getOriginalFilename())

                         .fileSize(file.getSize())

                         .content( new Binary(file.getBytes()))

                         .contentType(file.getContentType())

                         .uploadDate( new Date())

                         .suffix(suffix)

                         .md5(MD5Util.getMD5(file.getInputStream()))

                         .build()

         );

         return new FileExportVo(mongoFile);

     }

     /**

      * 保存GridFs文件(大文件)

      * @param file

      * @return

      * @throws Exception

      */

     public FileExportVo saveGridFsFile(MultipartFile file) throws Exception {

         String suffix = getFileSuffix(file);

         String gridFsId = this .storeFileToGridFS(file.getInputStream(), file.getContentType());

         MongoFile mongoFile = mongoTemplate.save(

                 MongoFile.builder()

                         .fileName(file.getOriginalFilename())

                         .fileSize(file.getSize())

                         .contentType(file.getContentType())

                         .uploadDate( new Date())

                         .suffix(suffix)

                         .md5(MD5Util.getMD5(file.getInputStream()))

                         .gridFsId(gridFsId)

                         .build()

         );

         return new FileExportVo(mongoFile);

     }

     /**

      * 上传文件到Mongodb的GridFs中

      * @param in

      * @param contentType

      * @return

      */

     public String storeFileToGridFS(InputStream in, String contentType){

         String gridFsId = IdUtil.simpleUUID();

         // TODO 将文件存储进GridFS中

         gridFsTemplate.store(in, gridFsId , contentType);

         return gridFsId;

     }

     /**

      * 获取Binary文件

      * @param id

      * @return

      */

     public Optional<MongoFile> getBinaryFileById(String id) {

         return mongoFileRepository.findById(id);

     }

     /**

      * 获取Grid文件

      * @param id

      * @return

      */

     public Optional<MongoFile> getGridFsFileById(String id){

         MongoFile mongoFile = mongoTemplate.findById(id , MongoFile. class );

         if (Objects.nonNull(mongoFile)){

             Query gridQuery = new Query().addCriteria(Criteria.where( "filename" ).is(mongoFile.getGridFsId()));

             try {

                 // TODO 根据id查询文件

                 GridFSFile fsFile = gridFsTemplate.findOne(gridQuery);

                 // TODO 打开流下载对象

                 GridFSDownloadStream in = gridFSBucket.openDownloadStream(fsFile.getObjectId());

                 if (in.getGridFSFile().getLength() > 0 ){

                     // TODO 获取流对象

                     GridFsResource resource = new GridFsResource(fsFile, in);

                     // TODO 获取数据

                     mongoFile.setContent( new Binary(IoUtil.readBytes(resource.getInputStream())));

                     return Optional.of(mongoFile);

                 } else {

                     return Optional.empty();

                 }

             } catch (IOException e){

                 log.error( "获取MongoDB大文件失败" , e);

             }

         }

         return Optional.empty();

     }

     /**

      * 获取文件后缀

      * @param file

      * @return

      */

     private String getFileSuffix(MultipartFile file) {

         String suffix = "" ;

         if (Objects.requireNonNull(file.getOriginalFilename()).contains( "." )) {

             suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf( "." ));

         }

         return suffix;

     }

}

MongoFileRepository.java

?

1

2

3

4

5

6

7

8

9

import com.coisini.mongodb.model.MongoFile;

import org.springframework.data.mongodb.repository.MongoRepository;

 

/**

  * @Description MongoDB文件仓储

  */

public interface MongoFileRepository extends MongoRepository<MongoFile, String> {

 

}

MongoFile.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

import lombok.Builder;

import lombok.Data;

import org.bson.types.Binary;

import org.springframework.data.annotation.Id;

import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

 

/**

  * @Description MongoDB文件实体

  */

@Document

@Builder

@Data

public class MongoFile {

 

     /**

      * 主键

      */

     @Id

     public String id;

 

     /**

      * 文件名称

      */

     public String fileName;

 

     /**

      * 文件大小

      */

     public long fileSize;

 

     /**

      * 上传时间

      */

     public Date uploadDate;

 

     /**

      * MD5值

      */

     public String md5;

 

     /**

      * 文件内容

      */

     private Binary content;

 

     /**

      * 文件类型

      */

     public String contentType;

 

     /**

      * 文件后缀名

      */

     public String suffix;

 

     /**

      * 文件描述

      */

     public String description;

 

     /**

      * 大文件管理GridFS的ID

      */

     private String gridFsId;

 

}

ResponseMessage.java

?

1

2

3

4

5

6

7

8

9

10

11

12

/**

  * @Description 统一消息

  */

public class ResponseMessage<T> {

 

     private String status;

     private String message;

     private T data;

 

     // 省略

 

}

FileExportVo.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import java.util.Objects;

 

/**

  * @Description 统一文件下载vo

  */

@Data

public class FileExportVo {

 

     private String fileId;

 

     private String fileName;

 

     private String contentType;

 

     private String suffix;

 

     private long fileSize;

 

     @JsonIgnore

     private byte [] data;

 

     public FileExportVo(MongoFile mongoFile) {

         BeanUtil.copyProperties(mongoFile, this );

         if (Objects.nonNull(mongoFile.getContent())) {

             this .data = mongoFile.getContent().getData();

         }

         this .fileId = mongoFile.getId();

     }

 

}

MD5Util.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import java.io.IOException;

import java.io.InputStream;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

 

/**

  * @Description MD5工具类

  */

public class MD5Util {

     /**

      * 获取该输入流的MD5值

      */

     public static String getMD5(InputStream is) throws NoSuchAlgorithmException, IOException {

         StringBuffer md5 = new StringBuffer();

         MessageDigest md = MessageDigest.getInstance( "MD5" );

         byte [] dataBytes = new byte [ 1024 ];

 

         int nread = 0 ;

         while ((nread = is.read(dataBytes)) != - 1 ) {

             md.update(dataBytes, 0 , nread);

         };

         byte [] mdbytes = md.digest();

 

         // convert the byte to hex format

         for ( int i = 0 ; i < mdbytes.length; i++) {

             md5.append(Integer.toString((mdbytes[i] & 0xff ) + 0x100 , 16 ).substring( 1 ));

         }

         return md5.toString();

     }

}

测试

文件上传

多文件上传

文件下载

文件删除

源码

GitHub : https://github.com/Maggieq8324/java-learn-demo/tree/master/springboot-mongodb-file

Gitee : https://gitee.com/maggieq8324/java-learn-demo/tree/master/springboot-mongodb-file

到此这篇关于SpringBoot 集成MongoDB实现文件上传的文章就介绍到这了,更多相关SpringBoot 集成MongoDB文件上传内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_41182727/article/details/124229613

查看更多关于SpringBoot 集成MongoDB实现文件上传功能的详细内容...

  阅读:18次