로우 코드 통합 Java 시리즈: 맞춤형 플러그인을 효율적으로 구축

머리말

소프트웨어 개발이 빠르게 발전하고 수요가 계속 증가함에 따라 개발자는 더 많은 압박과 과제에 직면하게 됩니다. 기존 개발 방식은 많은 시간과 에너지가 필요하며, 로우코드 개발 플랫폼의 등장으로 개발자는 더욱 효율적이고 빠른 개발 방식을 얻을 수 있습니다. 오늘 편집자는 명령 플러그인 구축을 예로 들어 Java 언어를 사용하여 사용자 정의 플러그인을 효율적으로 구축하는 방법을 보여줄 것입니다.

환경 준비

  • 이동형 그리드 플러그인 구축 도구 - Java 버전(forguncyJavaPluginGenerator)
  • 이동식 그리드 디자이너 (v10.0 버전 이상)
  • IDE 컴파일러(예: IntelliJ IDEA Community Edition)
  • 자바 런타임 환경
  • JDK8.0 버전 이상

플러그인 생성기

Forguncy Java Plugin Generator 도구-Java 버전 링크( forguncyJavaPluginGenerator )를 열고 [Forguncy Java Plugin Generator]를 다운로드합니다. 압축된 패키지 버전을 사용하는 것이 좋습니다.

[forguncyJavaExtensionGenerateTool.exe]를 열고 다음 인터페이스에서 플러그인의 기본 정보를 구성합니다.

서버 명령 플러그인을 생성하려면 클릭하세요. 생성이 완료되면 해당 디렉터리 세트에 프로젝트 파일이 생성됩니다.

다음으로 IDE 컴파일러를 사용하여 MyPlugin 프로젝트를 열면 프로젝트 디렉터리는 아래와 같습니다.

이제 사전 준비 작업이 완료되었습니다. 이제 코드 로직을 작성하겠습니다.

암호

종속성 추가

코드를 구현하기 전에 먼저 이동 가능한 유형 그리드와 관련된 몇 가지 종속성을 추가해야 합니다. 다음과 같은 종속성을 pom 파일에 추가해야 합니다.

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를 사용하여 로우 코드 플랫폼에서 명령 플러그인을 개발하는 전체 과정입니다. 자세한 내용을 보려면 여기를 클릭하세요 .

확장 링크:

양식 중심에서 모델 중심으로 로우코드 개발 플랫폼의 개발 동향을 해석합니다.

로우코드 개발 플랫폼이란?

브랜치 기반 버전 관리는 로우 코드가 프로젝트 납품에서 맞춤형 제품 개발로 이동하는 데 도움이 됩니다.

동료 치킨 "오픈 소스" deepin-IDE 및 마침내 부트스트랩을 달성했습니다! 좋은 친구, Tencent는 Switch를 "생각하는 학습 기계"로 전환했습니다. Tencent Cloud의 4월 8일 실패 검토 및 상황 설명 RustDesk 원격 데스크톱 시작 재구성 웹 클라이언트 WeChat의 SQLite 기반 오픈 소스 터미널 데이터베이스 WCDB의 주요 업그레이드 TIOBE 4월 목록: PHP 사상 최저치로 떨어졌고 FFmpeg의 아버지인 Fabrice Bellard는 오디오 압축 도구인 TSAC를 출시했으며 Google은 대규모 코드 모델인 CodeGemma를 출시했습니다 . 오픈소스라서 너무 좋아요 - 오픈소스 사진 및 포스터 편집기 도구
{{o.이름}}
{{이름}}

추천

출처my.oschina.net/powertoolsteam/blog/11052465