前言

随着软件开发的快速发展和需求的不断增长,开发人员面临着更多的压力和挑战。传统的开发方法需要花费大量的时间和精力,而低代码开发平台的出现为开发人员提供了一种更加高效、快速的开发方式。今天小编就以构建命令插件为例,展示如何使用Java语言高效构建自定义插件。

环境准备

  • 活字格插件构建工具-Java版(forguncyJavaPluginGenerator)
  • 活字格设计器(v10.0版本及以上)
  • IDE编译器(例如IntelliJ IDEA Community Edition)
  • Java运行时环境(Java Runtime Environment)
  • JDK8.0版本及以上

插件生成器

打开活字格插件构建工具-Java版链接(forguncyJavaPluginGenerator),下载【活字格Java扩展创建工具】。推荐使用压缩包版本创建。

打开【forguncyJavaExtensionGenerateTool.exe】,在如下界面配置插件的基础信息:

点击创建服务端命令插件,创建完成后,在设置的对应目录下会生成工程文件:

接下来使用IDE编译器打开MyPlugin工程,打开后,工程目录如下图:

至此就完成了前期的准备工作,下面我们来进行代码逻辑的编写。

代码实现

添加依赖

在实现代码之前,我们先要增加一些活字格的相关依赖,如下图我们需要给pom文件中添加如下依赖:

插件的图标和Logo替换Icon.png和PluginLogo.png即可。

而【PluginConfig.json】用于对插件的信息做基本的配置:

{
"assembly": [], // 如需要加载其他类
"javascript": [], // 如需加载其他JavaScript文件
"css": [], // 如需加载其他css文件
"image": "resources/PluginLogo.png", // 需要加载图片的相对路径
"description": "这是一个活字格插件", // 插件的文本描述信息
"description_cn": "这是一个活字格插件", // 插件的中文文本描述信息
"name": "MyPlugin", // 插件名称
"name_cn": "我的插件", // 插件中午名称
"pluginType": "command", // 插件类型,当前为命令类型插件
"guid": "fefeb164-ab98-48c8-b309-b5410052e504", // 插件唯一标识GUID,建议勿修改
"version": "1.0.0.0", // 插件版本
"dependenceVersion": "10.0.0.0" // 插件支持依赖最低活字格版本
}

编写核心代码逻辑

在完成上述配置之后,就可以编写插件逻辑了。下面是插件的一段示例代码,主要是通过5个参数(AppSecret、请求ID、时间戳、数据和签名结果)生成一段随机数签名。

package org.example;

import com.grapecity.forguncy.LoggerContext;
import com.grapecity.forguncy.commands.ICommandExecutableInServerSide;
import com.grapecity.forguncy.commands.IServerCommandExecuteContext;
import com.grapecity.forguncy.commands.annotation.ResultToProperty;
import com.grapecity.forguncy.commands.annotation.common.Category;
import com.grapecity.forguncy.commands.entity.Command;
import com.grapecity.forguncy.commands.entity.ExecuteResult;
import com.grapecity.forguncy.commands.enumeration.CommandScope;
import com.grapecity.forguncy.plugincommon.common.annotation.*;
import lombok.Data;
import org.apache.commons.codec.binary.Base64; import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest; @Data
@Icon( uri= "resources/Icon.png")
@Category(category = "程杰合集")
public class MyPlugin extends Command implements ICommandExecutableInServerSide { private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; @DisplayName(displayName = "AppSecret")
@FormulaProperty
@Required
private String appSecret; @DisplayName(displayName = "请求ID")
@FormulaProperty
@Required
private String requestId; @DisplayName(displayName = "时间戳")
@FormulaProperty
@Required
private String timestamp; @DisplayName(displayName = "数据")
@FormulaProperty
@Required
private String data; @ResultToProperty
@FormulaProperty
@DisplayName(displayName = "签名结果")
private String resultTo = "结果"; @Override
public ExecuteResult execute(IServerCommandExecuteContext dataContext) {
Long innerTimestamp = Long.parseLong(timestamp);
String res = null;
try {
res = sign(appSecret, requestId, innerTimestamp, data);
} catch (Exception e) {
throw new RuntimeException(e);
}
try {
dataContext.getParameters().put(resultTo, res);
} catch (Exception e) {
throw new RuntimeException(e);
} ExecuteResult executeResult = new ExecuteResult();
executeResult.getReturnValues().put("结果", res);
return executeResult;
} @Override
public boolean getDesignerPropertyVisible(String propertyName, CommandScope commandScope) { return super.getDesignerPropertyVisible(propertyName, commandScope);
} @Override
public String toString() {
return "签名程杰";
} public static String sign(String appSecret, String requestId, Long timestamp, String data) throws Exception{
// 1.签名参数按自然升序排列,拼接上data
StringBuilder sb = new StringBuilder();
sb.append("appSecret=").append(appSecret).append("&")
.append("requestId=").append(requestId).append("&")
.append("timestamp=").append(timestamp)
.append(data);
// 2.对签名字符串base64编码后获取32位md5值
// 2.对签名字符串base64编码后获取32位md5值
String base64Encode = base64Encode(sb.toString().getBytes("UTF-8"));
String md5Value = md5(base64Encode);
// 3.将得到的MD5值进行sha1散列,转换为16进制字符串
String sign = sha1(md5Value);
return sign;
} /**
* 对字符串进行MD5加密,得到32位MD5值
* @param text 明文
* @return 密文
*/
public static String md5(String text) {
try {
MessageDigest msgDigest = MessageDigest.getInstance("MD5");
msgDigest.update(text.getBytes("UTF-8"));
byte[] bytes = msgDigest.digest();
// 转成16进制
return new String(encodeHex(bytes));
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("System doesn't support MD5 algorithm.");
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("System doesn't support your EncodingException.");
}
} /***
* SHA加密
* @return
*/
public static String sha1(String content) throws Exception {
MessageDigest sha = MessageDigest.getInstance("SHA1");
byte[] byteArray = content.getBytes("UTF-8");
return new String(encodeHex(sha.digest(byteArray)));
} /**
* base64编码
*
* @param content
* @return
* @throws Exception
*/
public static String base64Encode(byte[] content) throws Exception {
return Base64.encodeBase64String(content).replaceAll("(\\\r\\\n|\\\r|\\\n|\\\n\\\r)", "");
} /**
* base64解码
*
* @param content
* @return
* @throws Exception
*/ public static byte[] base64Decode(String content) throws Exception {
return Base64.decodeBase64(content);
} /**
* 转换成16进制
* @param data
* @return
*/
private static char[] encodeHex(byte[] data) {
int l = data.length;
char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];
out[j++] = DIGITS[0x0F & data[i]];
}
return out;
}
public static String getPostData(HttpServletRequest request) {
StringBuilder data = new StringBuilder();
String line;
BufferedReader reader;
try {
reader = request.getReader();
while (null != (line = reader.readLine())) {
data.append(line);
}
} catch (IOException e) {
return null;
}
return data.toString();
}
}

使用maven打包插件

代码写完后,将整个项目打包:在此处点击【clean】,然后点击【install】:

接着在【target】目录会出现打包产物:

紧接着把打包后的zip插件安装到活字格设计器使用。

新建命令,在命令选择中就可以找到刚才打包的插件。

填写参数:

可以在服务端命令中进行测试:

可以看到,上图的测试结果中返回了一段随机数签名。这样,一个使用Java语言构建的插件就已经开发完成啦。

总结

以上就是如何使用Java如何在低代码平台中开发一个命令插件的全过程,如果您想了解更多的信息,欢迎点击这里查看。

扩展链接:

从表单驱动到模型驱动,解读低代码开发平台的发展趋势

低代码开发平台是什么?

基于分支的版本管理,帮助低代码从项目交付走向定制化产品开发

Java集成系列:高效构建自定义插件的更多相关文章

  1. Ionic2中集成腾讯Bugly之自定义插件

    Ionic2混合开发,入坑系列:Ionic2中集成腾讯Bugly之自定义插件 1.编写Bugly.js代码 var exec = require('cordova/exec'); module.exp ...

  2. Cordova与现有框架的结合,Cordova插件使用教程,Cordova自定义插件,框架集成Cordova,将Cordova集成到现有框架中

    一.框架集成cordova 将cordova集成到现有框架中 一般cordova工程是通过CMD命令来创建一个工程并添加Android.ios等平台,这样的创建方式可以完整的下载开发过程中所需要的的插 ...

  3. ionic2/cordova自定义插件集成aar包

    一.准备自定义插件 1. 准备:安装plugman npm install -g plugman 2. 新建组件 plugman create --name MyPlugin --plugin_id ...

  4. 【JAVA零基础入门系列】Day2 Java集成开发环境IDEA

    开发环境搭建好之后,还需要一个集成开发环境也就是IDE来进行编程.这里推荐的IDE是IDEA,那个老掉牙的Eclipse还是先放一边吧,(手动滑稽). IDEA的下载地址:http://www.jet ...

  5. nagios系列(五)之nagios图形显示的配置及自定义插件检测密码是否修改详解

    nagios图形显示的配置 在服务端安装相关软件 #1.图形显示管理的依赖库 yum install cairo pango zlib zlib-devel freetype freetype-dev ...

  6. java并发编程(7)构建自定义同步工具及条件队列

    构建自定义同步工具 一.通过轮询与休眠的方式实现简单的有界缓存 public void put(V v) throws InterruptedException { while (true) { // ...

  7. Java 集合系列之五:Map基本操作

    1. Java Map 1. Java Map 重要观点 Java Map接口是Java Collections Framework的成员.但是它不是Collection 将键映射到值的对象.一个映射 ...

  8. Gradle系列之Android Gradle插件

    原文发于微信公众号 jzman-blog,欢迎关注交流. 通过前面几篇文章学习了 Gradle 基础知识以及 Gradle 插件相关的知识,关于 Gradle 及其插件相关知识请先阅读下面几篇文章: ...

  9. Java 集合系列 17 TreeSet

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  10. Java 集合系列 12 TreeMap

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

随机推荐

  1. 异步小工具 asyncTool

    class asyncTool { constructor () { this.arr = [] this.ctx = {} } use (func) { const into = { func, n ...

  2. 玩转Vue3之深入理解响应式编程

    前言 Vue 3是一个功能强大的前端框架,它引入了一些令人兴奋的新特性,其中最引人注目的是ref和reactive.这两个API是Vue 3中响应式编程的核心,本文将深入探讨它们的用法和差异. 什么是 ...

  3. 基于C语言的串口AT指令发送实例解析

    一 知识点 1 AI指令后面一定要加 \n\r 2 注意AT指令里面待双引号的这种,要使用斜杠隔开. 二 源码: void Set_Pdu_Mode(void) { u8 a = 1; if(atKe ...

  4. Rust 标准库 Trait 指南

    部分内容来自 Rust 2021 年期刊 内容目录 引言 Trait 基础 自动 Trait 泛型 Trait 格式化 Trait 操作符 Trait 转换 Trait 错误处理 迭代器 Trait ...

  5. JSF标签之f:facet 的使用方法

    f:facet标签用来为包含f:facet标签的父组件与被f:facet标签所包含的子组件之间申明一种特殊的关系.常与h:panelGrid,h:dataTable等标签连用,申明组件为标题或页脚. ...

  6. C++ 赋值运算符和拷贝构造函数

    拷贝构造函数 class Foo{ public: Foo(); Foo(const Foo&); //自己定义的拷贝构造函数 }; 如果不自己定义,编译器会自己合成一个默认拷贝构造函数: c ...

  7. 记录--居中为什么要使用 transform?

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 引言 居中是我们在前端布局中经常会遇到的问题,其中包括水平居中和垂直居中.居中的方法很多,比如说水平居中可以使用text-align: c ...

  8. 记录--千万别让 console.log 上生产!用 Performance 和 Memory 告诉你为什么

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 很多前端都喜欢用 console.log 调试,先不谈调试效率怎么样,首先 console.log 有个致命的问题:会导致内存泄漏. 为什 ...

  9. 全网首套完整containerd容器工具教程

    1.Containerd的由来 [Docker名噪一时,捐出runC]2013年docker公司在推出docker产品后,由于其对全球技术产生了一定的影响力,Google公司明显感觉到自己公司内部所使 ...

  10. 《On Java 8》笔记 2

    第十一章 内部类 Java 8 的 Lambda 表达式和方法引用减少了编写内部类的需求 外部类可以提供一个方法返回一个指向内部类的引用 链接外部类 内部类还拥有其外部类的所有元素的访问权 使用 .t ...