问题
背景介绍
前后端分离框架中,前端在发起Ajax请求时,在Header携带Token值,后端获取该Token进行权限校验。
问题描述
在下载文件的场景,大部分浏览器是不支持Ajax请求文件下载,所以通常做法是直接请求下载地址,这时候是无法通过代码设置Header的参数,也就是无法知道当前用户信息,如何进行权限控制?
解决方案
该问题的痛点是数据权限问题。
初步思路
- 在用户要下载的时候,先进行权限校验
- 权限不足时,进行信息提示
- 权限足够时,则为用户生成一次性的下载链接(下载一次后失效,保证数据安全)
设计思路
- 流程设计
- 抽象功能
- 具体实现
流程设计
业务模块前端:业务模块的前端代码,例如用户信息下载的前端代码。
业务服务后端:业务模块的后端代码(非介绍重点,所以不做细节区分)。
文件服务类:文件服务的业务类,主要是处理业务逻辑,例如:生成下载地址的唯一编号,以及唯一编号映射的参数信息,文件生成。
文件控制类:提供统一的下载地址格式,放开权限。
代码设计
基于框架考虑,以下功能抽象出来:
- 持久化数据功能抽象(不同项目的具体情况不同)
- 生成文件功能抽象(因为不同业务生成文件的步骤是不一样的)
代码依赖关系
核心代码
DownloadController - 文件下载控制器,不做权限控制
package com.accloud.core.file.download.controller;
import com.accloud.core.file.download.FileResult;
import com.accloud.core.file.download.service.DownloadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
/**
* 文件下载控制器
*
* @author guoyu.huang
* @since 2020-10-16
*/
@Slf4j
@Controller
@RequestMapping("/download")
public class DownloadController {
@Autowired
private DownloadService downloadService;
&