关于java:模板文件云存储管理-Sisyphus

5次阅读

共计 5746 个字符,预计需要花费 15 分钟才能阅读完成。

模板文件云存储管理 Sisyphus 通过 easyExcel 实现模板文件的上传和下载,OSS 云存储平台存储模板文件,对应的文件名存储在 DUCC 配置核心,技术架构如下图所示。

外围逻辑

技术组件

EasyExcel

简介

EasyExcel 是一个基于 Java 的简略、省内存的读写 Excel 的阿里巴巴开源我的项目。在尽可能节约内存的状况下反对读写百 M 的 Excel,Github:https://github.com/alibaba/easyexcelhttps://github.com/liurenjin/easypoi

更少的内存占用

easyExcel 能大大减少占用内存的次要起因是在解析 Excel 时没有将文件数据一次性全副加载到内存中,而是从磁盘上一行行读取数据,一一解析。通过一行一行的解析模式,并将一行的解析后果以观察者的模式告诉解决(AnalysisEventListener)。

底层源码

简略应用

实体类

@Data
public class Hero {@ExcelProperty(value={"第一列"})
    private int id;
    @ExcelProperty(value={"第二列"})
    private String name;

}

监听类 HeroListener

public class HeroListener extends AnalysisEventListener<Hero> {Logger logger = LoggerFactory.getLogger(HeroListener.class);

    // 每次读取 100 条数据就进行保留操作
    private static final int BATCH_COUNT = 100;
    // 因为每次读都是新 new UserInfoDataListener 的,所以这个 list 不会存在线程平安问题
    List<Hero> list = new ArrayList<>();

    // 这个组件是 Spring 中的组件,这边举荐两种办法注入这个组件
    // 第一种就是提供一个 UserInfoDataListener 的构造方法,这个办法提供一个参数是 UserInfoDataListener 类型
    // 另外一种办法就是将 UserInfoDataListener 这个类定义成 UserService 实现类的外部类(举荐这种形式)//private UserService userService;

    @Override
    public void invoke(Hero data, AnalysisContext analysisContext) {logger.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
        if (list.size() >= BATCH_COUNT) {saveData();
            // 存储实现清理 list
            list.clear();}
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 这里也要保留数据,确保最初遗留的数据也存储到数据库
        saveData();
        logger.info("所有数据解析实现!");
    }

    private void saveData() {logger.info("{}条数据,开始存储数据库!", list.size());
        // 保留数据
        //userService.save(list);
        logger.info("存储数据库胜利!");
    }
}

Service 层
下载一个 excel

    @Override
    public void testExcelDownload(HttpServletResponse response) {
        try {List<Hero> stuInfo = this.heroDao.getAllHeroInfo();
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("测试", "UTF-8");
//            String fileName = "测试";
            response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
            EasyExcel.write(response.getOutputStream(),Hero.class)
                    .sheet("第一个 sheet")
                    .doWrite(stuInfo);;

        } catch (Exception e) {logger.error("testExcelDownload error", e);
            e.printStackTrace();}

    }

对象存储 OSS

简介

OSS 是一个分布式的对象存储服务,提供的是一个 Key-Value 对模式的对象存储服务。用户能够依据 Object 的名称(Key)惟一的获取该 Object 的内容。相干的名词介绍如下:
Bucket
Bucket 是一个用户用来管理所存储 Object 的存储空间。每个用户能够领有多个 Bucket。Bucket 的名称在 OSS 的范畴内必须是全局惟一的,一旦创立之后无奈批改名称。Bucket 外部的 Object 数目是没有限度的。

Bucket 对于用户来说是一个治理 Object 的单元,所有的 Object 都必须隶属于某个 Bucket。Bucket 有一些属性用来管制 Region、Object 的访问控制、Object 的生命周期等,这些属性是作用在该 Bucket 下所有的 Object 上的,因而用户能够灵便创立不同的 Bucket 来实现不同的治理性能。

同一个 Bucket 外部的空间是扁平的,即没有文件系统的目录等概念,所有的 Object 都是间接隶属于其对应的 Bucket。

Object
Object 是 OSS 存储数据的根本单元,称为 OSS 的对象,也被称为 OSS 的文件。在本文中,Object,对象,文件指的都是同一个意思。Object 由元信息(Object Meta),用户数据(Data)和文件名(Key)组成。Object 由一个在 Bucket 外部惟一的 Key 来标示。Object Meta 信息是一个键值对,示意了 Object 的一些属性,比方最初批改工夫、大小等信息,同时用户也能够存储一些自定义的信息在 Object Meta 信息中。
Object 在整个存储的生命周期内都是不可变的。一个 Object 的生命周期是从上传胜利到被删除为止。反复上传同名的 Object 会导致老的 Object 被删除而后新的 Object 取而代之。因而在 OSS 中,不反对相似文件系统的批改局部内容等操作。

AccessKey
AccessKey,简称 AK,指的是拜访身份验证中用到的 AccessKeyId 和 AccessKeySecret。OSS 通过应用 AccessKeyId 和 AccessKeySecret 对称加密的办法来验证某个申请的发送者身份。AccessKeyId 用于标示用户,AccessKeySecret 是用户用于加密签名字符串和 OSS 用来验证签名字符串的密钥,其中 AccessKeySecret 必须窃密。

  • Bucket 的拥有者申请的 AccessKey。
  • 被 Bucket 的拥有者通过 RAM 受权第三方请求者的 AccessKey。
  • 被 Bucket 的拥有者通过 STS 受权第三方请求者的 AccessKey。

Region 示意 OSS 的数据中心所在的区域,物理地位。Endpoint 示意 OSS 对外服务的拜访域名。

   从设计层面来说,将 OSS 映射为文件系统是十分低效的,也是不倡议的做法。如果肯定要挂载成文件系统的话,也尽量只做写新文件、删除文件、读取文件这几种操作。应用 OSS 应该充分发挥其长处,即海量数据处理能力,优先用来存储海量的非结构化数据,比方图片、视频、文档等。

OSS 常见操作

创立 Bucket
在上传文件(Object)到 OSS 之前,您须要创立一个用于存储文件的 Bucket。Bucket 具备各种配置属性,包含地区、拜访权限以及其余元数据。

上传文件
Bucket 创立实现后,能够通过多种形式上传不同大小的文件。

下载文件
文件上传实现后,能够将文件下载至浏览器默认门路或本地指定门路。

列举文件
当 Bucket 内存储了大量的文件后,能够抉择列举 Bucket 内的全副或局部文件。

删除文件
当不再须要保留上传的文件时,能够手动删除单个或多个文件,也能够通过配置生命周期规定主动删除单个或多个文件。

DUCC 配置核心

简介

DUCC 为京东的一款配置核心产品,是在原来 UCC 的根底上降级的新一代配置核心,相似与 apollo。采纳长轮询拉取 & 定时拉取,绝对的开源配置核心有 spring-cloud-config、diamond、disconf 和 apollo
https://github.com/spring-cloud/spring-cloud-config
https://github.com/takeseem/diamond
https://github.com/knightliao/disconf
https://github.com/ctripcorp/apollo/
DUCC 的操作形式:

  1. 平台上,首先创立本人的利用,而后在对应命名空间 - 配置环境 - 工作区新建对应的键值型配置参数,最初公布即可。
  2. 工程中,配置对应的 DUCC 资源管理器,增加 ducc 平台连贯信息,具体应用时,通过 key 获取配置。

特点

  • 反对多环境(或称分组),分组能够合并
  • 内置弱小的基于插件的数据绑定框架,反对多种类型等转换;
  • 反对 Log4j、Log4j2、Logback 的动静批改日记级别性能。
  • 反对 Spring 原生注解、反对自定义注解, 客户端代码入侵性低
  • 反对客户端多配置源,反对自定义配置,如 ZK、Consol 扩大
  • 反对配置预案切换

局部代码剖析

继续更新欠缺中
Pojo 和 PojoExcel 实体类

public class Pojo {
}

public class PojoExcel {}

PojoListener 监听类

public class PojoListener extends AnalysisEventListener<PojoExcel> {private static final Logger LOGGER = LoggerFactory.getLogger(PojoListener.class);

    private List<PojoExcel>  dataList;

    public PojoListener() {}

    public PojoListener(List<PojoExcel> dataList) {this.dataList = dataList;}

    @Override
    public void invoke(PojoExcel data, AnalysisContext analysisContext) {LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
        dataList.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {LOGGER.info("所有数据解析实现!");
    }
}

pojoExcelUtil 文件工具类

public static void writePojoExcel(List<PojoExcel> excelList, HttpServletResponse response, InputStream inputStream) throws Exception{EasyExcel.write(response.getOutputStream()).withTemplate(inputStream).autoCloseStream(Boolean.TRUE).sheet().doFill(excelList);
}


public static List<PojoExcel> readPojoExcel(InputStream in){List<PojoExcel> dataList = new ArrayList<>();
    PojoListener listener =  new PojoListener(dataList);
    EasyExcel.read(in,PojoExcel.class, listener).sheet("上传落地页").doRead();
    return dataList;
}

Service 层逻辑

// 读取文件
List<KolTaskAccountHrefExcel> dataList = pojoExcelUtil.readPojoExcel(file.getInputStream());

// 写出文件
String filename = duccResourceManager.getConfigValue(DuccConstant.POJO_FILENAME);// 通过 DUCC 获取文件名
pojoExcelUtil.writePojoExcel(dataList, response, pojoOssService.getExcelFileFromOss("模板文件.xlsx"));
// 获取 OSS 文件
@Override
public InputStream getExcelFileFromOss(String fileName) {StorageObject Object = jingdongStorageService.bucket(excelBucketName).object(fileName).get();
    if (storageObject == null) {return null;}
    return storageObject.getInputStream();}


//<property name="excelBucketName" value="${jss.bucketName.excel}"/>
//jss.bucketName.excel=OSS 零碎中文件寄存地位
正文完
 0