SpringBoot整合MongoBD实现文件的上传下载

文件的上传下载在web项目上经常用到,之前都是用别人写好的代码。工作之余自己也尝试写了上传下载的接口,以后项目中用到的话可以直接拿来用。本实例是在mysql上记录上传的文件信息,所以需要一个实体类。废话不多说,直接上菜:
1.开发环境:IDEA+JDK8+SpringBoot2.2.2+MongoDB
2.首先在pom文件引入MongoDB的依赖包:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

3.配置文件连接设置(我用的是本地的MongoDB没有设置用户名和密码):

  data:
    mongodb:
      uri: mongodb://127.0.0.1:27017/test
    servlet:
      multipart:
        #是否支持批量上传
        enabled: true
        #上传文件最大为 100M
        max-file-size: 100MB
        #上传总数据大小 200M
        max-request-size: 200MB

4.实体类FileMetadata创建:

package com.example.demo.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import javax.persistence.*;
import java.sql.Timestamp;

/**
 * 保存在mongo中的文件,与各个相关实体比如申请工单、协议等关联
 */
@Data
@Entity
@Table(name = "file_metadata")
public class FileMetadata {

    @Id
    // 这应该不是数据库生成,而是mongo那边的ID
//    @GeneratedValue(generator = "uuidMongoFiles")
//    @GenericGenerator(name = "uuidMongoFiles", strategy = "uuid")
    @Column(name = "id", columnDefinition = "varchar(128) COMMENT '编号'")
    private String id;

    @Column(name = "FILE_TYPE", columnDefinition = "varchar(20) COMMENT '文件类型,如资质文件、协议文件等'")
    private String fileType;

    @Column(name = "OBJECT_ID", columnDefinition = "varchar(128) COMMENT '关联的ID'")
    private String associateId;

    @Column(name = "OBJECT_CLASS", columnDefinition = "varchar(20) COMMENT '关联的实体类型'")
    private String associateObjectClass;

    @Column(name = "FILE_SEQ_NO", columnDefinition = "SMALLINT COMMENT '文件顺序'")
    private Integer fileOrder;

    @Column(name = "FILE_ORIGIN_NAME", columnDefinition = "varchar(255) COMMENT '上传文件原名'")
    private String fileOriginName;

    @Column(name = "FILE_DISPLAY_NAME", columnDefinition = "varchar(255) COMMENT '文件的标准展示名'")
    private String fileDisplayName;

    @Column(name = "FILE_YEAR", columnDefinition = "SMALLINT COMMENT '资料相关的年份'")
    private Integer year;

    @Column(name = "UPLOAD_TIME", columnDefinition = "timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '上传时间'")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Timestamp uploadTime;

    @Column(name = "MEMO", columnDefinition = "varchar(255) COMMENT '备注信息'")
    private String comment;

    @Column(name = "OPERATOR", columnDefinition = "varchar(50) COMMENT '操作员'")
    private String operator;

    @Transient
    private String viewPtah;

}

5.保存到MongoDB上的文件信息实体类创建:

package com.example.demo.mongodb.entity;

import lombok.Data;

import java.time.LocalDateTime;

/**
 * 定义保存在mongoFile中的mongoData
 */
@Data
public class MongoFileMetaDate {

    private String fileName;
    private String relatedOrgId;
    private String uploadUser;
    private LocalDateTime uploadTime;
    private String comment;

}

6.Controller层代码实现:

package com.example.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.dao.FileMetadataRepo;
import com.example.demo.entity.FileMetadata;
import com.example.demo.mongodb.repo.MongoFileRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;
import java.time.LocalDateTime;

/**
 * @Author: lqs
 * @Date: 2019/12/30 15:01
 */
@RestController
@RequestMapping("/uploadFiles")
public class uploadFilesController {
    @Autowired
    private MongoFileRepo mongoFileRepo;
    @Autowired
    private FileMetadataRepo fileMetadataRepo;

    /**
     * 文件上传
     * @param file
     * @return
     */
    @RequestMapping("/upload")
    @ResponseBody
    public String httpUpload(@RequestParam("files") MultipartFile file){
        JSONObject object=new JSONObject();
        String comment = "上传文件测试";//备注
        FileMetadata fileMetadata = new FileMetadata();
        fileMetadata.setAssociateId("10086");
        fileMetadata.setUploadTime(Timestamp.valueOf(LocalDateTime.now()));//上传时间
        fileMetadata.setFileOrder(1);//排序
        fileMetadata.setComment(comment);
        fileMetadata.setYear(2019);//年份
        fileMetadata.setFileOriginName(file.getOriginalFilename());//文件名
        fileMetadata.setOperator("会飞的鱼");//操作人
        // 下面这三个应该是什么?
        fileMetadata.setFileType(null);
        fileMetadata.setFileDisplayName(null);
        fileMetadata.setAssociateObjectClass(null);
        try{
            String id = mongoFileRepo.saveFile(file, comment);
            fileMetadata.setId(id);
            fileMetadataRepo.save(fileMetadata);
            object.put("result","文件上传成功");
        }catch (Exception e){
            object.put("result","文件失败");
        }
        return object.toString();
    }

    /**
     * 文件下载
     * @param id
     * @param response
     * @param request
     * @throws Exception
     */
    @RequestMapping("/downLoad")
    @ResponseBody
    public void downLoad(String id, HttpServletResponse response, HttpServletRequest request) throws Exception{
        mongoFileRepo.getFileById(id,response,request);
    }
}

7.Repo层实现:

package com.example.demo.mongodb.repo;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.mongodb.entity.MongoFileMetaDate;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.MongoDbFactory;
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.Repository;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.time.LocalDateTime;

@Repository
public class MongoFileRepo {
    private final GridFsTemplate fsTemplate;
    private final MongoDbFactory mongoDbFactory;
    public MongoFileRepo(GridFsTemplate fsTemplate,MongoDbFactory mongoDbFactory) {
        this.fsTemplate = fsTemplate;
        this.mongoDbFactory = mongoDbFactory;
    }
    /**
     * 向MongoDB中保存一个文件,返回其ID
     */
    public String saveFile(InputStream inputStream, MongoFileMetaDate metaDate) {
        ObjectId objectId = fsTemplate.store(inputStream, metaDate.getFileName(), metaDate);
        return objectId.toString();
    }
    /**
     * 向MongoDB中保存一个文件,返回其ID
     */
    public String saveFile(MultipartFile file, String comment) {
        JSONObject object=new JSONObject();
        try (InputStream inputStream = file.getInputStream()) {
            MongoFileMetaDate metaDate = new MongoFileMetaDate();
            metaDate.setFileName(file.getOriginalFilename());
            metaDate.setComment(comment);
            metaDate.setRelatedOrgId("");
            metaDate.setUploadTime(LocalDateTime.now());
            metaDate.setUploadUser("");
          return saveFile(inputStream, metaDate);
        } catch (Exception e) {
            object.put("fail","上传失败!");
            return object.toString();
        }
    }

    /**
     * 通过上传时生成的id来下载文件
     * @param id
     * @param response
     * @param request
     * @throws Exception
     */
    public void getFileById(String id, HttpServletResponse response, HttpServletRequest request) throws Exception {
        System.out.println("Finding by ID: " + id);
        GridFSFile fsFile = fsTemplate.findOne(new Query(Criteria
                .where("_id").is(new ObjectId(id))));
        //打开下载流对象
        MongoDatabase db = mongoDbFactory.getDb();
        GridFSBucket gridFSBucket = GridFSBuckets.create(db);
        GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(fsFile.getObjectId());
        //创建GridFsResource用于获取流对象
        GridFsResource resource = new GridFsResource(fsFile, gridFSDownloadStream);
        String fileName = fsFile.getFilename().replace(",", "");
        //处理中文文件名乱码
        if (request.getHeader("User-Agent").toUpperCase().contains("MSIE") ||
                request.getHeader("User-Agent").toUpperCase().contains("TRIDENT")
                || request.getHeader("User-Agent").toUpperCase().contains("EDGE")) {
            fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
        } else {
            //非IE浏览器的处理:
            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
        }
        // 通知浏览器进行文件下载
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        IOUtils.copy(resource.getInputStream(), response.getOutputStream());
    }
}

总结:本文只写了两个接口,可以用postman进行上传测试,下载的话直接在浏览器输入地址即可:http://127.0.0.1:8080/uploadFiles/downLoad?id=5e09c46d08a8862e7cd682a7
本次分享就到这里,如有纰漏,敬请指正。

你可能感兴趣的:(SpringBoot)