commit
18fac20ffd
@ -1,33 +1,34 @@ |
|||||||
* [首页](/?t=1565165921486) |
* [首页](/?t=1565681110217) |
||||||
* 开发文档 |
* 开发文档 |
||||||
* [快速体验](files/10010_快速体验.md?t=1565165921490) |
* [快速体验](files/10010_快速体验.md?t=1565681110219) |
||||||
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1565165921508) |
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1565681110236) |
||||||
* [新增接口](files/10020_新增接口.md?t=1565165921508) |
* [新增接口](files/10020_新增接口.md?t=1565681110236) |
||||||
* [业务参数校验](files/10030_业务参数校验.md?t=1565165921509) |
* [业务参数校验](files/10030_业务参数校验.md?t=1565681110236) |
||||||
* [错误处理](files/10040_错误处理.md?t=1565165921509) |
* [错误处理](files/10040_错误处理.md?t=1565681110236) |
||||||
* [编写文档](files/10041_编写文档.md?t=1565165921509) |
* [编写文档](files/10041_编写文档.md?t=1565681110236) |
||||||
* [接口交互详解](files/10050_接口交互详解.md?t=1565165921509) |
* [接口交互详解](files/10050_接口交互详解.md?t=1565681110236) |
||||||
* [easyopen支持](files/10070_easyopen支持.md?t=1565165921509) |
* [easyopen支持](files/10070_easyopen支持.md?t=1565681110236) |
||||||
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1565165921509) |
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1565681110237) |
||||||
* [ISV管理](files/10085_ISV管理.md?t=1565165921509) |
* [ISV管理](files/10085_ISV管理.md?t=1565681110237) |
||||||
* [自定义路由](files/10086_自定义路由.md?t=1565165921509) |
* [自定义路由](files/10086_自定义路由.md?t=1565681110237) |
||||||
* [自定义返回结果](files/10087_自定义返回结果.md?t=1565165921510) |
* [自定义返回结果](files/10087_自定义返回结果.md?t=1565681110237) |
||||||
* [自定义过滤器](files/10088_自定义过滤器.md?t=1565165921510) |
* [自定义过滤器](files/10088_自定义过滤器.md?t=1565681110237) |
||||||
* [路由授权](files/10090_路由授权.md?t=1565165921510) |
* [路由授权](files/10090_路由授权.md?t=1565681110237) |
||||||
* [接口限流](files/10092_接口限流.md?t=1565165921510) |
* [接口限流](files/10092_接口限流.md?t=1565681110237) |
||||||
* [监控日志](files/10093_监控日志.md?t=1565165921510) |
* [监控日志](files/10093_监控日志.md?t=1565681110237) |
||||||
* [SDK开发](files/10095_SDK开发.md?t=1565165921510) |
* [SDK开发](files/10095_SDK开发.md?t=1565681110237) |
||||||
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1565165921510) |
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1565681110237) |
||||||
* [应用授权](files/10097_应用授权.md?t=1565165921510) |
* [应用授权](files/10097_应用授权.md?t=1565681110238) |
||||||
* [传统web开发](files/10100_传统web开发.md?t=1565165921510) |
* [传统web开发](files/10100_传统web开发.md?t=1565681110238) |
||||||
* [文件上传](files/10104_文件上传.md?t=1565165921510) |
* [文件上传](files/10104_文件上传.md?t=1565681110238) |
||||||
* [nacos注册中心](files/10106_nacos注册中心.md?t=1565165921510) |
* [nacos注册中心](files/10106_nacos注册中心.md?t=1565681110238) |
||||||
* [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1565165921511) |
* [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1565681110238) |
||||||
* [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1565165921511) |
* [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1565681110238) |
||||||
* [预发布灰度发布](files/10110_预发布灰度发布.md?t=1565165921511) |
* [预发布灰度发布](files/10110_预发布灰度发布.md?t=1565681110238) |
||||||
|
* [动态修改请求参数](files/10111_动态修改请求参数.md?t=1565681110238) |
||||||
* 原理分析 |
* 原理分析 |
||||||
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1565165921511) |
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1565681110238) |
||||||
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1565165921511) |
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1565681110238) |
||||||
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1565165921511) |
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1565681110238) |
||||||
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1565165921511) |
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1565681110239) |
||||||
* [常见问题](files/90100_常见问题.md?t=1565165921511) |
* [常见问题](files/90100_常见问题.md?t=1565681110239) |
||||||
|
@ -1 +1 @@ |
|||||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>SOP Admin</title><link href=static/css/chunk-elementUI.81cf475c.css rel=stylesheet><link href=static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=static/css/app.4f0872ef.css rel=stylesheet></head><body><noscript><strong>We're sorry but SOP Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function n(n){for(var r,c,a=n[0],f=n[1],i=n[2],l=0,d=[];l<a.length;l++)c=a[l],u[c]&&d.push(u[c][0]),u[c]=0;for(r in f)Object.prototype.hasOwnProperty.call(f,r)&&(e[r]=f[r]);h&&h(n);while(d.length)d.shift()();return o.push.apply(o,i||[]),t()}function t(){for(var e,n=0;n<o.length;n++){for(var t=o[n],r=!0,c=1;c<t.length;c++){var a=t[c];0!==u[a]&&(r=!1)}r&&(o.splice(n--,1),e=f(f.s=t[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function a(e){return f.p+"static/js/"+({}[e]||e)+"."+{"chunk-238a81e9":"5955f13d","chunk-25908fca":"ca176fa6","chunk-2d2085ef":"7c741493","chunk-2d221c34":"c8ef105a","chunk-34c76be7":"98e1e7e5","chunk-37401378":"4e39ec9b","chunk-6f78c9fe":"f1ed64fa","chunk-73b2dcec":"14f248eb","chunk-9b31c83a":"2758df30","chunk-9f479afe":"2db777db","chunk-ea2e58a4":"f3f85b0e"}[e]+".js"}function f(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.e=function(e){var n=[],t={"chunk-238a81e9":1,"chunk-25908fca":1,"chunk-34c76be7":1,"chunk-37401378":1,"chunk-73b2dcec":1,"chunk-9b31c83a":1,"chunk-ea2e58a4":1};c[e]?n.push(c[e]):0!==c[e]&&t[e]&&n.push(c[e]=new Promise(function(n,t){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-238a81e9":"e8e2beee","chunk-25908fca":"89ab33e8","chunk-2d2085ef":"31d6cfe0","chunk-2d221c34":"31d6cfe0","chunk-34c76be7":"f531fb07","chunk-37401378":"a43114f3","chunk-6f78c9fe":"31d6cfe0","chunk-73b2dcec":"99cf6327","chunk-9b31c83a":"3b12267b","chunk-9f479afe":"31d6cfe0","chunk-ea2e58a4":"d10599db"}[e]+".css",u=f.p+r,o=document.getElementsByTagName("link"),a=0;a<o.length;a++){var i=o[a],l=i.getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(l===r||l===u))return n()}var d=document.getElementsByTagName("style");for(a=0;a<d.length;a++){i=d[a],l=i.getAttribute("data-href");if(l===r||l===u)return n()}var h=document.createElement("link");h.rel="stylesheet",h.type="text/css",h.onload=n,h.onerror=function(n){var r=n&&n.target&&n.target.src||u,o=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");o.code="CSS_CHUNK_LOAD_FAILED",o.request=r,delete c[e],h.parentNode.removeChild(h),t(o)},h.href=u;var s=document.getElementsByTagName("head")[0];s.appendChild(h)}).then(function(){c[e]=0}));var r=u[e];if(0!==r)if(r)n.push(r[2]);else{var o=new Promise(function(n,t){r=u[e]=[n,t]});n.push(r[2]=o);var i,l=document.createElement("script");l.charset="utf-8",l.timeout=120,f.nc&&l.setAttribute("nonce",f.nc),l.src=a(e),i=function(n){l.onerror=l.onload=null,clearTimeout(d);var t=u[e];if(0!==t){if(t){var r=n&&("load"===n.type?"missing":n.type),c=n&&n.target&&n.target.src,o=new Error("Loading chunk "+e+" failed.\n("+r+": "+c+")");o.type=r,o.request=c,t[1](o)}u[e]=void 0}};var d=setTimeout(function(){i({type:"timeout",target:l})},12e4);l.onerror=l.onload=i,document.head.appendChild(l)}return Promise.all(n)},f.m=e,f.c=r,f.d=function(e,n,t){f.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},f.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,n){if(1&n&&(e=f(e)),8&n)return e;if(4&n&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)f.d(t,r,function(n){return e[n]}.bind(null,r));return t},f.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return f.d(n,"a",n),n},f.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},f.p="",f.oe=function(e){throw console.error(e),e};var i=window["webpackJsonp"]=window["webpackJsonp"]||[],l=i.push.bind(i);i.push=n,i=i.slice();for(var d=0;d<i.length;d++)n(i[d]);var h=l;t()})([]);</script><script src=static/js/chunk-elementUI.8ebdfbab.js></script><script src=static/js/chunk-libs.9cf9cc40.js></script><script src=static/js/app.8145abe4.js></script></body></html> |
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=favicon.ico><title>SOP Admin</title><link href=static/css/chunk-elementUI.81cf475c.css rel=stylesheet><link href=static/css/chunk-libs.3dfb7769.css rel=stylesheet><link href=static/css/app.4f0872ef.css rel=stylesheet></head><body><noscript><strong>We're sorry but SOP Admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script>(function(e){function n(n){for(var r,c,a=n[0],f=n[1],i=n[2],l=0,h=[];l<a.length;l++)c=a[l],u[c]&&h.push(u[c][0]),u[c]=0;for(r in f)Object.prototype.hasOwnProperty.call(f,r)&&(e[r]=f[r]);d&&d(n);while(h.length)h.shift()();return o.push.apply(o,i||[]),t()}function t(){for(var e,n=0;n<o.length;n++){for(var t=o[n],r=!0,c=1;c<t.length;c++){var a=t[c];0!==u[a]&&(r=!1)}r&&(o.splice(n--,1),e=f(f.s=t[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function a(e){return f.p+"static/js/"+({}[e]||e)+"."+{"chunk-238a81e9":"5955f13d","chunk-25908fca":"ca176fa6","chunk-2d2085ef":"7c741493","chunk-2d221c34":"c8ef105a","chunk-34c76be7":"98e1e7e5","chunk-37401378":"4e39ec9b","chunk-6f78c9fe":"f1ed64fa","chunk-73b2dcec":"14f248eb","chunk-9b31c83a":"2758df30","chunk-9f479afe":"53fe8d4e","chunk-ea2e58a4":"f3f85b0e"}[e]+".js"}function f(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.e=function(e){var n=[],t={"chunk-238a81e9":1,"chunk-25908fca":1,"chunk-34c76be7":1,"chunk-37401378":1,"chunk-73b2dcec":1,"chunk-9b31c83a":1,"chunk-ea2e58a4":1};c[e]?n.push(c[e]):0!==c[e]&&t[e]&&n.push(c[e]=new Promise(function(n,t){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-238a81e9":"e8e2beee","chunk-25908fca":"89ab33e8","chunk-2d2085ef":"31d6cfe0","chunk-2d221c34":"31d6cfe0","chunk-34c76be7":"f531fb07","chunk-37401378":"a43114f3","chunk-6f78c9fe":"31d6cfe0","chunk-73b2dcec":"99cf6327","chunk-9b31c83a":"3b12267b","chunk-9f479afe":"31d6cfe0","chunk-ea2e58a4":"d10599db"}[e]+".css",u=f.p+r,o=document.getElementsByTagName("link"),a=0;a<o.length;a++){var i=o[a],l=i.getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(l===r||l===u))return n()}var h=document.getElementsByTagName("style");for(a=0;a<h.length;a++){i=h[a],l=i.getAttribute("data-href");if(l===r||l===u)return n()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=n,d.onerror=function(n){var r=n&&n.target&&n.target.src||u,o=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");o.code="CSS_CHUNK_LOAD_FAILED",o.request=r,delete c[e],d.parentNode.removeChild(d),t(o)},d.href=u;var s=document.getElementsByTagName("head")[0];s.appendChild(d)}).then(function(){c[e]=0}));var r=u[e];if(0!==r)if(r)n.push(r[2]);else{var o=new Promise(function(n,t){r=u[e]=[n,t]});n.push(r[2]=o);var i,l=document.createElement("script");l.charset="utf-8",l.timeout=120,f.nc&&l.setAttribute("nonce",f.nc),l.src=a(e),i=function(n){l.onerror=l.onload=null,clearTimeout(h);var t=u[e];if(0!==t){if(t){var r=n&&("load"===n.type?"missing":n.type),c=n&&n.target&&n.target.src,o=new Error("Loading chunk "+e+" failed.\n("+r+": "+c+")");o.type=r,o.request=c,t[1](o)}u[e]=void 0}};var h=setTimeout(function(){i({type:"timeout",target:l})},12e4);l.onerror=l.onload=i,document.head.appendChild(l)}return Promise.all(n)},f.m=e,f.c=r,f.d=function(e,n,t){f.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},f.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,n){if(1&n&&(e=f(e)),8&n)return e;if(4&n&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)f.d(t,r,function(n){return e[n]}.bind(null,r));return t},f.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return f.d(n,"a",n),n},f.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},f.p="",f.oe=function(e){throw console.error(e),e};var i=window["webpackJsonp"]=window["webpackJsonp"]||[],l=i.push.bind(i);i.push=n,i=i.slice();for(var h=0;h<i.length;h++)n(i[h]);var d=l;t()})([]);</script><script src=static/js/chunk-elementUI.8ebdfbab.js></script><script src=static/js/chunk-libs.9cf9cc40.js></script><script src=static/js/app.8145abe4.js></script></body></html> |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,280 @@ |
|||||||
|
package com.gitee.sop.test; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON; |
||||||
|
import com.gitee.sop.test.alipay.AlipayApiException; |
||||||
|
import com.gitee.sop.test.alipay.AlipaySignature; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.text.SimpleDateFormat; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* 简易客户端 |
||||||
|
* |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class Client { |
||||||
|
/** |
||||||
|
* http请求工具 |
||||||
|
*/ |
||||||
|
private static HttpTool httpTool = new HttpTool(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求url |
||||||
|
*/ |
||||||
|
private String url; |
||||||
|
|
||||||
|
/** |
||||||
|
* 平台提供的appKey |
||||||
|
*/ |
||||||
|
private String appId; |
||||||
|
|
||||||
|
/** |
||||||
|
* 平台提供的私钥 |
||||||
|
*/ |
||||||
|
private String privateKey; |
||||||
|
|
||||||
|
/** |
||||||
|
* 请求成功后处理 |
||||||
|
*/ |
||||||
|
private Callback callback; |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建一个客户端 |
||||||
|
* |
||||||
|
* @param url 请求url |
||||||
|
* @param appId 平台提供的appKey |
||||||
|
* @param privateKey 平台提供的私钥 |
||||||
|
*/ |
||||||
|
public Client(String url, String appId, String privateKey) { |
||||||
|
this.url = url; |
||||||
|
this.appId = appId; |
||||||
|
this.privateKey = privateKey; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建一个客户端 |
||||||
|
* |
||||||
|
* @param url 请求url |
||||||
|
* @param appId 平台提供的appKey |
||||||
|
* @param privateKey 平台提供的私钥 |
||||||
|
* @param callback 请求成功后处理 |
||||||
|
*/ |
||||||
|
public Client(String url, String appId, String privateKey, Callback callback) { |
||||||
|
this.url = url; |
||||||
|
this.appId = appId; |
||||||
|
this.privateKey = privateKey; |
||||||
|
this.callback = callback; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 发送请求 |
||||||
|
* @param requestBuilder 请求信息 |
||||||
|
* @return 返回结果 |
||||||
|
*/ |
||||||
|
public String execute(RequestBuilder requestBuilder) { |
||||||
|
RequestInfo requestInfo = requestBuilder.build(appId, privateKey); |
||||||
|
HttpTool.HTTPMethod httpMethod = requestInfo.getHttpMethod(); |
||||||
|
boolean postJson = requestInfo.isPostJson(); |
||||||
|
Map<String, ?> form = requestInfo.getForm(); |
||||||
|
Map<String, String> header = requestInfo.getHeader(); |
||||||
|
String requestUrl = requestInfo.getUrl() != null ? requestInfo.getUrl() : url; |
||||||
|
String responseData = null; |
||||||
|
try { |
||||||
|
// 发送请求
|
||||||
|
if (httpMethod == HttpTool.HTTPMethod.POST && postJson) { |
||||||
|
responseData = httpTool.requestJson(requestUrl, JSON.toJSONString(form), header); |
||||||
|
} else { |
||||||
|
responseData = httpTool.request(requestUrl, form, header, httpMethod); |
||||||
|
} |
||||||
|
} catch (IOException e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
Callback call = requestBuilder.getCallback(); |
||||||
|
if (call == null) { |
||||||
|
call = this.callback; |
||||||
|
} |
||||||
|
if (call != null) { |
||||||
|
call.callback(requestInfo, responseData); |
||||||
|
} |
||||||
|
return responseData; |
||||||
|
} |
||||||
|
|
||||||
|
public interface Callback { |
||||||
|
void callback(RequestInfo requestInfo, String responseData); |
||||||
|
} |
||||||
|
|
||||||
|
public static class RequestBuilder { |
||||||
|
private static final String DEFAULT_VERSION = "1.0"; |
||||||
|
|
||||||
|
private String url; |
||||||
|
private String method; |
||||||
|
private String version = DEFAULT_VERSION; |
||||||
|
private Map<String, String> bizContent; |
||||||
|
private HttpTool.HTTPMethod httpMethod; |
||||||
|
private Map<String, String> header; |
||||||
|
private boolean ignoreSign; |
||||||
|
private boolean postJson; |
||||||
|
private Callback callback; |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置请求url,如果指定了将会优先使用,不指定默认使用Client中的url |
||||||
|
* |
||||||
|
* @param url url |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder url(String url) { |
||||||
|
this.url = url; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置方法名 |
||||||
|
* |
||||||
|
* @param method 方法名 |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder method(String method) { |
||||||
|
this.method = method; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置版本号 |
||||||
|
* |
||||||
|
* @param version 版本号 |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder version(String version) { |
||||||
|
this.version = version; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置业务参数 |
||||||
|
* |
||||||
|
* @param bizContent 业务参数 |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder bizContent(Map<String, String> bizContent) { |
||||||
|
this.bizContent = bizContent; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置请求方法 |
||||||
|
* |
||||||
|
* @param httpMethod 请求方法 |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder httpMethod(HttpTool.HTTPMethod httpMethod) { |
||||||
|
this.httpMethod = httpMethod; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置请求头 |
||||||
|
* |
||||||
|
* @param header 请求头 |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder header(Map<String, String> header) { |
||||||
|
this.header = header; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否忽略签名验证 |
||||||
|
* |
||||||
|
* @param ignoreSign 设置true,不会构建sign字段 |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder ignoreSign(boolean ignoreSign) { |
||||||
|
this.ignoreSign = ignoreSign; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否是json请求 |
||||||
|
* |
||||||
|
* @param postJson 设置true,请求方式变成json(application/json) |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder postJson(boolean postJson) { |
||||||
|
this.postJson = postJson; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置请求成功处理 |
||||||
|
* |
||||||
|
* @param callback 回调处理 |
||||||
|
* @return 返回RequestBuilder |
||||||
|
*/ |
||||||
|
public RequestBuilder callback(Callback callback) { |
||||||
|
this.callback = callback; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public Callback getCallback() { |
||||||
|
return callback; |
||||||
|
} |
||||||
|
|
||||||
|
public RequestInfo build(String appId, String privateKey) { |
||||||
|
// 公共请求参数
|
||||||
|
Map<String, String> params = new HashMap<String, String>(); |
||||||
|
params.put("app_id", appId); |
||||||
|
if (method != null) { |
||||||
|
params.put("method", method); |
||||||
|
} |
||||||
|
if (version != null) { |
||||||
|
params.put("version", version); |
||||||
|
} |
||||||
|
params.put("format", "json"); |
||||||
|
params.put("charset", "utf-8"); |
||||||
|
params.put("sign_type", "RSA2"); |
||||||
|
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); |
||||||
|
|
||||||
|
// 业务参数
|
||||||
|
params.put("biz_content", JSON.toJSONString(bizContent == null ? Collections.emptyMap() : bizContent)); |
||||||
|
|
||||||
|
if (!ignoreSign) { |
||||||
|
String content = AlipaySignature.getSignContent(params); |
||||||
|
String sign = null; |
||||||
|
try { |
||||||
|
sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8"); |
||||||
|
} catch (AlipayApiException e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
params.put("sign", sign); |
||||||
|
} |
||||||
|
|
||||||
|
RequestInfo requestInfo = new RequestInfo(); |
||||||
|
requestInfo.setUrl(url); |
||||||
|
requestInfo.setMethod(method); |
||||||
|
requestInfo.setVersion(version); |
||||||
|
requestInfo.setForm(params); |
||||||
|
requestInfo.setHeader(header); |
||||||
|
requestInfo.setPostJson(postJson); |
||||||
|
requestInfo.setHttpMethod(httpMethod); |
||||||
|
return requestInfo; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Data |
||||||
|
public static class RequestInfo { |
||||||
|
private String url; |
||||||
|
private String method; |
||||||
|
private String version; |
||||||
|
private boolean postJson; |
||||||
|
private Map<String, ?> form; |
||||||
|
private Map<String, String> header; |
||||||
|
private HttpTool.HTTPMethod httpMethod; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,219 @@ |
|||||||
|
package com.gitee.sop.test; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON; |
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import org.junit.Assert; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Optional; |
||||||
|
import java.util.concurrent.CountDownLatch; |
||||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||||
|
|
||||||
|
/** |
||||||
|
* 涵盖所有测试情况,发版前运行这个类,确保功能没有问题。 |
||||||
|
* |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
public class AllInOneTest extends TestBase { |
||||||
|
|
||||||
|
String url = "http://localhost:8081/api"; |
||||||
|
String appId = "2019032617262200001"; |
||||||
|
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ="; |
||||||
|
|
||||||
|
private Client client = new Client(url, appId, privateKey, AllInOneTest::assertResult); |
||||||
|
|
||||||
|
/** |
||||||
|
* 以get方式提交 |
||||||
|
*/ |
||||||
|
public void testGet() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("alipay.story.get") |
||||||
|
.version("1.0") |
||||||
|
.bizContent(new BizContent().add("id", "1").add("name", "葫芦娃")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.GET); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 以表单方式提交(application/x-www-form-urlencoded) |
||||||
|
*/ |
||||||
|
public void testPostForm() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("alipay.story.get") |
||||||
|
.version("1.0") |
||||||
|
.bizContent(new BizContent().add("id", "1").add("name", "葫芦娃")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.POST); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 以json方式提交(application/json) |
||||||
|
*/ |
||||||
|
public void testPostJSON() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("alipay.story.get") |
||||||
|
.version("1.0") |
||||||
|
// 以json方式提交
|
||||||
|
.postJson(true) |
||||||
|
.bizContent(new BizContent().add("id", "1").add("name", "葫芦娃")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.POST); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 测试feign。gateway -> book-service(consumer) -> story-service(provider) |
||||||
|
*/ |
||||||
|
public void testFeign() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("alipay.book.story.get") |
||||||
|
.version("1.0") |
||||||
|
.bizContent(new BizContent()) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.GET); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 测试dubbo服务,book会调用story提供的服务。参见:DemoConsumerController.java |
||||||
|
*/ |
||||||
|
public void testDubbo() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("dubbo.story.get") |
||||||
|
.version("1.0") |
||||||
|
.bizContent(new BizContent().add("id", "222")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.GET); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 忽略验证,不校验签名,只需传接口名、版本号、业务参数 |
||||||
|
*/ |
||||||
|
public void testIgnoreSign() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("story.get") |
||||||
|
.version("2.1") |
||||||
|
.ignoreSign(true) |
||||||
|
.bizContent(new BizContent().add("id", "222").add("name", "忽略222")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.GET); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* JSR-303参数校验 |
||||||
|
*/ |
||||||
|
public void testJSR303() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("goods.add") |
||||||
|
.version("1.0") |
||||||
|
.bizContent(new BizContent().add("goods_name", "iphone6").add("goods_remark", "iphone6").add("goods_comment", "1")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.POST); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 测试是否有权限访问,可在sop-admin中设置权限 |
||||||
|
*/ |
||||||
|
public void testPermission() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("permission.story.get") |
||||||
|
.version("1.0") |
||||||
|
.bizContent(new BizContent()) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.GET); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 演示将接口名版本号跟在url后面,规则:http://host:port/{method}/{version}/
|
||||||
|
*/ |
||||||
|
public void testRestful() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.url("http://localhost:8081/alipay.story.get/1.0/") |
||||||
|
.bizContent(new BizContent().add("name", "name111")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.GET); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 验证中文乱码问题 |
||||||
|
*/ |
||||||
|
public void testString() { |
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("story.string.get") |
||||||
|
.version("1.0") |
||||||
|
.bizContent(new BizContent().add("name", "name111")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.GET) |
||||||
|
.callback((requestInfo, responseData) -> { |
||||||
|
JSONObject jsonObject = JSON.parseObject(responseData); |
||||||
|
JSONObject data = jsonObject.getJSONObject("story_string_get_response"); |
||||||
|
Assert.assertEquals("海底小纵队", data.getString("name")); |
||||||
|
}); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 限流测试,根据路由id限流 |
||||||
|
* |
||||||
|
* @throws InterruptedException |
||||||
|
*/ |
||||||
|
public void testLimit() throws InterruptedException { |
||||||
|
int threadsCount = 10; // threadsCount个线程同时提交
|
||||||
|
final CountDownLatch countDownLatch = new CountDownLatch(1); |
||||||
|
final CountDownLatch count = new CountDownLatch(threadsCount); |
||||||
|
final AtomicInteger success = new AtomicInteger(); |
||||||
|
for (int i = 0; i < threadsCount; i++) { |
||||||
|
new Thread(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
try { |
||||||
|
countDownLatch.await(); // 等在这里,执行countDownLatch.countDown();集体触发
|
||||||
|
// 业务方法
|
||||||
|
Client.RequestBuilder requestBuilder = new Client.RequestBuilder() |
||||||
|
.method("alipay.story.get") |
||||||
|
.version("1.2") |
||||||
|
.bizContent(new BizContent().add("id", "1").add("name", "葫芦娃")) |
||||||
|
.httpMethod(HttpTool.HTTPMethod.GET); |
||||||
|
|
||||||
|
client.execute(requestBuilder); |
||||||
|
success.incrementAndGet(); |
||||||
|
} catch (Exception e) { |
||||||
|
} finally { |
||||||
|
count.countDown(); |
||||||
|
} |
||||||
|
} |
||||||
|
}).start(); |
||||||
|
} |
||||||
|
countDownLatch.countDown(); |
||||||
|
count.await(); |
||||||
|
System.out.println("成功次数:" + success); |
||||||
|
} |
||||||
|
|
||||||
|
class BizContent extends HashMap<String, String> { |
||||||
|
public BizContent add(String key, String value) { |
||||||
|
this.put(key, value); |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void assertResult(Client.RequestInfo requestInfo, String responseData) { |
||||||
|
System.out.println(responseData); |
||||||
|
String method = requestInfo.getMethod(); |
||||||
|
if (method == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String node = method.replace('.', '_') + "_response"; |
||||||
|
JSONObject jsonObject = JSON.parseObject(responseData).getJSONObject(node); |
||||||
|
String code = Optional.ofNullable(jsonObject).map(json -> json.getString("code")).orElse("20000"); |
||||||
|
Assert.assertEquals("10000", code); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue