57:第五章:开发admin管理服务:10:开发【从MongoDB的GridFS中,获取文件,接口】;(从GridFS中,获取文件的SOP)(不使用MongoDB的服务,可以排除其自动加载类)

说明:

(1)本篇博客开发内容:开发【从MongoDB的GridFS中,获取文件,接口】;

目录

一:本篇博客合理性说明;

二:开发【从MongoDB的GridFS中,获取文件,接口】;

1.在【api】接口工程中的FileUploaderControllerApi接口中,定义【从MongoDB的GridFS中,获取文件,接口】;

2.在【files】文件服务的FileUploaderController类中,去实现【从MongoDB的GridFS中,获取文件,接口】;

三:一个问题:在启动【admin】管理服务和【user】用户服务的时候,报了"com.mongodb.MongoSocketOpenException: Exception opening socket";(解决办法,在【admin】和【user】启动时,在自动装配时,排除MongoDB即可)

四:【从MongoDB的GridFS中,获取文件】需要管理员登录,才能操作;(在InterceptorConfig中,把"AdminTokenInterceptor"拦截器,也作用到该接口上)

五:效果;

六:一个前端的问题:"cookie中的信息是否放在请求中"时,后端如何准确的判断"用户的登录状态"(这个问题,是可以泛化的)

1.问题描述; 

2.补救策略;

(1)在【api】接口工程中,创建AdminCookieTokenInterceptor拦截器;

(2)使用;(存在疑问……待完善)


一:本篇博客合理性说明;

本篇博客,就是开发从GridFS中,获取文件;

即:


二:开发【从MongoDB的GridFS中,获取文件,接口】;

1.在【api】接口工程中的FileUploaderControllerApi接口中,定义【从MongoDB的GridFS中,获取文件,接口】;

    /**
     * 【从MongoDB的GridFS中,获取文件】
     * @param faceId
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @GetMapping("/readInGridFS") //设置路由,这个是需要前后端约定好的;
    public void readInGridFS(@RequestParam String faceId,
                                        HttpServletRequest request,
                                        HttpServletResponse response) throws Exception;

说明:

(1)改接口的请求方式、url、参数,都不是瞎写的,前后端需要保持一致; 

(2)这个接口不需要返回值;其主要作用是,从GridFS中读取文件,把文件放到Response中即可;

2.在【files】文件服务的FileUploaderController类中,去实现【从MongoDB的GridFS中,获取文件,接口】;

    /**
     * 【从MongoDB的GridFS中,获取文件,接口】
     * @param faceId
     * @return
     * @throws Exception
     */
    @Override
    public void readInGridFS(String faceId,
                                        HttpServletRequest request,
                                        HttpServletResponse response) throws Exception {

        // 0.如果前端传过来的FaceId是空,或者是"null";直接抛一个"你所查看的文件不存在!"的自定义的MyCustomException异常;
        if (StringUtils.isBlank(faceId) || faceId.equalsIgnoreCase("null")) {
            GraceException.display(ResponseStatusEnum.FILE_NOT_EXIST_ERROR);
        }

        // 1. 从GridFS中读取文件;
        File file = readGridFSByFaceId(faceId);

        // 2. 把文件放到response中;
        FileUtils.downloadFileByStream(response, file);
    }

    /**
     * 工具方法:【通过id,从GridFS中,获取文件】→【保存到服务器本地】→【返回该文件,在本地服务器的file对象】
     * @param faceId
     * @return
     */
    private File readGridFSByFaceId(String faceId) throws Exception {
        /**
         * 1.通过gridFSBucket.find()方法,从GridFS中,查询文件;
         * 第一个参数"_id"表示,我们此次查询,是根据id查询;
         * 第二个参数是,我们具体此次查询的id号;
         * PS:这个查询结果可能包含多个结果(比如我们根据其他条件查询的时候,结果可能有多个),而且其是可以进行循环的;
         */
        GridFSFindIterable gridFSFindIterable = gridFSBucket.find(Filters.eq("_id", new ObjectId(faceId)));

        // 2. 获取查询到的单个文件的对象;因为,我们心里清楚,上面根据id去查询,最多只能查到一个;所以,可以直接只看查到结果的第一个;
        GridFSFile gridFSFile = gridFSFindIterable.first();

        // 3. 如果查询的结果为空,直接抛一个"你所查看的文件不存在!"的自定义的MyCustomException异常;
        if (gridFSFile == null) {
            GraceException.display(ResponseStatusEnum.FILE_NOT_EXIST_ERROR);
        }

        // 4.获得文件名;
        String fileName = gridFSFile.getFilename();

        // 5.把文件保存到服务器本地;
        // 5.1 创建服务器本地保存图片文件的文件夹
        File fileTemp = new File("e:/temp_face");
        if (!fileTemp.exists()) { //如果上面的路径不存在,就去创建;
            fileTemp.mkdirs();
        }
        // 5.2 获得文件流
        File myFile = new File("e:/temp_face/" + fileName);
        // 5.3 创建文件输出流
        OutputStream os = new FileOutputStream(myFile);//这个会报FileNotFoundException异常;
        /**
         * 5.4 利用gridFSBucket.downloadToStream()方法,把文件保存到服务器本地;
         * 第一个参数:文件保存到本地的名称;我们这儿以"文件在GridFS中的id",作为"文件保存到本地的名称";
         * 第二个参数:文件是输出流;
         */
        gridFSBucket.downloadToStream(new ObjectId(faceId), os);//downloadToStream()方法有其他的重构方式,利用其他的重构的方法也是可以的;
        // 6. 返回该文件,在本地服务器的file对象;
        return myFile;
    }

说明:

(1)首先,判断前端传过来的FaceId是空,或者是"null";

(2)然后,调用编写的工具方法readGridFSByFaceId(faceId),从GridFS中,获取文件;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值