tanghc 6 years ago
parent 0db229053f
commit 2953f7dc77
  1. 4
      changelog.md
  2. 46
      doc/docs/_sidebar.md
  3. 8
      doc/docs/files/10097_应用授权.md
  4. 3
      doc/docs/files/10100_对接前端.md
  5. 2
      sop-common/pom.xml
  6. 4
      sop-common/sop-gateway-common/pom.xml
  7. 4
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java
  8. 3
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/ValidateFilter.java
  9. 14
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/param/GatewayParamBuilder.java
  10. 8
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/ApiParam.java
  11. 22
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/param/BaseParamBuilder.java
  12. 5
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java
  13. 9
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RequestUtil.java
  14. 6
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreValidateFilter.java
  15. 67
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java
  16. 4
      sop-common/sop-service-common/pom.xml
  17. 2
      sop-example/sop-auth/pom.xml
  18. 2
      sop-example/sop-auth/src/main/java/com/gitee/sop/sopauth/auth/impl/OAuth2ServiceImpl.java
  19. 6
      sop-example/sop-auth/src/main/java/com/gitee/sop/sopauth/controller/CallbackController.java
  20. 2
      sop-example/sop-book/sop-book-web/pom.xml
  21. 2
      sop-example/sop-easyopen/pom.xml
  22. 2
      sop-example/sop-springmvc/pom.xml
  23. 2
      sop-example/sop-story/sop-story-web/pom.xml
  24. 2
      sop-gateway/pom.xml
  25. 31
      sop-gateway/src/main/java/com/gitee/sop/gateway/RedirectController.java
  26. 61
      sop-test/src/test/java/com/gitee/sop/RestUrlTest.java

@ -1,5 +1,9 @@
# changelog
## 1.7.1
- 支持接口名版本号放在url后面
## 1.7.0
- 可自定义数据节点名称

@ -1,25 +1,25 @@
* [首页](/?t=1557111672942)
* [首页](/?t=1557125401034)
* 开发文档
* [快速体验](files/10010_快速体验.md?t=1557111672945)
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1557111672960)
* [新增接口](files/10020_新增接口.md?t=1557111672961)
* [业务参数校验](files/10030_业务参数校验.md?t=1557111672961)
* [错误处理](files/10040_错误处理.md?t=1557111672961)
* [编写文档](files/10041_编写文档.md?t=1557111672961)
* [接口交互详解](files/10050_接口交互详解.md?t=1557111672961)
* [easyopen支持](files/10070_easyopen支持.md?t=1557111672961)
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1557111672961)
* [ISV管理](files/10085_ISV管理.md?t=1557111672961)
* [路由授权](files/10090_路由授权.md?t=1557111672961)
* [接口限流](files/10092_接口限流.md?t=1557111672961)
* [SDK开发](files/10095_SDK开发.md?t=1557111672962)
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1557111672962)
* [应用授权](files/10097_应用授权.md?t=1557111672962)
* [更改数据节点名称](files/10099_更改数据节点名称.md?t=1557111672962)
* [对接前端](files/10100_对接前端.md?t=1557111672962)
* [快速体验](files/10010_快速体验.md?t=1557125401037)
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1557125401053)
* [新增接口](files/10020_新增接口.md?t=1557125401053)
* [业务参数校验](files/10030_业务参数校验.md?t=1557125401053)
* [错误处理](files/10040_错误处理.md?t=1557125401053)
* [编写文档](files/10041_编写文档.md?t=1557125401053)
* [接口交互详解](files/10050_接口交互详解.md?t=1557125401053)
* [easyopen支持](files/10070_easyopen支持.md?t=1557125401053)
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1557125401053)
* [ISV管理](files/10085_ISV管理.md?t=1557125401053)
* [路由授权](files/10090_路由授权.md?t=1557125401054)
* [接口限流](files/10092_接口限流.md?t=1557125401054)
* [SDK开发](files/10095_SDK开发.md?t=1557125401054)
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1557125401054)
* [应用授权](files/10097_应用授权.md?t=1557125401054)
* [更改数据节点名称](files/10099_更改数据节点名称.md?t=1557125401054)
* [对接前端](files/10100_对接前端.md?t=1557125401054)
* 原理分析
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1557111672962)
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1557111672962)
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1557111672962)
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1557111672963)
* [常见问题](files/90100_常见问题.md?t=1557111672963)
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1557125401054)
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1557125401054)
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1557125401054)
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1557125401055)
* [常见问题](files/90100_常见问题.md?t=1557125401055)

@ -24,8 +24,16 @@ http://openauth.yourdomain.com/oauth2/appToAppAuth?app_id=2019032617262200001&re
| app_id | 开发者应用的AppId | String | 是 | 开发者应用的AppId | 2015101400446982 |
| redirect_uri | 回调页面 | String | 是 | 参数需要UrlEncode | http%3A%2F%2Fexample.com |
- 第二步:获取code
授权成功后,会跳转至开发者定义的回调页面(即redirect_uri参数对应的url),在回调页面请求中会带上当次授权的授权码code和开发者的app_id,示例如下:
http://www.xxx.com/oauth2callback?app_id=2015101400446982&code=ca34ea491e7146cc87d25fca24c4cD11
- 第三步:使用code换取app_auth_token
接口名称:open.auth.token.app
开发者通过code可以换取app_auth_token、授权用户的userId。

@ -144,4 +144,7 @@ $(function () {
})
```
1.7.1开始支持接口名版本号放在url后面,规则:`http://host:port/{method}/{version}/`(最后的`/`不能少),如:`http://localhost:8081/story.demo.get/1.0/`
等同于:`http://localhost:8081/api?method=story.demo.get&version=1.0`。
把接口名版本号放在url后面的好处是调用接口一目了然,在浏览器F12调试的时候特别有用,可以一眼看到调用了哪些接口,否则将会看到全部都是api请求,需要点开查看request header才能知道到底调用了哪个接口

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>

@ -5,11 +5,11 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>sop-gateway-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>sop-gateway-common</name>

@ -15,6 +15,10 @@ public class SopConstants {
public static final String DEFAULT_SIGN_METHOD = "md5";
public static final String EMPTY_JSON = "{}";
public static final String REDIRECT_METHOD_KEY = "r-method";
public static final String REDIRECT_VERSION_KEY = "r-version";
/**
* 在拦截器中调用获取参数
* String cachedBody = (String)exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_OBJECT_KEY);

@ -2,11 +2,8 @@ package com.gitee.sop.gatewaycommon.gateway.filter;
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
import com.gitee.sop.gatewaycommon.bean.ApiContext;
import com.gitee.sop.gatewaycommon.bean.RouteConfig;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.exception.ApiException;
import com.gitee.sop.gatewaycommon.manager.RouteConfigManager;
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
import com.gitee.sop.gatewaycommon.param.ApiParam;
import com.gitee.sop.gatewaycommon.util.RouteUtil;
import com.gitee.sop.gatewaycommon.validate.Validator;

@ -1,9 +1,7 @@
package com.gitee.sop.gatewaycommon.gateway.param;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.param.ApiParam;
import com.gitee.sop.gatewaycommon.param.ApiParamFactory;
import com.gitee.sop.gatewaycommon.param.ParamBuilder;
import com.gitee.sop.gatewaycommon.param.BaseParamBuilder;
import org.springframework.web.server.ServerWebExchange;
import java.util.Map;
@ -11,12 +9,10 @@ import java.util.Map;
/**
* @author tanghc
*/
public class GatewayParamBuilder implements ParamBuilder<ServerWebExchange> {
public class GatewayParamBuilder extends BaseParamBuilder<ServerWebExchange> {
@Override
public ApiParam build(ServerWebExchange exchange) {
Map<String, String> params = exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_FOR_MAP);
return ApiParamFactory.build(params);
public Map<String, String> buildRequestParams(ServerWebExchange request) {
return request.getAttribute(SopConstants.CACHE_REQUEST_BODY_FOR_MAP);
}
}

@ -208,4 +208,12 @@ public class ApiParam extends JSONObject implements Param {
public int hashCode() {
return super.hashCode();
}
public void setRestName(String restName) {
this.restName = restName;
}
public void setRestVersion(String restVersion) {
this.restVersion = restVersion;
}
}

@ -14,16 +14,26 @@ import java.util.Map;
* @author tanghc
*/
@Slf4j
public class ApiParamFactory {
public abstract class BaseParamBuilder<T> implements ParamBuilder<T> {
private ApiParamFactory(){}
public abstract Map<String, String> buildRequestParams(T ctx);
public static ApiParam build(Map<String, ?> params) {
ApiParam apiParam = new ApiParam();
for (Map.Entry<String, ?> entry : params.entrySet()) {
@Override
public ApiParam build(T ctx) {
ApiParam apiParam = this.newApiParam(ctx);
Map<String, String> requestParams = this.buildRequestParams(ctx);
for (Map.Entry<String, ?> entry : requestParams.entrySet()) {
apiParam.put(entry.getKey(), entry.getValue());
}
this.initOtherProperty(apiParam);
return apiParam;
}
protected ApiParam newApiParam(T ctx) {
return new ApiParam();
}
protected void initOtherProperty(ApiParam apiParam) {
RouteRepository<? extends TargetRoute> routeRepository = RouteRepositoryContext.getRouteRepository();
if (routeRepository == null) {
log.error("RouteRepositoryContext.setRouteRepository()方法未使用");
@ -35,6 +45,6 @@ public class ApiParamFactory {
throw ErrorEnum.ISV_INVALID_METHOD.getErrorMeta().getException();
}
apiParam.setIgnoreValidate(BooleanUtils.toBoolean(routeDefinition.getIgnoreValidate()));
return apiParam;
}
}

@ -91,9 +91,8 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
}
Object name = params.get(ParamNames.API_NAME);
Object version = params.get(ParamNames.VERSION_NAME);
if(name == null) {
// 随便生成一个name
name = System.currentTimeMillis();
if(name == null || version == null) {
return true;
}
TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(String.valueOf(name) + version);
if (targetRoute == null) {

@ -55,27 +55,24 @@ public class RequestUtil {
* @param request request对象
* @return 返回参数键值对
*/
public static Map<String, Object> convertRequestParamsToMap(HttpServletRequest request) {
public static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
Map<String, String[]> paramMap = request.getParameterMap();
if(paramMap == null || paramMap.isEmpty()) {
return Collections.emptyMap();
}
Map<String, Object> retMap = new HashMap<>(paramMap.size());
Map<String, String> retMap = new HashMap<>(paramMap.size());
Set<Map.Entry<String, String[]>> entrySet = paramMap.entrySet();
for (Map.Entry<String, String[]> entry : entrySet) {
String name = entry.getKey();
String[] values = entry.getValue();
if (values.length == 1) {
if (values.length >= 1) {
retMap.put(name, values[0]);
} else if (values.length > 1) {
retMap.put(name, values);
} else {
retMap.put(name, "");
}
}
return retMap;
}

@ -1,18 +1,14 @@
package com.gitee.sop.gatewaycommon.zuul.filter;
import com.gitee.sop.gatewaycommon.bean.ApiContext;
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
import com.gitee.sop.gatewaycommon.bean.RouteConfig;
import com.gitee.sop.gatewaycommon.bean.ApiContext;
import com.gitee.sop.gatewaycommon.exception.ApiException;
import com.gitee.sop.gatewaycommon.manager.RouteConfigManager;
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
import com.gitee.sop.gatewaycommon.param.ApiParam;
import com.gitee.sop.gatewaycommon.util.RouteUtil;
import com.gitee.sop.gatewaycommon.validate.Validator;
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
/**
* 前置校验

@ -1,23 +1,16 @@
package com.gitee.sop.gatewaycommon.zuul.param;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
import com.gitee.sop.gatewaycommon.param.ApiParam;
import com.gitee.sop.gatewaycommon.param.ApiParamFactory;
import com.gitee.sop.gatewaycommon.param.ApiUploadContext;
import com.gitee.sop.gatewaycommon.param.ParamBuilder;
import com.gitee.sop.gatewaycommon.param.BaseParamBuilder;
import com.gitee.sop.gatewaycommon.util.RequestUtil;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 参数解析默认实现
@ -25,30 +18,17 @@ import java.util.Set;
* @author tanghc
*/
@Slf4j
public class ZuulParamBuilder implements ParamBuilder<RequestContext> {
public class ZuulParamBuilder extends BaseParamBuilder<RequestContext> {
private static final String CONTENT_TYPE_MULTIPART = MediaType.MULTIPART_FORM_DATA_VALUE;
private static final String CONTENT_TYPE_JSON = MediaType.APPLICATION_JSON_VALUE;
private static final String CONTENT_TYPE_TEXT = MediaType.TEXT_PLAIN_VALUE;
private static final String GET = "get";
@Override
public ApiParam build(RequestContext ctx) {
public Map<String, String> buildRequestParams(RequestContext ctx) {
HttpServletRequest request = ctx.getRequest();
// zuul会做一层包装
if (request instanceof HttpServletRequestWrapper) {
HttpServletRequestWrapper req = (HttpServletRequestWrapper) request;
request = req.getRequest();
}
Map<String, Object> params = this.getParams(request);
ApiParam apiParams = ApiParamFactory.build(params);
ApiUploadContext apiUploadContext = this.buildApiUploadContext(request);
apiParams.setApiUploadContext(apiUploadContext);
return apiParams;
}
public Map<String, Object> getParams(HttpServletRequest request) {
Map<String, Object> params = null;
Map<String, String> params = null;
if (GET.equalsIgnoreCase(request.getMethod())) {
params = RequestUtil.convertRequestParamsToMap(request);
@ -72,32 +52,15 @@ public class ZuulParamBuilder implements ParamBuilder<RequestContext> {
return params;
}
protected ApiUploadContext buildApiUploadContext(HttpServletRequest request) {
ApiUploadContext apiUploadContext = null;
String contectType = request.getContentType();
if (contectType.contains(CONTENT_TYPE_MULTIPART)) {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
// 检查form中是否有enctype="multipart/form-data"
if (multipartResolver.isMultipart(request)) {
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
Map<String, MultipartFile> finalMap = new HashMap<>(fileMap.size());
Set<String> keys = fileMap.keySet();
for (String name : keys) {
MultipartFile file = fileMap.get(name);
if (file.getSize() > 0) {
finalMap.put(name, file);
}
}
if (finalMap.size() > 0) {
// 保存上传文件
apiUploadContext = new ApiUploadContext(finalMap);
}
}
}
return apiUploadContext;
@Override
protected ApiParam newApiParam(RequestContext ctx) {
ApiParam apiParam = super.newApiParam(ctx);
HttpServletRequest request = ctx.getRequest();
String method = (String) request.getAttribute(SopConstants.REDIRECT_METHOD_KEY);
String version = (String) request.getAttribute(SopConstants.REDIRECT_VERSION_KEY);
apiParam.setRestName(method);
apiParam.setRestVersion(version);
return apiParam;
}
}

@ -6,11 +6,11 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>sop-service-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>sop-service-common</name>

@ -26,7 +26,7 @@
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>

@ -43,6 +43,7 @@ public class OAuth2ServiceImpl implements OAuth2Service {
private static final String TOKEN_TYPE = "Bearer";
public static final String APP_ID_NAME = "app_id";
private OAuthIssuer oauthIssuer = new OAuthIssuerImpl(new MD5Generator());
@ -96,6 +97,7 @@ public class OAuth2ServiceImpl implements OAuth2Service {
HttpServletResponse.SC_FOUND);
// 设置授权码
builder.setCode(authorizationCode);
builder.setParam(APP_ID_NAME, clientId);
// 得到到客户端重定向地址
String redirectURI = oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI);

@ -31,9 +31,10 @@ public class CallbackController {
*/
@GetMapping("oauth2callback")
@ResponseBody
public String callback(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
public OpenAuthTokenAppResponse callback(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
String app_id = servletRequest.getParameter("app_id");
String code = servletRequest.getParameter("code");
log.info("app_id:{}, code:{}", app_id, code);
OpenAuthTokenAppRequest request = new OpenAuthTokenAppRequest();
OpenAuthTokenAppModel model = new OpenAuthTokenAppModel();
@ -48,7 +49,6 @@ public class CallbackController {
// 后续使用token进行接口访问
log.info("授权成功,body:{}", response.getBody());
}
System.out.println(response.getBody());
return response.getBody();
return response;
}
}

@ -23,7 +23,7 @@
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.gitee.sop</groupId>

@ -29,7 +29,7 @@
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>

@ -20,7 +20,7 @@
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
</dependency>
<!-- eureka 服务发现 -->
<dependency>

@ -23,7 +23,7 @@
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.gitee.sop</groupId>

@ -23,7 +23,7 @@
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-gateway-common</artifactId>
<version>1.7.0-SNAPSHOT</version>
<version>1.7.1-SNAPSHOT</version>
</dependency>
<!-- ↓↓↓ 使用spring cloud zuul ↓↓↓ -->

@ -0,0 +1,31 @@
package com.gitee.sop.gateway;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
/**
* @author tanghc
*/
@Controller
public class RedirectController {
@Value("${zuul.servlet-path}")
private String path;
@RequestMapping("/{method}/{version}/")
public String redirect(
@PathVariable("method") String method
, @PathVariable("version") String version
, HttpServletRequest request
) {
request.setAttribute(SopConstants.REDIRECT_METHOD_KEY, method);
request.setAttribute(SopConstants.REDIRECT_VERSION_KEY, version);
return "forward:" + path;
}
}

@ -0,0 +1,61 @@
package com.gitee.sop;
import com.alibaba.fastjson.JSON;
import com.gitee.sop.alipay.AlipaySignature;
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author tanghc
*/
public class RestUrlTest extends TestBase {
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=";
/**
* 演示将接口名版本号跟在url后面规则:http://host:port/{method}/{version}/
* @throws Exception
*/
@Test
public void testDemo() throws Exception {
// 公共请求参数
Map<String, String> params = new HashMap<String, String>();
params.put("app_id", appId);
// 参数中的接口名和版本转移到了url中
// params.put("method", "story.demo.get");
// params.put("version", "1.0");
// 注意这里的url
String url = "http://localhost:8081/story.demo.get/1.0/";
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()));
// 业务参数
Map<String, String> bizContent = new HashMap<>();
params.put("biz_content", JSON.toJSONString(bizContent));
System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey);
String content = AlipaySignature.getSignContent(params);
System.out.println("待签名内容:" + content);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
System.out.println("签名(sign):" + sign);
params.put("sign", sign);
System.out.println("----------- 返回结果 -----------");
String responseData = post(url, params);// 发送请求
System.out.println(responseData);
}
}
Loading…
Cancel
Save