Spring Boot 实现读取本地资源(图片,视频,JSON)并在线预览

前言

最近遇到一个需求,
需要对静态资源(非项目内,由摄像头生成一些文件,以及用户的人脸识别入库文件等)  
做鉴权处理,这样一来原本直接将静态资源放在Nginx的方案就不再可用了,需要在Java端做处理
  • 简单说下思路, 流程大致是下图这样
已登录
未登录
图片查看权限
视频查看权限
JSON查看权限
请求接口
是否登录
鉴权
结束
图片
视频流
JSON

首先是 Controller


import com.hitotek.htvistion.util.io.StreamManager;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 4everlynn
 * @version V1.0
 * @description 静态资源鉴权后返回
 * @date 2019/2/19
 */
@RestController
@RequestMapping(value = "/store", produces = {"application/octet-stream"})
public class ResourceController {

    @Autowired
    private StreamManager streamManager;

    /**
     * 返回图片流
     *
     * @param fileName 图片名
     */
    @GetMapping(value = "/image/{fileName}")
    @RequiresRoles("user")
    public ResponseEntity<FileSystemResource> viewImage(@PathVariable String fileName) {
        return streamManager.getImage(fileName);
    }

    /**
     * 返回视频流
     *
     * @param fileName 视频文件名
     */
    @GetMapping("/video/{fileName}")
    @RequiresRoles("user")
    public ResponseEntity<FileSystemResource> viewVideo(@PathVariable String fileName) {
        return streamManager.getVideo(fileName);
    }

    /**
     * 返回json文件(与视频文件名相同)
     *
     * @param fileName 视频文件名.json
     */
    @GetMapping(value = "/json/{fileName}", produces = "application/json")
    @RequiresRoles("user")
    public ResponseEntity<FileSystemResource> viewJson(@PathVariable String fileName) {
        return streamManager.getJson(fileName);
    }
}

然后是自己实现的一个工具类(抽象层)

package com.hitotek.htvistion.util.io;

import com.hitotek.htvistion.constant.EnvironmentConstant;
import com.hitotek.htvistion.util.Strings;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.ResponseEntity;

import java.io.File;

/**
 * @author 4everlynn
 * @version V1.0
 * @description
 * @date 2019/2/19
 */
@Slf4j
@Data
public abstract class AbstractStreamManager {
    private File imageStoreRoot;
    private File videoStoreRoot;

    public AbstractStreamManager() {
        // 初始化存储仓库 传入静态资源仓库的硬盘上的绝对路径
        // 此处也是一个绝对路径
        this.initialize(EnvironmentConstant.store());
    }

    /**
     * 获取图片流
     *
     * @param fileName 图片文件名
     * @return 图片
     */
    public abstract ResponseEntity<FileSystemResource> getImage(String fileName);

    /**
     * 获取视频流
     *
     * @param fileName 视频文件名
     * @return 视频流
     */
    public abstract ResponseEntity<FileSystemResource> getVideo(String fileName);

    /**
     * 获取视频骨架JSON
     *
     * @param fileName 视频文件名
     * @return JSON
     */
    public abstract ResponseEntity<FileSystemResource> getJson(String fileName);


    ResponseEntity<FileSystemResource> getFile(String fileName) {
        File targetFile = new File(fileName);
        // 文件存在才进行操作
        if (targetFile.exists()) {
            return ResponseEntity
                    .ok(new FileSystemResource(targetFile));
        }
        return ResponseEntity.notFound().build();
    }

    /**
     * 初始化存储仓库
     *
     * @param store 仓库路径
     */
    private void initialize(String store) {
        // 检测路径是否存在, 如果没有则创建
        if (!Strings.isNullOrEmpty(store)) {
            File file = new File(store);
            if (!file.exists()) {
                //noinspection ResultOfMethodCallIgnored
                file.mkdirs();
            }
            // 图片存储路径
            File imageStore = new File(store + File.separator + EnvironmentConstant.imageDir());
            // 视频存储路径
            File videoStore = new File(store + File.separator + EnvironmentConstant.videoDir());
            // 检测图片存储路径是否存在, 没有则创建
            if (!imageStore.exists()) {
                //noinspection ResultOfMethodCallIgnored
                imageStore.mkdir();
            }

            if (!videoStore.exists()) {
                //noinspection ResultOfMethodCallIgnored
                videoStore.mkdir();
            }
            // 缓存视频、图片存储路径
            this.videoStoreRoot = videoStore;
            this.imageStoreRoot = imageStore;
        }
        log.info("streamManager initialized with " + store);
    }
}

工具类(实现层层)

package com.hitotek.htvistion.util.io;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * @author Qicheng Peng
 * @version V1.0
 * @description
 * @date 2019/2/19
 */

@Component
@Slf4j
public class StreamManager extends AbstractStreamManager {
    /**
     * @param fileName 图片文件名
     * @return
     */
    @Override
    public ResponseEntity<FileSystemResource> getImage(String fileName) {
        return getFile(getImageStoreRoot().getAbsolutePath() + File.separator + fileName);
    }

    /**
     * @param fileName 视频文件名
     * @return
     */
    @Override
    public ResponseEntity<FileSystemResource> getVideo(String fileName) {
        return getFile(getVideoStoreRoot().getAbsolutePath() + File.separator + fileName);
    }

    /**
     * @param fileName 视频文件名
     * @return
     */
    @Override
    public ResponseEntity<FileSystemResource> getJson(String fileName) {
        return getVideo(fileName);
    }
}

你可能感兴趣的:(Java)