前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >文件上传和下载

文件上传和下载

作者头像
码农王同学
发布2020-03-25 10:56:50
1K0
发布2020-03-25 10:56:50
举报
文章被收录于专栏:后端Coder后端Coder

进行javaWeb项目的开发,文件上传和下载还是被比较普遍的使用到一种技术,之前都是使用专用的文件服务器进行文件的存储,今天要介绍的是基于mongodb数据库进行文件的存储。

首先,我们基于springboot进行web框架的搭建,简单快速,先看下pom文件的内容。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wpw</groupId>
    <artifactId>springboot-mongo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-mongo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-commons</artifactId>
            <version>1.5.2</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

上面的pom文件也仅仅需要依赖mongodb和web的starter就可以了,使用web的starter就是快速搭建一个web项目。

接下来,需要配置一下文件上传和下载所用到的mongo配置,使其装载到spring容器。

package com.wpw.springbootmongo;

import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;

/**
 * @author pc
 */
@Configuration
public class MongoConf {
    private final MongoDbFactory mongoDbFactory;


    public MongoConf(MongoDbFactory mongoDbFactory) {
        this.mongoDbFactory = mongoDbFactory;
    }

    @Bean
    public GridFSBucket getGridFSBucket() {
        MongoDatabase db = mongoDbFactory.getDb();
        return GridFSBuckets.create(db);
    }
}

java这门语言就是基于面向对象的思想实现,这里将文件返回的结果定义一个类,然后对文件的结果信息和状态码信息进行封装。

package com.wpw.springbootmongo;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bson.types.ObjectId;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@Builder
public class FileResult {
    private Boolean flag;
    private Object fileId;

    /**
     * 组装文件成功时的返回结果
     *
     * @param fileId 文件id
     * @param flag   是否成功的标识
     * @return 文件返回的结果
     */
    public static FileResult fileResultSuccess(ObjectId fileId, Boolean flag) {
        return new FileResult().setFileId(fileId).setFlag(flag);
    }

    /**
     * 获取文件
     *
     * @param fileId 文件id
     * @param flag   是否成功的标识
     * @return 文件返回的结果
     */
    public static FileResult fileResultFail(String fileId, Boolean flag) {
        return new FileResult().setFileId(fileId).setFlag(flag);
    }
}

在resources文件夹下面建立application.yaml文件,然后配置自己的mongodb服务器连接地址。

spring:
  data:
    mongodb:
      database: test
      uri: mongodb://自己mongodb服务器地址
      port: 27017

上面用到的文件上传和下载的基本配置就结束了,下面为了演示仅书写了一个示例程序进行文件的上传和下载的实现。

package com.wpw.springbootmongo;

import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import lombok.extern.slf4j.Slf4j;
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.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.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Objects;

/**
 * @author pc
 */
@RestController
@Slf4j
@RequestMapping(value = "/file")
public class FileController {
    private final GridFsTemplate gridFsTemplate;

    private final GridFSBucket gridFSBucket;

    public FileController(GridFsTemplate gridFsTemplate, GridFSBucket gridFSBucket) {
        this.gridFsTemplate = gridFsTemplate;
        this.gridFSBucket = gridFSBucket;
    }

    @PostMapping(value = "/upload")
    public FileResult uploadFile(@RequestParam
                                         (value = "file") MultipartFile file) {
        log.info("文件名称:{}", file.getOriginalFilename());
        try {
            InputStream inputStream = file.getInputStream();
            log.info("文件类型:{}", file.getContentType());
            log.info("将文件存储到mongodb中");
            ObjectId objectId = gridFsTemplate.store(inputStream, file.getOriginalFilename(), file.getContentType());
            System.out.println("objectId = " + objectId);
            return FileResult.fileResultSuccess(objectId, true);
        } catch (IOException e) {
            log.error("文件流异常:{}", e);
        }
        return null;
    }

    @RequestMapping(value = "/download", method = {RequestMethod.GET, RequestMethod.POST})
    public void downloadFile(@RequestParam(name = "file_id") String fileId,
                             HttpServletResponse response) throws IOException {
        log.info("准备下载文件....");
        Query query = Query.query(Criteria.where("_id").is(fileId));
        GridFSFile gridFSFile = gridFsTemplate.findOne(query);
        if (Objects.isNull(gridFSFile)) {
            return;
        }

        String fileName = gridFSFile.getFilename().replace(",", "");
        String contentType = gridFSFile.getMetadata().get("_contentType").toString();

        // 通知浏览器进行文件下载
        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
        GridFsResource resource = new GridFsResource(gridFSFile, gridFSDownloadStream);

        OutputStream outputStream = response.getOutputStream();
        InputStream inputStream = resource.getInputStream();
        IOUtils.copy(inputStream, outputStream);
        outputStream.flush();
        outputStream.close();
        inputStream.close();
    }
}

我们启动一下我们的项目程序,然后使用postman测试工具将自己的文件上传到mongodb服务器,然后得到上传之后的文件id,先暂时记录文件id,后面会用到。

文本在浏览器上输入ip+端口/download?file_id= ,就可以将上传的文件下载到本地了,由于现在都是前后端分离的模式,仅仅将下载的路由地址和文件上传服务器返回的地址给到前端开发就可以了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农王同学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档