前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 快速开发框架 magic-api

Java 快速开发框架 magic-api

作者头像
默存
发布2024-01-04 15:10:08
4180
发布2024-01-04 15:10:08
举报
文章被收录于专栏:默存

magic-api

一个基于 Java 的接口快速开发框架,通过 magic-api 提供的 UI 界面完成编写接口,无需定义 ControllerServiceDaoMapperXMLVO 等 Java 对象即可完成常见的 HTTP API 接口开发。

官网地址:https://www.ssssssss.org/magic-api

官方在线演示:https://magic-api.ssssssss.org

官方示例项目:https://gitee.com/ssssssss-team/magic-api-example

特性

  • • 支持 MySQL、MariaDB、Oracle、DB2、PostgreSQL、SQLServer 等支持jdbc规范的数据库
  • • 支持非关系型数据库Redis、Mongodb
  • • 支持集群部署、接口自动同步。
  • • 支持分页查询以及自定义分页查询
  • • 支持多数据源配置,支持在线配置数据源
  • • 支持SQL缓存,以及自定义SQL缓存
  • • 支持自定义JSON结果、自定义分页结果
  • • 支持对接口权限配置、拦截器等功能
  • • 支持运行时动态修改数据源
  • • 支持Swagger接口文档生成
  • • 基于magic-script脚本引擎,动态编译,无需重启,实时发布
  • • 支持Linq式查询,关联、转换更简单
  • • 支持数据库事务、SQL支持拼接,占位符,判断等语法
  • • 支持文件上传、下载、输出图片
  • • 支持脚本历史版本对比与恢复
  • • 支持脚本代码自动提示、参数提示、悬浮提示、错误提示
  • • 支持导入Spring中的Bean、Java中的类
  • • 支持在线调试
  • • 支持自定义工具类、自定义模块包、自定义类型扩展、自定义方言、自定义列名转换等自定义操作

使用示例

添加依赖

新建 SpringBoot 项目,添加相关依赖:

代码语言:javascript
复制
<properties>
    <java.version>1.8</java.version>
    <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-boot.version>2.7.15</spring-boot.version>

    <magic-api.version>2.1.1</magic-api.version>
    <druid-spring-boot.varsion>1.2.6</druid-spring-boot.varsion>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.ssssssss</groupId>
        <artifactId>magic-api-spring-boot-starter</artifactId>
        <version>${magic-api.version}</version>
    </dependency>

    <dependency>
        <groupId>org.ssssssss</groupId>
        <artifactId>magic-api-plugin-task</artifactId>
        <version>${magic-api.version}</version>
    </dependency>

    <dependency>
        <groupId>org.ssssssss</groupId>
        <artifactId>magic-api-plugin-component</artifactId>
        <version>${magic-api.version}</version>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>${druid-spring-boot.varsion}</version>
    </dependency>
</dependencies>

配置文件

代码语言:javascript
复制
server:
  port: 8080

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/demo?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&autoReconnect=true
    username: root
    password: 123456
    initialSize: 10
    minIdle: 10
    maxActive: 100
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 300000
    minEvictableIdleTimeMillis: 3600000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20

magic-api:
  web: /api/web
  show-sql: true #配置打印SQL
  sql-column-case: camel
  security:
    username: admin # 登录用的用户名
    password: admin@123 # 登录用的密码
  support-cross-domain: true # 跨域支持,默认开启
  resource:
    type: database  # 配置接口存储方式,这里选择存在数据库中
    table-name: magic_api_file  # 数据库中的表名
    prefix: /  # 前缀
#    location: data/magic-api
  page:
    page: current
    size: size
  cache:
    enable: true  #开启缓存,默认是不开启的
    ttl: 3600000 #有效期1小时,默认-1 即永不过期
  response-code:
    success: 200 #执行成功的code值
    invalid: 400 #参数验证未通过的code值
    exception: 500 #执行出现异常的code值

详细配置见文档:https://www.ssssssss.org/magic-api/pages/config/spring-boot/#%E5%AE%8C%E6%95%B4%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B

统一请求响应配置

代码语言:javascript
复制
package com.demo.config;

import com.demo.base.WrapMapper;
import org.springframework.stereotype.Component;
import org.ssssssss.magicapi.core.context.RequestEntity;
import org.ssssssss.magicapi.core.interceptor.ResultProvider;
import org.ssssssss.magicapi.modules.db.model.Page;

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

/**
 * @ClassName: MagicAPIJsonConfig.java
 * @Description: 统一请求响应配置
 * @Author: tanyp
 **/
@Component
public class MagicAPIJsonConfig implements ResultProvider {

    /**
     * @MonthName: buildResult
     * @Description: 定义返回结果,默认返回JsonBean
     * @Author: tanyp
     * @Param: [requestEntity, i, s, o]
     * @return: java.lang.Object
     **/
    @Override
    public Object buildResult(RequestEntity requestEntity, int code, String message, Object data) {
        return WrapMapper.wrap(code, message, data);
    }

    /**
     * @MonthName: buildPageResult
     * @Description: 定义分页返回结果
     * @Author: tanyp
     * @Param: [requestEntity, page, total, data]
     * @return: java.lang.Object
     **/
    @Override
    public Object buildPageResult(RequestEntity requestEntity, Page page, long total, List<Map<String, Object>> data) {
        return new HashMap<String, Object>() {
            {
                put("total", total);
                put("pages", page.getOffset());
                put("size", page.getLimit());
                put("records", data);
            }
        };
    }
}

定义返回结果实体类

代码语言:javascript
复制
package com.demo.base;

import java.util.Objects;

/**
 * @ClassName: WrapMapper.java
 * @Description: 返回包装类
 * @Author: tanyp
 **/
public class WrapMapper {

    private WrapMapper() {
    }

    public static <E> Wrapper<E> wrap(int code, String message, E o) {
        return new Wrapper<E>(code, message, o);
    }

    public static <E> Wrapper<E> wrap(int code, String message) {
        return new Wrapper<E>(code, message);
    }

    public static <E> Wrapper<E> wrap(int code) {
        return wrap(code, null);
    }

    public static <E> Wrapper<E> wrap(Exception e) {
        return new Wrapper<E>(Wrapper.ERROR_CODE, e.getMessage());
    }

    public static <E> E unWrap(Wrapper<E> wrapper) {
        return wrapper.getResult();
    }

    public static <E> Wrapper<E> illegalArgument() {
        return wrap(Wrapper.ILLEGAL_ARGUMENT_CODE_, Wrapper.ILLEGAL_ARGUMENT_MESSAGE);
    }

    public static <E> Wrapper<E> error() {
        return wrap(Wrapper.ERROR_CODE, Wrapper.ERROR_MESSAGE);
    }

    public static <E> Wrapper<E> error(String message) {
        return wrap(Wrapper.ERROR_CODE, Objects.isNull(message) ? Wrapper.ERROR_MESSAGE : message);
    }

    public static <E> Wrapper<E> error(int code, String message) {
        return wrap(code, Objects.isNull(message) ? Wrapper.ERROR_MESSAGE : message);
    }

    public static <E> Wrapper<E> ok() {
        return new Wrapper<E>();
    }

    public static <E> Wrapper<E> wrap(E o) {
        return new Wrapper<>(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, o);
    }

    public static <E> Wrapper<E> ok(E o) {
        return new Wrapper<>(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE, o);
    }

    public static <E> Wrapper<E> success() {
        return new Wrapper<>(Wrapper.SUCCESS_CODE, Wrapper.SUCCESS_MESSAGE);
    }
}
代码语言:javascript
复制
package com.demo.base;

import java.io.Serializable;

/**
 * @ClassName: Wrapper.java
 * @Description: 包装类
 * @Author: tanyp
 **/
public class Wrapper<T> implements Serializable {

    /**
     * 成功码.
     */
    public static final int SUCCESS_CODE = 200;

    /**
     * 成功信息.
     */
    public static final String SUCCESS_MESSAGE = "操作成功";

    /**
     * 错误码.
     */
    public static final int ERROR_CODE = 500;

    /**
     * 错误信息.
     */
    public static final String ERROR_MESSAGE = "系统异常,请稍后重试!";

    /**
     * 错误码:参数非法
     */
    public static final int ILLEGAL_ARGUMENT_CODE_ = 400;

    /**
     * 错误信息:参数非法
     */
    public static final String ILLEGAL_ARGUMENT_MESSAGE = "请求参数非法,请核查!";

    /**
     * 错误码:参数非法
     */
    public static final int AUTHORIZATION_CODE = 402;

    /**
     * 错误信息:参数非法
     */
    public static final String AUTHORIZATION_MESSAGE = "Token has expired";

    /**
     * 编号.
     */
    private int code;

    /**
     * 信息.
     */
    private String message;

    /**
     * 结果数据
     */
    private T result;

    public Wrapper() {
        this(SUCCESS_CODE, SUCCESS_MESSAGE);
    }

    public Wrapper(int code, String message) {
        this.code(code).message(message);
    }

    public Wrapper(int code, String message, T result) {
        super();
        this.code(code).message(message).result(result);
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getResult() {
        return result;
    }

    public void setResult(T result) {
        this.result = result;
    }

    public Wrapper<T> code(int code) {
        this.setCode(code);
        return this;
    }

    public Wrapper<T> message(String message) {
        this.setMessage(message);
        return this;
    }

    public Wrapper<T> result(T result) {
        this.setResult(result);
        return this;
    }

    @Override
    public String toString() {
        return "Wrapper{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", result=" + result +
                '}';
    }

    public boolean isSuccess() {
        return this.getCode() == Wrapper.SUCCESS_CODE;
    }

    public boolean isFail() {
        return !isSuccess();
    }
}

全局异常拦截

代码语言:javascript
复制
package com.demo.extension;

import com.demo.base.WrapMapper;
import com.demo.base.Wrapper;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @ClassName: GlobalException.java
 * @Description: 全局异常拦截
 * @Author: tanyp
 **/
@RestControllerAdvice
public class GlobalException {

    @ExceptionHandler(value = Exception.class)
    public Wrapper handleException(Exception e) {
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
            // 参数校验异常
            return WrapMapper.wrap(Wrapper.ILLEGAL_ARGUMENT_CODE_, "参数有误:" + ex.getBindingResult().getFieldError().getDefaultMessage(), null);
        } else {
            // 统一系统异常
            return WrapMapper.wrap(Wrapper.ERROR_CODE, e.getMessage(), null);
        }
    }
}

初始化数据库

代码语言:javascript
复制
CREATE TABLE `magic_api_file` (
  `file_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `file_content` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
  PRIMARY KEY (`file_path`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='API 表';

CREATE TABLE `magic_backup_record` (
  `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '原对象ID',
  `create_date` bigint NOT NULL COMMENT '备份时间',
  `tag` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '标签',
  `type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '类型',
  `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '原名称',
  `content` blob COMMENT '备份内容',
  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '操作人',
  PRIMARY KEY (`id`,`create_date`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='api 备份';

启动项目

启动成功,日志如下:

代码语言:javascript
复制
2024-01-03 09:44:24.290  INFO 4324 --- [           main] o.s.m.s.b.s.MagicAPIAutoConfiguration    : 注册扩展:class org.ssssssss.magicapi.modules.servlet.ResponseModule -> class org.ssssssss.magicapi.servlet.javaee.MagicJavaEEResponseExtension
  __  __                _           _     ____  ___ 
 |  \/  |  __ _   __ _ (_)  ___    / \   |  _ \|_ _|
 | |\/| | / _` | / _` || | / __|  / _ \  | |_) || | 
 | |  | || (_| || (_| || || (__  / ___ \ |  __/ | | 
 |_|  |_| \__,_| \__, ||_| \___|/_/   \_\|_|   |___|
                  |___/                        2.1.1
集成插件:
- 组件
- 定时任务
2024-01-03 09:44:24.308 ERROR 4324 --- [           main] o.s.m.s.b.s.MagicAPIAutoConfiguration    : 当前备份设置未配置,强烈建议配置备份设置,以免代码丢失。
2024-01-03 09:44:24.338  INFO 4324 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path '/'
2024-01-03 09:44:24.343  INFO 4324 --- [           main] com.ufan.admin.UfanAdminApplication      : Started UfanAdminApplication in 2.158 seconds (JVM running for 2.62)
********************************************当前服务相关地址********************************************
服务启动成功,magic-api已内置启动! Access URLs:
    接口本地地址:   http://localhost:8080/
    接口外部地址:   http://172.16.80.253:8080/
    接口配置平台:   http://172.16.80.253:8080/api/web/index.html
    可通过配置关闭输出:  magic-api.show-url=false
********************************************当前服务相关地址********************************************
2024-01-03 09:44:26.206  INFO 4324 --- [nio-7001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]  : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-01-03 09:44:26.206  INFO 4324 --- [nio-7001-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2024-01-03 09:44:26.206  INFO 4324 --- [nio-7001-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms

访问:http://localhost:8080/api/web/index.html

如图所示:

magic-api 总体来说还是非常方便的,在做一些中小型项目的时候可以轻易的解决问题。

了解更多请看官方文档:https://www.ssssssss.org/magic-api

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • magic-api
  • 特性
  • 使用示例
相关产品与服务
关系型数据库
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档