IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> springboot整合hasor-dataway -> 正文阅读

[Java知识库]springboot整合hasor-dataway

前提:需要两张约定的表,这是dataway需要的

这里基于【mysql】数据库演示,所以在 dataway的依赖 jar 包中选择 “META-INF/hasor-framework/mysql” 目录下的两张表粘贴到自己的数据库下
在这里插入图片描述

CREATE TABLE `interface_info` (
    `api_id`          int(11)      NOT NULL AUTO_INCREMENT   COMMENT 'ID',
    `api_method`      varchar(12)  NOT NULL                  COMMENT 'HttpMethod:GET、PUT、POST',
    `api_path`        varchar(512) NOT NULL                  COMMENT '拦截路径',
    `api_status`      int(2)       NOT NULL                  COMMENT '状态:0草稿,1发布,2有变更,3禁用',
    `api_comment`     varchar(255)     NULL                  COMMENT '注释',
    `api_type`        varchar(24)  NOT NULL                  COMMENT '脚本类型:SQL、DataQL',
    `api_script`      mediumtext   NOT NULL                  COMMENT '查询脚本:xxxxxxx',
    `api_schema`      mediumtext       NULL                  COMMENT '接口的请求/响应数据结构',
    `api_sample`      mediumtext       NULL                  COMMENT '请求/响应/请求头样本数据',
    `api_create_time` datetime     DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `api_gmt_time`    datetime     DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
    PRIMARY KEY (`api_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='Dataway 中的API';

CREATE TABLE `interface_release` (
    `pub_id`          int(11)      NOT NULL AUTO_INCREMENT   COMMENT 'Publish ID',
    `pub_api_id`      int(11)      NOT NULL                  COMMENT '所属API ID',
    `pub_method`      varchar(12)  NOT NULL                  COMMENT 'HttpMethod:GET、PUT、POST',
    `pub_path`        varchar(512) NOT NULL                  COMMENT '拦截路径',
    `pub_status`      int(2)       NOT NULL                  COMMENT '状态:0有效,1无效(可能被下线)',
    `pub_type`        varchar(24)  NOT NULL                  COMMENT '脚本类型:SQL、DataQL',
    `pub_script`      mediumtext   NOT NULL                  COMMENT '查询脚本:xxxxxxx',
    `pub_script_ori`  mediumtext   NOT NULL                  COMMENT '原始查询脚本,仅当类型为SQL时不同',
    `pub_schema`      mediumtext       NULL                  COMMENT '接口的请求/响应数据结构',
    `pub_sample`      mediumtext       NULL                  COMMENT '请求/响应/请求头样本数据',
    `pub_release_time`datetime     DEFAULT CURRENT_TIMESTAMP COMMENT '发布时间(下线不更新)',
    PRIMARY KEY (`pub_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='Dataway API 发布历史。';

create index idx_interface_release on interface_release (pub_api_id);

这里有两种方式,第一种是基于主数据源(跟系统所使用同一个数据库),第二种是独立数据源(跟系统使用不同的数据库,比如系统使用的主数据库,dataway使用从数据库)。
第一种方式可以去【这里】查看。这里演示第二种方式,基于ruoyi-vue项目。

第一步:新增一个maven模块 ruoyi-hasor

在这里插入图片描述

第二步:给这个ruoyi-hasor引入jar

<!-- hasor-dataway -->
<dependency>
    <groupId>net.hasor</groupId>
    <artifactId>hasor-dataway</artifactId>
    <version>${hasor.version}</version>
</dependency>

<!-- hasor-spring -->
<dependency>
    <groupId>net.hasor</groupId>
    <artifactId>hasor-spring</artifactId>
    <version>${hasor.version}</version>
</dependency>

<!-- FunctionX 官方维护的一组基础函数库  -->
<dependency>
    <groupId>net.hasor</groupId>
    <artifactId>hasor-dataql-fx</artifactId>
    <version>${hasor.version}</version>
</dependency>

<!-- 通用工具-->
<dependency>
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi-common</artifactId>
</dependency>

如果 不是用若依框架(没有ruoyi-common模块),那就再把下面的jar引入进去即可:

<!--常用工具类 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>
<!-- JSON工具类 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

<!-- 阿里JSON解析器 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
</dependency>

<!-- io常用工具类 -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
</dependency>
<!-- pool 对象池 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
<!-- druid 连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
</dependency>

第三步:ruoyi-hasor模块新建三个文件夹,并分别新建以下java文件

chain:存放关于dataway日志打印、兼容设置等java文件
config:存放关于dataway组件注册相关java文件
core:存放关于dataway上下文、数据源配置相关java文件
在这里插入图片描述

FxSqlCheckChain:

package com.ruoyi.chain;

import com.ruoyi.common.utils.StringUtils;
import net.hasor.dataql.fx.db.FxSqlCheckChainSpi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 打印sql
 * @author fangmingzheng
 * @date 2022/4/20 15:02
 */
public class FxSqlCheckChain implements FxSqlCheckChainSpi {
    private static final Logger log = LoggerFactory.getLogger(FxSqlCheckChain.class);

    public static FxSqlCheckChain getInstance() {
        return new FxSqlCheckChain();
    }

    @Override
    public int doCheck(FxSqlInfo fxSqlInfo) throws Throwable {
        String sourceName = fxSqlInfo.getSourceName();
        if (StringUtils.isNotEmpty(sourceName)) {
            log.info("【dataway】dataSource ==>:{}", sourceName);
        }
        log.info("【dataway】sql ==>:{}", fxSqlInfo.getQueryString().trim());
        log.info("【dataway】params ==>: {}", fxSqlInfo.getQueryParams());
        return FxSqlCheckChainSpi.NEXT;
    }
}

PreExecuteChain

package com.ruoyi.chain;

import net.hasor.dataway.spi.ApiInfo;
import net.hasor.dataway.spi.PreExecuteChainSpi;
import net.hasor.utils.future.BasicFuture;
import org.apache.commons.collections4.MapUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * dataway 接口执行前
 * @author fangmingzheng
 * @date 2022/4/20 10:07
 */
public class PreExecuteChain implements PreExecuteChainSpi {

    public static PreExecuteChain getInstance() {
        return new PreExecuteChain();
    }

    /**
     * sql 直接前
     * @param apiInfo
     * @param basicFuture
     */
    @Override
    public void preExecute(ApiInfo apiInfo, BasicFuture<Object> basicFuture) {
        Map<String, Object> parameter = apiInfo.getParameterMap();

        // 注入用户权限参数
        parameter.putAll(MapUtils.emptyIfNull(loginUserAuthParams()));
    }


    /**
     * 获取登录用户权限参数
     * @return
     */
    private Map<String, Object> loginUserAuthParams () {
        Map<String, Object> authParams = new HashMap<>();
        // todo 注入登录用户 权限参数
        return authParams;
    }
}

ReturnProcessChain

package com.ruoyi.chain;

import com.ruoyi.common.core.domain.AjaxResult;
import net.hasor.dataway.spi.ApiInfo;
import net.hasor.dataway.spi.ResultProcessChainSpi;

/**
 * 兼容 4.1.5之前 dataway版本
 * dataway 执行结果处理, 让 structure 配置仅使用于dataway页面调试使用
 * @author fangmingzheng
 * @date 2022/4/20 10:14
 */
public class ReturnProcessChain implements ResultProcessChainSpi {

    public static ReturnProcessChain getInstance() {
        return new ReturnProcessChain();
    }


    /**
     * 对返回结果进行处理
     * @param formPre
     * @param apiInfo
     * @param result
     * @return
     */
    @Override
    public Object callAfter(boolean formPre, ApiInfo apiInfo, Object result) {
        // apiInfo.isPerform() 为 true 表示,API 调用是从 UI 界面发起的。
        if (apiInfo.isPerform() || apiInfo.getParameterMap().containsKey("SELF_CALL")) {
            return result;
        }
        apiInfo.getOptionMap().put("resultStructure", false);
        return AjaxResult.success(result);
    }

    /**
     * 异常
     * @param formPre
     * @param apiInfo
     * @param e
     * @return
     */
    @Override
    public Object callError(boolean formPre, ApiInfo apiInfo, Throwable e) {
        if (apiInfo.isPerform()) {
            return ResultProcessChainSpi.super.callError(formPre, apiInfo, e);
        }
        apiInfo.getOptionMap().put("resultStructure", false);
        return AjaxResult.error( "系统繁忙");
    }
}

HasorConfig

package com.ruoyi.config;

import com.ruoyi.core.HasorContextHandle;
import net.hasor.dataway.DatawayService;
import net.hasor.spring.boot.EnableHasor;
import net.hasor.spring.boot.EnableHasorWeb;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description 启动datatway服务
 * @Author fangmingzheng
 * @Date  2022/10/21
 */
@EnableHasor()
@EnableHasorWeb()
@Configuration
public class HasorConfig {

    @Bean
    public DatawayService datawayService() {
        return HasorContextHandle.getInstance(DatawayService.class);
    }
}

HasorContextHandle

package com.ruoyi.core;

import net.hasor.core.AppContext;

/**
 * hasor 上下文
 * @author fangmingzheng
 * @date 2022/4/20 10:14
 */
public class HasorContextHandle {

    private static AppContext appContext;


    public static void setAppContext(AppContext appContext) {
        HasorContextHandle.appContext = appContext;
    }

    public static AppContext getAppContext() {
        return appContext;
    }


    public static <T> T getInstance(Class<T> clazz) {
        return appContext.getInstance(clazz);
    }
}

HasorModule

注意
@Value(“${spring.datasource.druid.slave.url}”)等这里面的路径就是后文中从库的信息,需要改成你自己的

package com.ruoyi.core;


import com.alibaba.druid.pool.DruidDataSource;
import com.ruoyi.chain.FxSqlCheckChain;
import com.ruoyi.chain.PreExecuteChain;
import com.ruoyi.chain.ReturnProcessChain;
import net.hasor.core.ApiBinder;
import net.hasor.core.AppContext;
import net.hasor.core.DimModule;
import net.hasor.dataql.fx.db.FxSqlCheckChainSpi;
import net.hasor.dataway.spi.PreExecuteChainSpi;
import net.hasor.dataway.spi.ResultProcessChainSpi;
import net.hasor.db.JdbcModule;
import net.hasor.db.Level;
import net.hasor.spring.SpringModule;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 注入 spi
 * @author hujin
 * @date 2022/4/20 10:14
 */
@DimModule
@Component
public class HasorModule implements SpringModule {

    @Value("${spring.datasource.druid.slave.url}")
    private String url;
    @Value("${spring.datasource.druid.slave.username}")
    private String username;
    @Value("${spring.datasource.druid.slave.password}")
    private String password;

    /**
     * dataway连接从库
     * @param apiBinder
     * @return void
     * @author fangmingzheng
     * @create 2022/9/6
     **/
    @Override
    public void loadModule(ApiBinder apiBinder) throws Throwable {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        // 用来检测连接是否有效
        dataSource.setValidationQuery("SELECT 1");
        // 借用连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
        dataSource.setTestOnBorrow(false);
        // 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
        dataSource.setTestOnReturn(false);
        // 连接空闲时检测,如果连接空闲时间大于timeBetweenEvictionRunsMillis指定的毫秒,
        // 执行validationQuery指定的SQL来检测连接是否有效
        // 如果检测失败,则连接将被从池中去除
        dataSource.setTestWhileIdle(true);
        dataSource.setTimeBetweenEvictionRunsMillis(60000);//1分钟
        dataSource.setMaxActive(20);
        dataSource.setInitialSize(5);
        // 注入数据源
        apiBinder.installModule(new JdbcModule(Level.Full, dataSource));

        // 日志
        apiBinder.bindSpiListener(FxSqlCheckChainSpi.class, FxSqlCheckChain.getInstance());
        // 数据权限参数
        apiBinder.bindSpiListener(PreExecuteChainSpi.class, PreExecuteChain.getInstance());
        // 返回结果
        apiBinder.bindSpiListener(ResultProcessChainSpi.class, ReturnProcessChain.getInstance());
    }

    /**
     * 注入hasor上下文对象
     * @param appContext
     */
    @Override
    public void onStart(AppContext appContext) {
        HasorContextHandle.setAppContext(appContext);
    }
}

第四步:在启动模块配置文件中添加dataway配置和从库路径

我的启动模块是ruoyi-admin,所以在ruoyi-admin模块下application.yml 或者 application.properties配置文件中添加

# 启用 Dataway 功能(默认不启用)
HASOR_DATAQL_DATAWAY: true
# 开启 ui 管理功能(注意生产环境必须要设置为 false,否则会造成严重的生产安全事故)
HASOR_DATAQL_DATAWAY_ADMIN: true
# (可选)API 工作路径
HASOR_DATAQL_DATAWAY_API_URL: /api/
# (可选)ui 的工作路径,只有开启 ui 管理功能后才有效
HASOR_DATAQL_DATAWAY_UI_URL: /api/interface-ui/

在这里插入图片描述

# 从库数据源
slave:
    # 从数据源开关/默认关闭
    enabled: true
    url: jdbc:mysql://localhost:3306/zsxtool?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: root

在这里插入图片描述

第五步:在启动模块下的pom文件中引入刚才新建的ruoyi-hasor模块

引入之后就能正常启动加载了
我这里的启动模块是ruoyi-admin,所以如果不一样,需要改成你自己的

<!-- dataway模块-->
<dependency>
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi-hasor</artifactId>
</dependency>

在这里插入图片描述

第六步:开放dataway的ui可视化界面的路径权限

前提是上述第四步的界面开关必须打开
就是这两个:
HASOR_DATAQL_DATAWAY: true
HASOR_DATAQL_DATAWAY_ADMIN: true
这一步比较重要!!!

上面第四步中配置的路径:"/api/interface-ui/"需要在权限配置中放开,否则访问不到。我这里使用的若依框架中是在SecurityConfig这个文件中设置路由权限的,你们需要改成你们自己的
在这里插入图片描述

第七步:运行项目

项目路径+datawayui路径,例如:
http://127.0.0.1:9090/api/interface-ui/#/

运行结果

在这里插入图片描述
账号密码应该默认的 admin / admin

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:01:38  更:2022-10-22 21:04:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 4:15:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码