Browse Source

open

master
pioneer 3 years ago
commit
7ee96edd3a
  1. 6
      README.md
  2. BIN
      doc/JSD-9778-需求确认书V1.docx
  3. BIN
      doc/JSD-9778配置使用文档.docx
  4. 68
      doc/apiDataset.cpt
  5. BIN
      lib/finekit-10.0.jar
  6. 24
      plugin.xml
  7. 40
      src/main/java/com/fr/plugin/xxx/LocaleFinder.java
  8. 45
      src/main/java/com/fr/plugin/xxx/data/UsersTableData.java
  9. 104
      src/main/java/com/fr/plugin/xxx/data/UsersTableDataModel.java
  10. 62
      src/main/java/com/fr/plugin/xxx/data/WebTableDataModel.java
  11. 706
      src/main/java/com/fr/plugin/xxx/kit/HttpKit.java
  12. 57
      src/main/java/com/fr/plugin/xxx/provider/UsersTableDataDefine.java
  13. 52
      src/main/java/com/fr/plugin/xxx/ui/UsersTableDataPane.java
  14. 137
      src/main/java/com/fr/plugin/xxx/ui/WebBaseTableDataPane.java
  15. 60
      src/main/java/com/fr/plugin/xxx/ui/WebQueryPane.java
  16. 133
      src/main/java/com/fr/plugin/xxx/util/Base64Utils.java
  17. 310
      src/main/java/com/fr/plugin/xxx/util/RSAUtils.java
  18. BIN
      src/main/resources/com/fr/plugin/xxx/images/help.png
  19. BIN
      src/main/resources/com/fr/plugin/xxx/images/logo16.png
  20. 11
      src/main/resources/com/fr/plugin/xxx/locale/lang.properties
  21. 11
      src/main/resources/com/fr/plugin/xxx/locale/lang_zh_CN.properties

6
README.md

@ -0,0 +1,6 @@
# open-JSD-9778
JSD-9778 通过获取统计数据接口,实现程序数据集功能\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。

BIN
doc/JSD-9778-需求确认书V1.docx

Binary file not shown.

BIN
doc/JSD-9778配置使用文档.docx

Binary file not shown.

68
doc/apiDataset.cpt

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<WorkBook xmlVersion="20211223" releaseVersion="10.0.0">
<TableDataMap>
<TableData name="API数据集1" class="com.fr.plugin.xxx.data.UsersTableData" pluginID="com.fr.plugin.xxx.dataset" plugin-version="1.0">
<Parameters>
<Parameter>
<Attributes name="host"/>
<O>
<![CDATA[http://localhost:8090/jsd9778/place/cageview/getData]]></O>
</Parameter>
<Parameter>
<Attributes name="apiKey"/>
<O>
<![CDATA[c36da4bf9c5f98e4]]></O>
</Parameter>
<Parameter>
<Attributes name="privateKey"/>
<O>
<![CDATA[MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALhdfiHuDR3UfwUZR-lzq6-zLPrt_ALx2p2LG8m4kRv7D3cr8rr-96UWHmz0O1iluSx8_pkII2gG3S9peYtxWUqaHK-z2xVjXX0K1VuhgAg6AsRrpHxQpWUnPJHLdYeYW-4Ny6IQl-apw867arEYVdiYeIZ97Qn92_rPNBpbYFFpAgMBAAECgYA0f7r5InZttiLtasOFgMC06Yq3cak_lWsxTXl-OaZol1dSEhuukAgo5GGJmQqFNbvDJVzCawTaDIpTg-9ue7p2_c_DZV1xZO0DDCIrqoV9hIQejcH4NrP-2f02KMfnMMeSGzBLT8J9KRWJ30yDh33ok5KFk58zZgaXYreGyM5OeQJBAOqWyCurRYmadg_vpeZAvH7m3HEmjXF2bTNaigzVYOuwTOnE62MpV3cTNtpWT8u83n0tOfjoZWh5o9qNDrdgZtcCQQDJMTjc0EV2FVV8C-4hElsmRtr5zIIw2xrEuHaqisB32Mapd3diGM-fTA6GpaqwXEnzalcNhrNFqCvBHcPygUG_AkBtIL13ixIrI_6eBTaguSa2xgBwZqXPzW6ZQBoOREj0-yucZ-20UGwOyZJv2Uz_kxnRE3PvdXSPOF7f8VSSO7c7AkAMxInmQXVXBA2TvLIU-TQ9npuA5MCSVyVAvLATLJEASgp5cLJr0EVEx6_YTaUiYgjzYJk7q4Ou9Pgp3ji0KA3DAkB5cxB_PItb7XaWJg53Q4vfcCXCrBBsNrwpCLeqwqTQgicYTK5CRYXwNCjTxdiri-OG0lBzP5_jQMVNDt7lV4qJ]]></O>
</Parameter>
</Parameters>
</TableData>
</TableDataMap>
<ElementCaseMobileAttr>
<ElementCaseMobileAttrProvider horizontal="1" vertical="1" zoom="true" refresh="false" isUseHTML="false" isMobileCanvasSize="false" appearRefresh="false" allowFullScreen="false" allowDoubleClickOrZoom="true" functionalWhenUnactivated="false"/>
</ElementCaseMobileAttr>
<Report class="com.fr.report.worksheet.WorkSheet" name="sheet1">
<ReportPageAttr>
<HR/>
<FR/>
<HC/>
<FC/>
</ReportPageAttr>
<ColumnPrivilegeControl/>
<RowPrivilegeControl/>
<RowHeight defaultValue="723900">
<![CDATA[723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900]]></RowHeight>
<ColumnWidth defaultValue="2743200">
<![CDATA[2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200]]></ColumnWidth>
<CellElementList>
<C c="0" r="0">
<PrivilegeControl/>
<Expand/>
</C>
</CellElementList>
<ReportAttrSet>
<ReportSettings headerHeight="0" footerHeight="0">
<PaperSetting/>
<Background name="ColorBackground" color="-1"/>
</ReportSettings>
</ReportAttrSet>
<PrivilegeControl/>
</Report>
<ReportParameterAttr>
<Attributes showWindow="true" delayPlaying="true" windowPosition="1" align="0" useParamsTemplate="true" currentIndex="0"/>
<PWTitle>
<![CDATA[参数]]></PWTitle>
</ReportParameterAttr>
<StyleList/>
<DesignerVersion DesignerVersion="KAA"/>
<PreviewType PreviewType="0"/>
<TemplateCloudInfoAttrMark class="com.fr.plugin.cloud.analytics.attr.TemplateInfoAttrMark" pluginID="com.fr.plugin.cloud.analytics.v10" plugin-version="2.5.1.20220225">
<TemplateCloudInfoAttrMark createTime="1647534084397"/>
</TemplateCloudInfoAttrMark>
<TemplateIdAttMark class="com.fr.base.iofile.attr.TemplateIdAttrMark">
<TemplateIdAttMark TemplateId="88ceb155-68ab-4f40-8551-8d6038d2acf4"/>
</TemplateIdAttMark>
</WorkBook>

BIN
lib/finekit-10.0.jar

Binary file not shown.

24
plugin.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<id>com.fr.plugin.xxx.dataset</id>
<name><![CDATA[API数据集定制]]></name>
<active>yes</active>
<version>1.2</version>
<env-version>10.0</env-version>
<jartime>2018-07-31</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[API数据集定制]]></description>
<change-notes><![CDATA[API数据集定制]]></change-notes>
<main-package>com.fr.plugin.xxx</main-package>
<prefer-packages>
<prefer-package>com.fanruan.api</prefer-package>
</prefer-packages>
<extra-core>
<LocaleFinder class="com.fr.plugin.xxx.LocaleFinder"/>
</extra-core>
<extra-designer>
<TableDataDefineProvider class="com.fr.plugin.xxx.provider.UsersTableDataDefine"/>
<ServerTableDataDefineProvider class="com.fr.plugin.xxx.provider.UsersTableDataDefine"/>
</extra-designer>
<function-recorder class="com.fr.plugin.xxx.LocaleFinder"/>
</plugin>

40
src/main/java/com/fr/plugin/xxx/LocaleFinder.java

@ -0,0 +1,40 @@
/*
* Copyright (C), 2018-2020
* Project: starter
* FileName: LocaleFinder
* Author: xxx
* Date: 2020/8/31 22:19
*/
package com.fr.plugin.xxx;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.stable.fun.Authorize;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
import static com.fr.plugin.xxx.LocaleFinder.PLUGIN_ID;
/**
* <Function Description><br>
* <LocaleFinder>
*
* @author xxx
* @since 1.0.0
*/
@EnableMetrics
@Authorize(callSignKey = PLUGIN_ID)
public class LocaleFinder extends AbstractLocaleFinder {
public static final String PLUGIN_ID = "com.fr.plugin.xxx.dataset";
@Override
@Focus(id = PLUGIN_ID, text = "Plugin-xxx", source = Original.PLUGIN)
public String find() {
return "com/fr/plugin/xxx/locale/lang";
}
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
}

45
src/main/java/com/fr/plugin/xxx/data/UsersTableData.java

@ -0,0 +1,45 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: WechatTableData
* Author: xxx
* Date: 2021/12/8 16:55
*/
package com.fr.plugin.xxx.data;
import com.fanruan.api.data.open.BaseTableData;
import com.fr.base.TableData;
import com.fr.general.data.DataModel;
import com.fr.script.Calculator;
/**
* <Function Description><br>
* <UsersTableData>
*
* @author xxx
* @since 1.0.0
*/
public class UsersTableData extends BaseTableData {
private static final long serialVersionUID = -7456007025209900779L;
@Override
public DataModel createDataModel(Calculator calculator) {
return createDataModel(calculator, TableData.RESULT_ALL);
}
@Override
public DataModel createDataModel(Calculator calculator, int rowCount) {
return new UsersTableDataModel(Calculator.processParameters(calculator, super.getParameters(calculator)));
}
@Override
public Object clone() throws CloneNotSupportedException {
UsersTableData cloned = (UsersTableData) super.clone();
return cloned;
}
@Override
public boolean equals(Object obj) {
return obj instanceof UsersTableData;
}
}

104
src/main/java/com/fr/plugin/xxx/data/UsersTableDataModel.java

@ -0,0 +1,104 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: WechatTableDataModel
* Author: xxx
* Date: 2021/12/8 19:09
*/
package com.fr.plugin.xxx.data;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.xxx.kit.HttpKit;
import com.fr.plugin.xxx.util.RSAUtils;
import com.fr.stable.ParameterProvider;
import com.fr.third.org.apache.commons.codec.binary.Base64;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* <Function Description><br>
* <UsersTableDataModel>
*
* @author xxx
* @since 1.0.0
*/
public class UsersTableDataModel extends WebTableDataModel {
public static final String TOTAL_CAGE_SUM = "totalCageSum";
public static final String FREE_PRE = "freePre";
public static final String NAME = "name";
public static final String FREE_CAGE_SUM = "freeCageSum";
public static final String FEED_ANIMAL_SUM = "feedAnimalSum";
private static final long serialVersionUID = 1561845127687781184L;
public UsersTableDataModel(ParameterProvider[] parameters) {
super(parameters);
// this.columnNames = new String[]{TOTAL_CAGE_SUM, FREE_PRE, NAME, FREE_CAGE_SUM, FEED_ANIMAL_SUM};
this.columnNames = new String[]{"总笼位", "空置率", "名称", "空笼位", "在笼猴子数"};
}
@Override
protected void init() {
if (!PluginContexts.currentContext().isAvailable()) {
LogKit.error(I18nKit.getLocText("Plugin-xxx_Licence_Expired"));
return;
}
if (this.valueList != null) {
return;
}
this.valueList = new ArrayList();
// 域名
this.host = this.parameters[0].getValue().toString();
// 应用标识
String apiKey = this.parameters[1].getValue().toString();
// 公钥
String publicKey = this.parameters[2].getValue().toString();
try {
JSONArray usersInfo = getUserInfo(apiKey, publicKey);
addFRUserInfo2List(usersInfo);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 人员获取
*
* @param apiKey
* @param publicKey
* @return
* @throws IOException
*/
private JSONArray getUserInfo(String apiKey, String publicKey) throws Exception {
Map<String, String> header = new HashMap<>();
header.put("API_KEY", apiKey);
String response = HttpKit.get(this.host, new HashMap<>(), header);
LogKit.info("xxx-UsersTableDataModel-getUserInfo-response:{}", response);
byte[] bytes = Base64.decodeBase64(response);
byte[] decodedData = RSAUtils.decryptByPublicKey(bytes, publicKey);
String decodedDataStr = new String(decodedData);
LogKit.info("xxx-UsersTableDataModel-getUserInfo-decodedData:{}", decodedDataStr);
return new JSONArray(decodedDataStr);
}
private void addFRUserInfo2List(JSONArray usersInfo) {
ArrayList<String> frUserInfo;
for (Object o : usersInfo) {
JSONObject userInfo = (JSONObject) o;
frUserInfo = new ArrayList<>();
frUserInfo.add(userInfo.getString(TOTAL_CAGE_SUM));
frUserInfo.add(userInfo.getString(FREE_PRE));
frUserInfo.add(userInfo.getString(NAME));
frUserInfo.add(userInfo.getString(FREE_CAGE_SUM));
frUserInfo.add(userInfo.getString(FEED_ANIMAL_SUM));
this.valueList.add(frUserInfo.toArray());
}
}
}

62
src/main/java/com/fr/plugin/xxx/data/WebTableDataModel.java

@ -0,0 +1,62 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: WebTableDataModel
* Author: xxx
* Date: 2021/12/16 8:17
*/
package com.fr.plugin.xxx.data;
import com.fanruan.api.data.open.BaseDataModel;
import com.fanruan.api.err.TableDataException;
import com.fr.stable.ParameterProvider;
import java.util.ArrayList;
/**
* <Function Description><br>
* <WebTableDataModel>
*
* @author xxx
* @since 1.0.0
*/
public abstract class WebTableDataModel extends BaseDataModel {
private static final long serialVersionUID = 5010918328453603247L;
protected ParameterProvider[] parameters;
protected String[] columnNames;
protected ArrayList valueList = null;
protected String host;
public WebTableDataModel(ParameterProvider[] parameters) {
this.parameters = parameters;
}
@Override
public int getColumnCount() throws TableDataException {
return this.columnNames.length;
}
@Override
public String getColumnName(int i) throws TableDataException {
return columnNames[i];
}
@Override
public int getRowCount() throws TableDataException {
init();
return valueList.size();
}
@Override
public Object getValueAt(int row, int col) throws TableDataException {
init();
return ((Object[]) valueList.get(row))[col];
}
@Override
public void release() throws Exception {
this.parameters = null;
}
protected abstract void init();
}

706
src/main/java/com/fr/plugin/xxx/kit/HttpKit.java

@ -0,0 +1,706 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: HttpKit
* Author: xxx
* Date: 2021/3/17 14:19
*/
package com.fr.plugin.xxx.kit;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.macro.EncodeConstants;
import com.fanruan.api.net.http.rs.HttpRequest;
import com.fanruan.api.net.http.rs.*;
import com.fr.third.guava.collect.Maps;
import com.fr.third.org.apache.http.*;
import com.fr.third.org.apache.http.client.HttpRequestRetryHandler;
import com.fr.third.org.apache.http.client.config.RequestConfig;
import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity;
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
import com.fr.third.org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import com.fr.third.org.apache.http.client.methods.HttpRequestBase;
import com.fr.third.org.apache.http.client.protocol.HttpClientContext;
import com.fr.third.org.apache.http.client.utils.URIBuilder;
import com.fr.third.org.apache.http.config.Registry;
import com.fr.third.org.apache.http.config.RegistryBuilder;
import com.fr.third.org.apache.http.conn.routing.HttpRoute;
import com.fr.third.org.apache.http.conn.socket.ConnectionSocketFactory;
import com.fr.third.org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import com.fr.third.org.apache.http.conn.socket.PlainConnectionSocketFactory;
import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import com.fr.third.org.apache.http.conn.ssl.SSLSocketFactory;
import com.fr.third.org.apache.http.conn.ssl.TrustStrategy;
import com.fr.third.org.apache.http.entity.FileEntity;
import com.fr.third.org.apache.http.entity.mime.HttpMultipartMode;
import com.fr.third.org.apache.http.entity.mime.MultipartEntityBuilder;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import com.fr.third.org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import com.fr.third.org.apache.http.message.BasicNameValuePair;
import com.fr.third.org.apache.http.protocol.HttpContext;
import com.fr.third.org.apache.http.ssl.SSLContextBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static com.fanruan.api.net.http.rs.HttpRequestType.POST;
/**
* <p>
* http请求工具类封装了用于http请求的各种方法
* 新增https忽略证书功能 Update By xxx on 2021-03-17
* </p>
*/
public class HttpKit {
private static final int RETRY_TIMES = 5;
private final static Object SYNC_LOCK = new Object();
private static CloseableHttpClient httpClient = null;
/**
* 根据请求地址创建HttpClient对象
*
* @param url 请求地址
* @return HttpClient对象
*/
public static CloseableHttpClient getHttpClient(String url) {
String hostname = url.split("/")[2];
int port = 80;
if (hostname.contains(":")) {
String[] arr = hostname.split(":");
hostname = arr[0];
port = Integer.parseInt(arr[1]);
}
if (httpClient == null) {
synchronized (SYNC_LOCK) {
if (httpClient == null) {
// httpClient = createHttpClient(hostname, port, SSLContexts.createDefault());
try {
httpClient = createHttpClient(hostname, port, createIgnoreVerifySSL());
} catch (NoSuchAlgorithmException e) {
LogKit.error(e.getMessage(), e);
} catch (KeyManagementException e) {
LogKit.error(e.getMessage(), e);
}
}
}
}
return httpClient;
}
/**
* 新增了https 请求绕过证书认证
*
* @return
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
//信任所有
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
return sslContext;
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
LogKit.error(e.getMessage(), e);
}
return null;
}
public static CloseableHttpClient createHttpClient(String hostname, int port, SSLContext sslContext) {
return createHttpClient(200, 40, 100, hostname, port, sslContext);
}
private static CloseableHttpClient createHttpClient(int maxTotal,
int maxPerRoute,
int maxRoute,
String hostname,
int port,
SSLContext sslContext) {
ConnectionSocketFactory socketFactory = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<ConnectionSocketFactory> registry = RegistryBuilder
.<ConnectionSocketFactory>create()
.register("http", socketFactory)
.register("https", sslConnectionSocketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
// 将最大连接数增加
cm.setMaxTotal(maxTotal);
// 将每个路由基础的连接增加
cm.setDefaultMaxPerRoute(maxPerRoute);
HttpHost httpHost = new HttpHost(hostname, port);
// 将目标主机的最大连接数增加
cm.setMaxPerRoute(new HttpRoute(httpHost), maxRoute);
// 请求重试处理
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= RETRY_TIMES) {// 如果已经重试了5次,就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
return false;
}
if (exception instanceof InterruptedIOException) {// 超时
return false;
}
if (exception instanceof UnknownHostException) {// 目标服务器不可达
return false;
}
if (exception instanceof SSLException) {// SSL握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
com.fr.third.org.apache.http.HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,就再次尝试
return !(request instanceof HttpEntityEnclosingRequest);
}
};
return HttpClients.custom()
.setConnectionManager(cm)
.setRetryHandler(httpRequestRetryHandler)
.build();
}
/**
* 设置 httpEntity
*
* @param requestBase 请求体
* @param httpRequest 请求
*/
private static void setHttpEntity(@NotNull HttpEntityEnclosingRequestBase requestBase, @NotNull HttpRequest httpRequest) {
HttpEntity httpEntity = httpRequest.getHttpEntity();
if (httpEntity != null) {
// 如果存在 httpEntity 直接设置
requestBase.setEntity(httpEntity);
return;
}
Map<String, String> params = httpRequest.getParams();
if (params == null || params.isEmpty()) {
return;
}
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : params.entrySet()) {
pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
try {
requestBase.setEntity(new UrlEncodedFormEntity(pairs, httpRequest.getEncoding()));
} catch (UnsupportedEncodingException e) {
LogKit.error(e.getMessage(), e);
}
}
private static <V> Map<String, String> transformMap(Map<String, V> oldMap) {
if (oldMap == null) {
return null;
}
return Maps.transformEntries(oldMap, new Maps.EntryTransformer<String, V, String>() {
@Override
public String transformEntry(@Nullable String key, @Nullable V value) {
return value == null ? null : value.toString();
}
});
}
/**
* 发起POST请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params POST请求的参数
* @return 服务器返回的文本内容
*/
public static <V> String post(String url, Map<String, V> params) throws IOException {
return executeAndParse(HttpRequest
.custom()
.url(url)
.post(transformMap(params))
.build());
}
/**
* 发起POST请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params POST请求的参数
* @param responseType 返回类型
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest)
*/
@Deprecated
public static <T, V> T post(String url, Map<String, V> params, HttpResponseType<T> responseType) throws IOException {
CloseableHttpResponse response = execute(HttpRequest
.custom()
.url(url)
.post(transformMap(params))
.build());
return responseType.result(response, null);
}
/**
* 发起POST请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params POST请求的参数
* @param headers 请求头
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest)
*/
@Deprecated
public static <V> String post(String url, Map<String, V> params, Map<String, String> headers) throws IOException {
return executeAndParse(HttpRequest
.custom()
.url(url)
.post(transformMap(params))
.headers(headers)
.build());
}
/**
* 发起POST请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params POST请求的参数
* @param headers 请求头
* @param responseType 返回类型
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest)
*/
@Deprecated
public static <T, V> T post(String url, Map<String, V> params, Map<String, String> headers, HttpResponseType<T> responseType) throws IOException {
CloseableHttpResponse response = execute(HttpRequest
.custom()
.url(url)
.post(transformMap(params))
.headers(headers)
.build());
return responseType.result(response, null);
}
/**
* 发起POST请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params POST请求的参数
* @param responseEncoding 响应的文本的编码
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle)
*/
@Deprecated
public static <V> String post(String url, Map<String, V> params, String responseEncoding) throws IOException {
return executeAndParse(HttpRequest
.custom()
.url(url)
.post(transformMap(params))
.build(),
new TextResponseHandle(responseEncoding));
}
/**
* 发起POST请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params POST请求的参数
* @param responseEncoding 响应的文本的编码
* @param headers 请求头
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle)
*/
@Deprecated
public static <V> String post(String url, Map<String, V> params, String responseEncoding, Map<String, String> headers) throws IOException {
return executeAndParse(HttpRequest
.custom()
.url(url)
.post(transformMap(params))
.headers(headers)
.build(),
new TextResponseHandle(responseEncoding));
}
/**
* 发起POST请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params POST请求的参数
* @param responseEncoding 响应的文本的编码
* @param paramsEncoding 参数编码
* @param headers 请求头
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle)
*/
public static <V> String post(String url, Map<String, V> params, String responseEncoding, String paramsEncoding, Map<String, String> headers) throws IOException {
return executeAndParse(HttpRequest
.custom()
.url(url)
.post(transformMap(params))
.encoding(paramsEncoding)
.headers(headers)
.build(),
new TextResponseHandle(responseEncoding));
}
/**
* 发起POST请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params POST请求的参数
* @param responseEncoding 响应的文本的编码
* @param paramsEncoding 参数编码
* @param headers 请求头
* @param responseType 返回值类型
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest)
*/
public static <T, V> T post(String url, Map<String, V> params, String responseEncoding, String paramsEncoding, Map<String, String> headers, HttpResponseType<T> responseType) throws IOException {
CloseableHttpResponse response = execute(HttpRequest
.custom()
.url(url)
.post(transformMap(params))
.encoding(paramsEncoding)
.headers(headers)
.build());
return responseType.result(response, responseEncoding);
}
/**
* 发起GET请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @return 服务器返回的文本内容
*/
public static String get(String url) throws IOException {
return executeAndParse(HttpRequest.custom().url(url).build());
}
/**
* 发起GET请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params 参数
* @return 服务器返回的文本内容
*/
public static String get(String url, Map<String, String> params) throws IOException {
return executeAndParse(HttpRequest.custom().url(url).params(params).build());
}
/**
* 发起GET请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params 参数
* @param headers 请求头
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle)
*/
public static String get(String url, Map<String, String> params, Map<String, String> headers) throws IOException {
return executeAndParse(HttpRequest.custom().url(url).params(params).headers(headers).build());
}
/**
* 发起GET请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params 参数
* @param responseEncoding 返回的文本的编码
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle)
*/
public static String get(String url, Map<String, String> params, String responseEncoding) throws IOException {
return executeAndParse(HttpRequest
.custom()
.url(url)
.params(params)
.build(),
new TextResponseHandle(responseEncoding));
}
/**
* 发起GET请求并获取返回的文本
*
* @param url 响应请求的的服务器地址
* @param params 参数
* @param responseEncoding 返回的文本的编码
* @return 服务器返回的文本内容
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle)
*/
public static String get(String url, Map<String, String> params, String responseEncoding, Map<String, String> headers) throws IOException {
return executeAndParse(HttpRequest
.custom()
.url(url)
.params(params)
.headers(headers)
.build(),
new TextResponseHandle(responseEncoding));
}
/**
* 从指定的地址下载文件
*
* @param url 文件下载地址
* @return 文件的字节流
* @throws IOException 下载过程中出现错误则抛出此异常
*/
public static ByteArrayInputStream download(String url) throws IOException {
return executeAndParse(HttpRequest.custom().url(url).build(), StreamResponseHandle.DEFAULT);
}
/**
* 从指定的地址下载文件
*
* @param url 文件下载地址
* @param params 参数对
* @param responseEncoding 响应的文件编码
* @param headers 请求头
* @return 文件的字节流
* @throws IOException 下载过程中出现错误则抛出此异常
*/
public static ByteArrayInputStream download(String url, Map<String, String> params, String responseEncoding, Map<String, String> headers) throws IOException {
return executeAndParse(HttpRequest
.custom()
.url(url)
.params(params)
.headers(headers)
.build(),
new StreamResponseHandle(responseEncoding));
}
/**
* 上传文件到指定的服务器
*
* @param url 接收文件的服务器地址
* @param file 要上传的文件默认的文件编码为utf-8
* @throws IOException 上传中出现错误则抛出此异常
*/
public static void upload(String url, File file) throws IOException {
upload(url, file, Charset.forName("utf-8"));
}
/**
* 上传文件到指定的服务器
*
* @param url 接收文件的服务器地址
* @param file 要上传的文件
* @param charset 文件的编码
* @throws IOException 上传中出现错误则抛出此异常
*/
public static void upload(String url, File file, Charset charset) throws IOException {
upload(url, new FileEntity(file), charset);
}
/**
* 上传文件到指定的服务器
*
* @param url 接收文件的服务器地址
* @param builder 附件构造器
* @param charset 文件的编码
* @throws IOException 上传中出现错误则抛出此异常
*/
public static void upload(String url, MultipartEntityBuilder builder, Charset charset) throws IOException {
upload(url, builder, charset, Collections.<String, String>emptyMap(), POST);
}
/**
* 上传文件到指定的服务器
*
* @param url 接收文件的服务器地址
* @param fileEntity 文件实体
* @param charset 文件的编码
* @throws IOException 上传中出现错误则抛出此异常
*/
public static void upload(String url, FileEntity fileEntity, Charset charset) throws IOException {
upload(url, fileEntity, charset, Collections.<String, String>emptyMap(), POST);
}
/**
* 上传多文件到指定的服务器
*
* @param url 接收文件的服务器地址
* @param builder 附件构造器
* @param charset 文件的编码
* @param headers 请求头
* @param httpRequestType 请求类型
* @throws IOException 上传中出现错误则抛出此异常
*/
public static void upload(String url, MultipartEntityBuilder builder, Charset charset, Map<String, String> headers, HttpRequestType httpRequestType) throws IOException {
// richie:采用浏览器模式,防止出现乱码
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
HttpEntity reqEntity = builder.setCharset(charset).build();
upload(url, reqEntity, charset, headers, httpRequestType);
}
/**
* 上传文件到指定的服务器
*
* @param url 接收文件的服务器地址
* @param reqEntity 请求实体
* @param charset 文件的编码
* @param headers 请求头
* @param httpRequestType 请求类型
* @throws IOException 上传中出现错误则抛出此异常
*/
public static void upload(String url, HttpEntity reqEntity, Charset charset, Map<String, String> headers, HttpRequestType httpRequestType) throws IOException {
executeAndParse(HttpRequest
.custom()
.url(url)
.headers(headers)
.method(httpRequestType)
.httpEntity(reqEntity)
.encoding(charset.toString())
.build(),
UploadResponseHandle.DEFAULT);
}
/**
* 请求资源或服务使用默认文本http解析器UTF-8编码
*
* @param httpRequest httpRequest
* @return 返回处理结果
*/
public static String executeAndParse(HttpRequest httpRequest) throws IOException {
return executeAndParse(httpRequest, TextResponseHandle.DEFAULT);
}
/**
* 请求资源或服务自请求参数并指定 http 响应处理器
*
* <pre>
* String res = HttpToolbox.executeAndParse(HttpRequest
* .custom()
* .url("")
* .build(),
* TextResponseHandle.DEFAULT);
* </pre>
*
* @param httpRequest httpRequest
* @param handle http 解析器
* @return 返回处理结果
*/
public static <T> T executeAndParse(HttpRequest httpRequest, BaseHttpResponseHandle<T> handle) throws IOException {
return handle.parse(execute(httpRequest));
}
/**
* 请求资源或服务传入请求参数
*
* @param httpRequest httpRequest
* @return 返回处理结果
*/
public static CloseableHttpResponse execute(HttpRequest httpRequest) throws IOException {
return execute(getHttpClient(httpRequest.getUrl()), httpRequest);
}
/**
* 请求资源或服务自定义client对象传入请求参数
*
* @param httpClient http客户端
* @param httpRequest httpRequest
* @return 返回处理结果
*/
public static CloseableHttpResponse execute(CloseableHttpClient httpClient, HttpRequest httpRequest) throws IOException {
String url = httpRequest.getUrl();
// 创建请求对象
HttpRequestBase httpRequestBase = httpRequest.getMethod().createHttpRequest(url);
// 设置header信息
httpRequestBase.setHeader("User-Agent", "Mozilla/5.0");
Map<String, String> headers = httpRequest.getHeaders();
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpRequestBase.setHeader(entry.getKey(), entry.getValue());
}
}
// 配置请求的设置
RequestConfig requestConfig = httpRequest.getConfig();
if (requestConfig != null) {
httpRequestBase.setConfig(requestConfig);
}
// 判断是否支持设置entity(仅HttpPost、HttpPut、HttpPatch支持)
if (HttpEntityEnclosingRequestBase.class.isAssignableFrom(httpRequestBase.getClass())) {
setHttpEntity((HttpEntityEnclosingRequestBase) httpRequestBase, httpRequest);
} else {
Map<String, String> params = httpRequest.getParams();
if (params != null && !params.isEmpty()) {
// 注意get等不支持设置entity需要更新拼接之后的URL,但是url变量没有更新
httpRequestBase.setURI(URI.create(buildUrl(url, params, httpRequest.getEncoding())));
}
}
return httpClient.execute(httpRequestBase);
}
/**
* 构建 Url
*
* @param url 请求地址
* @param params 参数
* @return 拼接之后的地址
*/
public static String buildUrl(String url, Map<String, String> params) {
try {
return buildUrl(url, params, EncodeConstants.ENCODING_UTF_8);
} catch (UnsupportedEncodingException ignore) {
}
return url;
}
/**
* 构建 Url
*
* @param url 请求地址
* @param params 参数
* @return 拼接之后的地址
* @throws UnsupportedEncodingException 不支持的编码
*/
private static String buildUrl(String url, Map<String, String> params, String paramsEncoding) throws UnsupportedEncodingException {
if (params == null || params.isEmpty()) {
return url;
}
URIBuilder builder;
try {
builder = new URIBuilder(url);
for (Map.Entry<String, String> entry : params.entrySet()) {
String key = URLEncoder.encode(entry.getKey(), paramsEncoding);
String value = URLEncoder.encode(entry.getValue(), paramsEncoding);
builder.setParameter(key, value);
}
return builder.build().toString();
} catch (URISyntaxException e) {
LogKit.debug("Error to build url, please check the arguments.");
}
return url;
}
}

57
src/main/java/com/fr/plugin/xxx/provider/UsersTableDataDefine.java

@ -0,0 +1,57 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: WechatTableDataDefine
* Author: xxx
* Date: 2021/12/8 16:41
*/
package com.fr.plugin.xxx.provider;
import com.fanruan.api.i18n.I18nKit;
import com.fr.base.TableData;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.fun.ServerTableDataDefineProvider;
import com.fr.design.fun.impl.AbstractTableDataDefineProvider;
import com.fr.plugin.xxx.data.UsersTableData;
import com.fr.plugin.xxx.ui.UsersTableDataPane;
/**
* <Function Description><br>
* <WechatTableDataDefine>
*
* @author xxx
* @since 1.0.0
*/
public class UsersTableDataDefine extends AbstractTableDataDefineProvider implements ServerTableDataDefineProvider {
public static final String ICON_PATH = "/com/fr/plugin/xxx/images/logo16.png";
@Override
public Class<? extends TableData> classForTableData() {
return UsersTableData.class;
}
@Override
public Class<? extends TableData> classForInitTableData() {
return UsersTableData.class;
}
@Override
public Class<? extends AbstractTableDataPane> appearanceForTableData() {
return UsersTableDataPane.class;
}
@Override
public String nameForTableData() {
return I18nKit.getLocText("Plugin-xxx_Users_Table_Data");
}
@Override
public String prefixForTableData() {
return I18nKit.getLocText("Plugin-xxx_Users_Table_Data");
}
@Override
public String iconPathForTableData() {
return ICON_PATH;
}
}

52
src/main/java/com/fr/plugin/xxx/ui/UsersTableDataPane.java

@ -0,0 +1,52 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: WechatTableDataPane
* Author: xxx
* Date: 2021/12/8 19:19
*/
package com.fr.plugin.xxx.ui;
import com.fanruan.api.i18n.I18nKit;
import com.fr.plugin.xxx.data.UsersTableData;
import com.fr.script.Calculator;
import com.fr.stable.ParameterProvider;
import java.util.List;
/**
* <Function Description><br>
* <UsersTableDataPane>
*
* @author xxx
* @since 1.0.0
*/
public class UsersTableDataPane extends WebBaseTableDataPane<UsersTableData> {
public UsersTableDataPane() {
super();
}
@Override
public void populateBean(UsersTableData data) {
if (data == null) {
return;
}
Calculator c = Calculator.createCalculator();
this.editorPane.populate(data.getParameters(c));
}
@Override
public UsersTableData updateBean() {
UsersTableData data = new UsersTableData();
List<ParameterProvider> parameterProviderList = this.editorPane.update();
ParameterProvider[] parameters = parameterProviderList.toArray(new ParameterProvider[0]);
data.setParameters(parameters);
return data;
}
@Override
protected String title4PopupWindow() {
return I18nKit.getLocText("Plugin-xxx_Query");
}
}

137
src/main/java/com/fr/plugin/xxx/ui/WebBaseTableDataPane.java

@ -0,0 +1,137 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: WebBaseTableDatapane
* Author: xxx
* Date: 2021/12/10 8:49
*/
package com.fr.plugin.xxx.ui;
import com.fanruan.api.design.DesignKit;
import com.fanruan.api.design.ui.action.UpdateAction;
import com.fanruan.api.design.ui.component.UIToolbar;
import com.fanruan.api.design.ui.component.table.UITableEditorPane;
import com.fanruan.api.design.ui.component.table.action.UITableEditAction;
import com.fanruan.api.design.ui.component.table.model.ParameterTableModel;
import com.fanruan.api.design.ui.component.table.model.UITableModelAdapter;
import com.fanruan.api.design.ui.toolbar.ToolBarDef;
import com.fanruan.api.design.work.BaseTableDataPane;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.util.IOKit;
import com.fr.base.TableData;
import com.fr.stable.ParameterProvider;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.URI;
/**
* <Function Description><br>
* <WebBaseTableDatapane>
*
* @author xxx
* @since 1.0.0
*/
public abstract class WebBaseTableDataPane<T extends TableData> extends BaseTableDataPane<T> {
public static final String ICON_HELP = "/com/fr/plugin/xxx/images/help.png";
public static final String ICON_PREVIEW = "/com/fr/design/images/m_file/preview.png";
public static final String ICON_REFRESH = "/com/fr/design/images/control/refresh.png";
public static final String HELP_URL = "https://help.finereport.com/index.php";
private static final String PREVIEW_BUTTON = I18nKit.getLocText("Plugin-xxx_Preview");
private static final String REFRESH_BUTTON = I18nKit.getLocText("Plugin-xxx_Refresh");
private static final String HELP_BUTTON = I18nKit.getLocText("Plugin-xxx_Help");
protected UITableEditorPane<ParameterProvider> editorPane;
public WebBaseTableDataPane() {
this.setLayout(new BorderLayout(4, 4));
Box box = new Box(BoxLayout.Y_AXIS);
JPanel northPane = new JPanel(new BorderLayout(4, 4));
JToolBar editToolBar = createToolBar();
northPane.add(editToolBar, BorderLayout.CENTER);
JToolBar editHelpBar = createHelpBar();
northPane.add(editHelpBar, BorderLayout.EAST);
northPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0));
UITableModelAdapter<ParameterProvider> model = new ParameterTableModel();
editorPane = new UITableEditorPane<ParameterProvider>(model);
box.add(northPane);
box.add(editorPane);
JPanel sqlSplitPane = new JPanel(new BorderLayout(4, 4));
sqlSplitPane.add(box, BorderLayout.CENTER);
this.add(sqlSplitPane, BorderLayout.CENTER);
}
private JToolBar createToolBar() {
ToolBarDef toolBarDef = new ToolBarDef();
toolBarDef.addShortCut(new PreviewAction());
UIToolbar editToolBar = ToolBarDef.createJToolBar();
toolBarDef.updateToolBar(editToolBar);
return editToolBar;
}
private JToolBar createHelpBar() {
ToolBarDef helpBarDef = new ToolBarDef();
helpBarDef.addShortCut(new HelpAction());
UIToolbar editHelpBar = ToolBarDef.createJToolBar();
helpBarDef.updateToolBar(editHelpBar);
return editHelpBar;
}
@Override
protected String title4PopupWindow() {
return I18nKit.getLocText("Plugin-xxx_Query");
}
private void refresh() {
java.util.List<ParameterProvider> existParameterList = editorPane.update();
ParameterProvider[] ps = existParameterList == null ? new ParameterProvider[0] : existParameterList.toArray(new ParameterProvider[0]);
editorPane.populate(ps);
}
private class PreviewAction extends UpdateAction {
public PreviewAction() {
this.setName(PREVIEW_BUTTON);
this.setMnemonic('P');
this.setSmallIcon(IOKit.readIcon(ICON_PREVIEW));
}
public void actionPerformed(ActionEvent evt) {
DesignKit.previewTableData(WebBaseTableDataPane.this.updateBean());
}
}
private class HelpAction extends UpdateAction {
public HelpAction() {
this.setName(HELP_BUTTON);
this.setMnemonic('P');
this.setSmallIcon(IOKit.readIcon(ICON_HELP));
}
public void actionPerformed(ActionEvent evt) {
try {
Desktop.getDesktop().browse(URI.create(HELP_URL));
} catch (IOException e1) {
LogKit.error(e1.getMessage(), e1);
}
}
}
protected class RefreshAction extends UITableEditAction {
public RefreshAction() {
this.setName(REFRESH_BUTTON);
this.setSmallIcon(IOKit.readIcon(ICON_REFRESH));
}
public void actionPerformed(ActionEvent e) {
refresh();
}
@Override
public void checkEnabled() {
}
}
}

60
src/main/java/com/fr/plugin/xxx/ui/WebQueryPane.java

@ -0,0 +1,60 @@
/*
* Copyright (C), 2018-2021
* Project: starter
* FileName: WechatQueryPane
* Author: xxx
* Date: 2021/12/14 15:32
*/
package com.fr.plugin.xxx.ui;
import com.fanruan.api.design.ui.component.UIButtonGroup;
import com.fanruan.api.design.ui.component.UILabel;
import com.fanruan.api.design.ui.container.BasicPane;
import com.fanruan.api.design.ui.layout.TableLayoutKit;
import com.fanruan.api.i18n.I18nKit;
import java.awt.*;
/**
* <Function Description><br>
* <WebQueryPane>
*
* @author xxx
* @since 1.0.0
*/
public class WebQueryPane extends BasicPane {
public static final String[] SEARCH_OPTIONS = new String[]{
I18nKit.getLocText("Plugin-xxx_Search_User"),
I18nKit.getLocText("Plugin-xxx_Search_Department")
};
private UIButtonGroup searchType;
public WebQueryPane() {
setLayout(new BorderLayout());
searchType = new UIButtonGroup<String[]>(SEARCH_OPTIONS);
searchType.setSelectedIndex(0);
Component[][] coms = new Component[][]{
{new UILabel(I18nKit.getLocText("Plugin-xxx_Search_Type") + ":"), searchType}
};
double p = TableLayoutKit.PREFERRED;
double f = TableLayoutKit.FILL;
double[] rowSize = {p};
double[] columnSize = {p, f};
add(TableLayoutKit.createTableLayoutPane(coms, rowSize, columnSize));
}
@Override
protected String title4PopupWindow() {
return I18nKit.getLocText("Plugin-xxx_Query");
}
public int getSearchType() {
return searchType.getSelectedIndex();
}
public void setSearchType(int searchType) {
this.searchType.setSelectedIndex(searchType);
}
}

133
src/main/java/com/fr/plugin/xxx/util/Base64Utils.java

@ -0,0 +1,133 @@
package com.fr.plugin.xxx.util;
import com.fr.base.Base64;
import java.io.*;
public class Base64Utils {
/** */
/**
* 文件读取缓冲区大小
*/
private static final int CACHE_SIZE = 1024;
/** */
/**
* <p>
* BASE64字符串解码为二进制数据
* </p>
*
* @param base64
* @return
* @throws Exception
*/
public static byte[] decode(String base64) throws Exception {
return Base64.decode(base64);
}
/** */
/**
* <p>
* 二进制数据编码为BASE64字符串
* </p>
*
* @param bytes
* @return
* @throws Exception
*/
public static String encode(byte[] bytes) throws Exception {
return new String(Base64.encode(bytes));
}
/** */
/**
* <p>
* 将文件编码为BASE64字符串
* </p>
* <p>
* 大文件慎用可能会导致内存溢出
* </p>
*
* @param filePath 文件绝对路径
* @return
* @throws Exception
*/
public static String encodeFile(String filePath) throws Exception {
byte[] bytes = fileToByte(filePath);
return encode(bytes);
}
/** */
/**
* <p>
* BASE64字符串转回文件
* </p>
*
* @param filePath 文件绝对路径
* @param base64 编码字符串
* @throws Exception
*/
public static void decodeToFile(String filePath, String base64) throws Exception {
byte[] bytes = decode(base64);
byteArrayToFile(bytes, filePath);
}
/** */
/**
* <p>
* 文件转换为二进制数组
* </p>
*
* @param filePath 文件路径
* @return
* @throws Exception
*/
public static byte[] fileToByte(String filePath) throws Exception {
byte[] data = new byte[0];
File file = new File(filePath);
if (file.exists()) {
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
byte[] cache = new byte[CACHE_SIZE];
int nRead = 0;
while ((nRead = in.read(cache)) != -1) {
out.write(cache, 0, nRead);
out.flush();
}
out.close();
in.close();
data = out.toByteArray();
}
return data;
}
/** */
/**
* <p>
* 二进制数据写文件
* </p>
*
* @param bytes 二进制数据
* @param filePath 文件生成目录
*/
public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
InputStream in = new ByteArrayInputStream(bytes);
File destFile = new File(filePath);
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
destFile.createNewFile();
OutputStream out = new FileOutputStream(destFile);
byte[] cache = new byte[CACHE_SIZE];
int nRead = 0;
while ((nRead = in.read(cache)) != -1) {
out.write(cache, 0, nRead);
out.flush();
}
out.close();
in.close();
}
}

310
src/main/java/com/fr/plugin/xxx/util/RSAUtils.java

@ -0,0 +1,310 @@
package com.fr.plugin.xxx.util;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSAUtils {
/** */
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/** */
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/** */
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/** */
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/** */
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/** */
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/** */
/**
* <p>
* 生成密钥对(公钥和私钥)
* </p>
*
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/** */
/**
* <p>
* 用私钥对信息生成数字签名
* </p>
*
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64Utils.encode(signature.sign());
}
/** */
/**
* <p>
* 校验数字签名
* </p>
*
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
* @return
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64Utils.decode(sign));
}
/** */
/**
* <P>
* 私钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/** */
/**
* <p>
* 公钥解密
* </p>
*
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/** */
/**
* <p>
* 公钥加密
* </p>
*
* @param data 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/** */
/**
* <p>
* 私钥加密
* </p>
*
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/** */
/**
* <p>
* 获取私钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64Utils.encode(key.getEncoded());
}
/** */
/**
* <p>
* 获取公钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64Utils.encode(key.getEncoded());
}
}

BIN
src/main/resources/com/fr/plugin/xxx/images/help.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

BIN
src/main/resources/com/fr/plugin/xxx/images/logo16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

11
src/main/resources/com/fr/plugin/xxx/locale/lang.properties

@ -0,0 +1,11 @@
Plugin-igqh=API Dataset Plugin
Plugin-igqh_Group=API Dataset Plugin
Plugin-igqh_Licence_Expired=API Dataset Plugin Licence Expired
Plugin-igqh_Users_Table_Data=API Table Data
Plugin-igqh_Query=Query
Plugin-igqh_Help=Help
Plugin-igqh_Preview=Preview
Plugin-igqh_Refresh=Refresh
Plugin-igqh_Search_Type=Search Type
Plugin-igqh_Search_User=User
Plugin-igqh_Search_Department=Department

11
src/main/resources/com/fr/plugin/xxx/locale/lang_zh_CN.properties

@ -0,0 +1,11 @@
Plugin-igqh=API\u6570\u636E\u96C6\u63D2\u4EF6
Plugin-igqh_Group=API\u6570\u636E\u96C6\u63D2\u4EF6
Plugin-igqh_Licence_Expired=API\u6570\u636E\u96C6\u63D2\u4EF6\u8BB8\u53EF\u8FC7\u671F
Plugin-igqh_Users_Table_Data=API\u6570\u636E\u96C6
Plugin-igqh_Query=\u67E5\u8BE2
Plugin-igqh_Help=\u5E2E\u52A9\u6587\u6863
Plugin-igqh_Preview=\u9884\u89C8
Plugin-igqh_Refresh=\u5237\u65B0
Plugin-igqh_Search_Type=\u64CD\u4F5C\u79CD\u7C7B
Plugin-igqh_Search_User=\u7528\u6237
Plugin-igqh_Search_Department=\u90E8\u95E8
Loading…
Cancel
Save