commit
7ee96edd3a
21 changed files with 1826 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||||||
|
# open-JSD-9778 |
||||||
|
|
||||||
|
JSD-9778 通过获取统计数据接口,实现程序数据集功能\ |
||||||
|
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||||
|
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||||
|
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 |
Binary file not shown.
Binary file not shown.
@ -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> |
Binary file not shown.
@ -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> |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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"); |
||||||
|
} |
||||||
|
} |
@ -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() { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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()); |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 817 B |
After Width: | Height: | Size: 1.1 KiB |
@ -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 |
@ -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…
Reference in new issue