Compare commits

..

No commits in common. 'master' and 'pr' have entirely different histories.
master ... pr

  1. 6
      README.md
  2. 8
      changelog.md
  3. 4
      doc/docs/README.md
  4. 2
      doc/pom.xml
  5. 2
      pom.xml
  6. 2
      sop-admin/pom.xml
  7. 4
      sop-admin/sop-admin-server/pom.xml
  8. 4
      sop-auth/pom.xml
  9. 2
      sop-common/pom.xml
  10. 2
      sop-common/sop-bridge-eureka/pom.xml
  11. 10
      sop-common/sop-bridge-nacos/pom.xml
  12. 2
      sop-common/sop-gateway-common/pom.xml
  13. 8
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ApiConfig.java
  14. 25
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/BizResultHandler.java
  15. 9
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/result/GatewayResultExecutor.java
  16. 8
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteRepository.java
  17. 4
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/result/BaseExecutorAdapter.java
  18. 215
      sop-common/sop-service-common/pom.xml
  19. 57
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java
  20. 186
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/SingleParameterClassCreator.java
  21. 44
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/SingleParameterContext.java
  22. 24
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/SingleParameterContextValue.java
  23. 27
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/SingleParameterWrapper.java
  24. 128
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/FieldUtil.java
  25. 2
      sop-example/pom.xml
  26. 2
      sop-example/sop-springmvc/pom.xml
  27. 2
      sop-example/sop-story/pom.xml
  28. 15
      sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java
  29. 2
      sop-gateway/pom.xml
  30. 5
      sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/MyRouteInterceptor.java
  31. 2
      sop-gateway/src/main/resources/META-INF/gateway.properties
  32. 2
      sop-sdk/pom.xml
  33. 4
      sop-sdk/sdk-java/pom.xml
  34. 2
      sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java
  35. 15
      sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java
  36. 2
      sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java
  37. 2
      sop-test/pom.xml
  38. 18
      sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java
  39. 15
      sop-test/src/test/java/com/gitee/sop/test/OneParamTest.java
  40. 2
      sop-website/pom.xml
  41. 2
      sop-website/sop-website-server/pom.xml
  42. 2
      sop-website/sop-website-vue/src/components/DocView/index.vue

@ -142,3 +142,9 @@ System.out.println(responseData);
## 相关文档
[开发文档](http://durcframework.gitee.io/sop)
## 沟通交流
- QQ群
1群:167643071(满)、2群:167643071(满)、3群:565894770

@ -1,13 +1,5 @@
# changelog
## 4.4.2
- 优化参数绑定
## 4.4.1
- 修复单值参数绑定问题
## 4.4.0
**【重要】:升级前请阅读 [升级到4.4.0注意事项](./升级到4.4.0注意事项.md)**

@ -1,3 +1,7 @@
# SOP开发文档
Git地址:[SOP](https://gitee.com/durcframework/SOP)
- QQ群
1群:167643071(满)、2群:167643071(满)、3群:565894770

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.sop</groupId>
<artifactId>doc</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<properties>
<!-- Generic properties -->

@ -11,7 +11,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<packaging>pom</packaging>
<description>一个开放平台解决方案项目,基于Spring Cloud实现,目标是能够让用户快速得搭建起自己的开放平台</description>

@ -6,7 +6,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -5,13 +5,13 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sop-admin-server</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>

@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
@ -38,7 +38,7 @@
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sdk-java</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
</dependency>
<!-- http请求 -->
<dependency>

@ -6,7 +6,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-common</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

@ -2,16 +2,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-common</artifactId>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-bridge-nacos</artifactId>
<version>4.4.2-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-gateway-common</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>${project.version}</version>
</dependency>
<dependency>

@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-common</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -1,6 +1,5 @@
package com.gitee.sop.gatewaycommon.bean;
import com.gitee.sop.gatewaycommon.gateway.result.BizResultHandler;
import com.gitee.sop.gatewaycommon.gateway.result.GatewayResultExecutor;
import com.gitee.sop.gatewaycommon.interceptor.RouteInterceptor;
import com.gitee.sop.gatewaycommon.limit.DefaultLimitManager;
@ -144,13 +143,6 @@ public class ApiConfig {
*/
private MonitorManager monitorManager = new MonitorManager();
/**
* 业务返回参数处理
*/
private BizResultHandler bizResultHandler = (serviceData, serviceObj, apiParam, request) -> {
serviceData.putAll(serviceObj);
};
// -------- fields ---------
/**

@ -1,25 +0,0 @@
package com.gitee.sop.gatewaycommon.gateway.result;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.gatewaycommon.param.ApiParam;
import org.springframework.web.server.ServerWebExchange;
import java.util.Map;
/**
* 处理业务返回数据
* @author thc
*/
public interface BizResultHandler {
/**
* 处理业务参数
* @param serviceData 外层service数据
* @param serviceObj 业务数据
* @param apiParam apiParam
* @param request ServerWebExchange
* @author thc
* @date 2021/7/7 10:41
*/
void handle(Map<String, Object> serviceData, JSONObject serviceObj, ApiParam apiParam, ServerWebExchange request);
}

@ -2,7 +2,6 @@ package com.gitee.sop.gatewaycommon.gateway.result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.gatewaycommon.bean.ApiConfig;
import com.gitee.sop.gatewaycommon.bean.DefaultRouteInterceptorContext;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.exception.ApiException;
@ -17,12 +16,14 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.gateway.support.TimeoutException;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriUtils;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
@ -95,8 +96,4 @@ public class GatewayResultExecutor extends BaseExecutorAdapter<ServerWebExchange
return this.merge(exchange, jsonObject);
}
@Override
protected void handleBizResult(Map<String, Object> serviceData, JSONObject serviceObj, ApiParam apiParam, ServerWebExchange request) {
ApiConfig.getInstance().getBizResultHandler().handle(serviceData, serviceObj, apiParam, request);
}
}

@ -55,14 +55,8 @@ public class GatewayRouteRepository implements RouteRepository<GatewayTargetRout
RewritePathGatewayFilterFactory.Config config = new RewritePathGatewayFilterFactory.Config();
config.setRegexp(gatewayTargetRoute.getFullPath());
config.setReplacement(routeDefinition.getPath());
String serviceId = gatewayTargetRoute.getServiceDefinition().getServiceId();
String path = routeDefinition.getPath();
if (!path.startsWith("/")) {
path = "/" + path;
}
String finalPath = "/" + serviceId + path;
builder.route(routeDefinition.getId(),
r -> r.path(finalPath)
r -> r.path(routeDefinition.getPath())
// path匹配
.filters(gatewayFilterSpec -> gatewayFilterSpec.filter(rewritePathGatewayFilterFactory.apply(config)))
.uri(routeDefinition.getUri())

@ -179,12 +179,10 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
serviceData.put(GATEWAY_CODE_NAME, errorMeta.getCode());
serviceData.put(GATEWAY_MSG_NAME, errorMeta.getError(getLocale(request)).getMsg());
JSONObject serviceObj = JSON.parseObject(serviceResult, Feature.OrderedField);
this.handleBizResult(serviceData, serviceObj, apiParam, request);
serviceData.putAll(serviceObj);
return serviceData;
}
protected abstract void handleBizResult(Map<String, Object> serviceData, JSONObject serviceObj, ApiParam apiParam, T request);
/**
* 该路由是否合并结果

@ -1,45 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-common</artifactId>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-common</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<java.version>1.8</java.version>
<!-- springboot 版本-->
<spring-boot.version>2.3.2.RELEASE</spring-boot.version>
<!-- spring cloud 版本 -->
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
<!-- spring cloud alibaba 版本 -->
<!-- 具体版本对应关系见:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E -->
<spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version>
<!-- Logging -->
<logback.version>1.2.3</logback.version>
<!-- Test -->
<junit.version>4.11</junit.version>
<fastjson.version>1.2.73</fastjson.version>
<commons-io.version>2.5</commons-io.version>
<commons-fileupload.version>1.3.3</commons-fileupload.version>
<commons-collection.version>3.2.2</commons-collection.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<commons-codec.version>1.11</commons-codec.version>
<commons-logging.version>1.2</commons-logging.version>
<validation-api.version>2.0.1.Final</validation-api.version>
<hibernate-validator.version>6.0.13.Final</hibernate-validator.version>
<fastmybatis.version>1.9.1</fastmybatis.version>
<guava.version>29.0-jre</guava.version>
<swagger.version>1.5.21</swagger.version>
<springfox-spring-web.version>2.9.2</springfox-spring-web.version>
<springfox-swagger2.version>2.9.2</springfox-swagger2.version>
<easyopen.version>1.16.9</easyopen.version>
<pagehelper.version>5.2.0</pagehelper.version>
<asm.version>6.2</asm.version>
</properties>
<dependencies>
@ -131,179 +108,5 @@
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 加了这个就不需要加版本号了 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>net.oschina.durcframework</groupId>
<artifactId>fastmybatis-spring-boot-starter</artifactId>
<version>${fastmybatis.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>${springfox-spring-web.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger2.version}</version>
</dependency>
<dependency>
<groupId>net.oschina.durcframework</groupId>
<artifactId>easyopen</artifactId>
<version>${easyopen.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.7</version>
</dependency>
<dependency>
<groupId>net.oschina.durcframework</groupId>
<artifactId>easyopen-spring-boot-starter</artifactId>
<version>${easyopen.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${validation-api.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collection.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- 打包时跳过测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -2,17 +2,19 @@ package com.gitee.sop.servercommon.param;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import com.gitee.sop.servercommon.annotation.Open;
import com.gitee.sop.servercommon.bean.OpenContext;
import com.gitee.sop.servercommon.bean.OpenContextImpl;
import com.gitee.sop.servercommon.bean.ParamNames;
import com.gitee.sop.servercommon.bean.ServiceContext;
import com.gitee.sop.servercommon.util.FieldUtil;
import com.gitee.sop.servercommon.util.OpenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
@ -34,6 +36,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Parameter;
import java.security.Principal;
import java.time.ZoneId;
import java.util.ArrayList;
@ -51,7 +54,6 @@ import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
private static final String HAS_INIT_OPEN_CONTEXT = "hasInitOpenContext";
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache = new ConcurrentHashMap<>(256);
private static List<MethodParameter> NEED_INIT_OPEN_CONTEXT = new ArrayList<>(16);
@ -111,6 +113,7 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
if (special) {
NEED_INIT_OPEN_CONTEXT.add(methodParameter);
}
this.wrapSingleParam(methodParameter, open);
return true;
}
@ -119,6 +122,20 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
return NEED_INIT_OPEN_CONTEXT.contains(methodParameter);
}
/**
* 包装单个值参数
* @param methodParameter 参数信息
* @param open open注解
*/
private void wrapSingleParam(MethodParameter methodParameter, Open open) {
Parameter parameter = methodParameter.getParameter();
boolean isNumberStringEnumType = FieldUtil.isNumberStringEnumType(parameter.getType());
if (isNumberStringEnumType) {
log.debug("包装参数,方法:{},参数名:{}", methodParameter.getMethod(), parameter.getName());
SingleParameterContext.add(parameter, open);
}
}
@Override
public Object resolveArgument(
MethodParameter methodParameter
@ -147,32 +164,39 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
Object paramObj = this.getParamObject(methodParameter, nativeWebRequest);
if (paramObj != null) {
// JSR-303验证
paramValidator.validateBizParam(paramObj);
return paramObj;
if (paramObj instanceof SingleParameterWrapper) {
SingleParameterWrapper parameterWrapper = (SingleParameterWrapper) paramObj;
paramValidator.validateBizParam(parameterWrapper.getWrapperObject());
return parameterWrapper.getParamValue();
} else {
paramValidator.validateBizParam(paramObj);
return paramObj;
}
}
HandlerMethodArgumentResolver resolver = getOtherArgumentResolver(methodParameter);
if (resolver != null) {
return resolver.resolveArgument(
Object param = resolver.resolveArgument(
methodParameter
, modelAndViewContainer
, nativeWebRequest
, webDataBinderFactory
);
OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext();
if (openContext instanceof OpenContextImpl) {
OpenContextImpl openContextImpl = (OpenContextImpl) openContext;
openContextImpl.setBizObject(param);
}
return param;
}
return null;
}
private OpenContextImpl initOpenContextImpl(NativeWebRequest nativeWebRequest) {
HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
Object hasInit = request.getAttribute(HAS_INIT_OPEN_CONTEXT);
if (hasInit != null) {
return (OpenContextImpl) ServiceContext.getCurrentContext().getOpenContext();
}
ServiceContext currentContext = ServiceContext.getCurrentContext();
JSONObject requestParams = OpenUtil.getRequestParams(request);
OpenContextImpl openContext = new OpenContextImpl(requestParams);
currentContext.setOpenContext(openContext);
request.setAttribute(HAS_INIT_OPEN_CONTEXT, true);
return openContext;
}
@ -193,11 +217,22 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver {
Map<String, Object> requestParams = openContext.getParameterMap();
Object bizObj = requestParams.get(ParamNames.BIZ_CONTENT_NAME);
String bizContent = bizObj == null ? null : bizObj.toString();
if (StringUtils.isEmpty(bizContent)) {
if (bizContent == null) {
return null;
}
// 方法参数类型
Class<?> parameterType = methodParameter.getParameterType();
SingleParameterContextValue singleValue = SingleParameterContext.get(openContext.getMethod(), openContext.getVersion());
// 如果是单值参数
if (singleValue != null) {
JSONObject jsonObj = JSON.parseObject(bizContent);
Object paramValue = jsonObj.getObject(singleValue.getParameterName(), parameterType);
Object wrapperObject = jsonObj.toJavaObject(singleValue.getWrapClass());
SingleParameterWrapper singleParameterWrapper = new SingleParameterWrapper();
singleParameterWrapper.setParamValue(paramValue);
singleParameterWrapper.setWrapperObject(wrapperObject);
return singleParameterWrapper;
}
Object param;
try {
param = JSON.parseObject(bizContent, parameterType);

@ -0,0 +1,186 @@
package com.gitee.sop.servercommon.param;
import com.gitee.sop.servercommon.util.FieldUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Parameter;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 包装单个参数
* <code>
* public class WrapperParam0id implements SingleValue {
* public String id;
*
* public Object fetchValue() {
* return this.id;
* }
* }
* </code>
*
* @author tanghc
*/
public class SingleParameterClassCreator implements Opcodes {
private static final Logger logger = LoggerFactory.getLogger(SingleParameterClassCreator.class);
private static final String FOLDER_END_CHAR = "/";
private static final String CLASS_FILE_SUFFIX = ".class";
private static final String WRAPPER_PARAM = "WrapperParam";
private static final String PKG = "com/gitee/sop/servercommon/gen/";
private static final String OBJECT = "java/lang/Object";
private static final ParameterClassLoader CLASS_LOADER = new ParameterClassLoader();
private static final AtomicInteger i = new AtomicInteger();
// 生成class文件的保存路径
private String savePath;
/**
* 生成一个类里面指放这个字段
*
* @param parameter 字段只能是基本类型或字符串类型
* @return 如果不是基本类型或字符串类型返回null
*/
public Class<?> create(Parameter parameter, String paramName) {
Class<?> paramType = parameter.getType();
if (!FieldUtil.isNumberStringEnumType(paramType)) {
return null;
}
/* *******************************class********************************************** */
// 创建一个ClassWriter, 以生成一个新的类
ClassWriter classWriter = new ClassWriter(0);
// 类名
String className = WRAPPER_PARAM + i.incrementAndGet() + paramName;
// 类路径名:com/gitee/sop/service/gen/WrapperParam
String classpathName = PKG + className;
classWriter.visit(V1_8, ACC_PUBLIC, classpathName, null, OBJECT, null);
/* ********************************constructor********************************************* */
MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
null);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKESPECIAL, OBJECT, "<init>", "()V", false);
methodVisitor.visitInsn(RETURN);
methodVisitor.visitMaxs(1, 1);
methodVisitor.visitEnd();
/* ************************************parameter***************************************** */
// 生成String name字段, Ljava/lang/String;
Type type = Type.getType(paramType);
FieldVisitor fieldVisitor = classWriter.visitField(ACC_PUBLIC, paramName, type.getDescriptor(), null, null);
// 生成验证注解
Annotation[] annotations = parameter.getAnnotations();
for (Annotation annotation : annotations) {
ValidationAnnotationDefinition validationAnnotationDefinition = ValidationAnnotationDefinitionFactory.build(annotation);
if (validationAnnotationDefinition == null) {
continue;
}
Class<?> annoClass = validationAnnotationDefinition.getAnnotationClass();
Type annoType = Type.getType(annoClass);
AnnotationVisitor annotationVisitor = fieldVisitor.visitAnnotation(annoType.getDescriptor(), true);
Map<String, Object> properties = validationAnnotationDefinition.getProperties();
if (properties != null) {
try {
Set<Map.Entry<String, Object>> entrySet = properties.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
Object val = entry.getValue();
if (val != null) {
// 设置枚举值
if (val.getClass().isEnum()) {
Type eType = Type.getType(val.getClass());
annotationVisitor.visitEnum(entry.getKey(), eType.getDescriptor(), val.toString());
} else if (val instanceof Class<?>) {
// val是Class类型
Type vType = Type.getType((Class<?>) val);
annotationVisitor.visit(entry.getKey(), vType);
} else {
annotationVisitor.visit(entry.getKey(), val);
}
}
}
} catch (Exception e) {
logger.error("ASM生成注解出错", e);
}
}
// 结束生成注解
annotationVisitor.visitEnd();
logger.debug("ASM生成参数注解,参数:{},注解:{},注解属性:{}", paramName, annoClass.getName(), properties);
}
fieldVisitor.visitEnd();
classWriter.visitEnd();
/* **********************************generate and load******************************************* */
byte[] code = classWriter.toByteArray();
if (StringUtils.isNotBlank(savePath)) {
if (!savePath.endsWith(FOLDER_END_CHAR)) {
savePath = savePath + FOLDER_END_CHAR;
}
this.writeClassFile(code, savePath + className + CLASS_FILE_SUFFIX);
}
Class<?> clazz = CLASS_LOADER.defineClass(code);
logger.debug("生成参数包装类:{},包装参数名:{},参数类型:{}", clazz.getName(), paramName, paramType);
return clazz;
}
protected void writeClassFile(byte[] code, String filepath) {
// 将二进制流写到本地磁盘上
try {
FileUtils.writeByteArrayToFile(new File(filepath), code);
} catch (IOException e) {
logger.error("写文件错误,filepath:" + filepath, e);
}
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
// 自定义类加载器
static class ParameterClassLoader extends ClassLoader {
public ParameterClassLoader() {
/*
指定父加载器不指定默认为AppClassLoader
springboot启动会使用自带的org.springframework.boot.loader.LaunchedURLClassLoader
如果不指定会出现加载器不一致导致ASM生成的class获取不到字段的注解
因此ASM生成的class必须使用当前ClassLoader进行生成
*/
super(Thread.currentThread().getContextClassLoader());
}
/**
* 加载class
*
* @param clazz 字节码
* @return
*/
public Class<?> defineClass(byte[] clazz) {
return this.defineClass(null, clazz, 0, clazz.length);
}
}
}

@ -0,0 +1,44 @@
package com.gitee.sop.servercommon.param;
import com.gitee.sop.servercommon.annotation.Open;
import com.gitee.sop.servercommon.bean.ServiceConfig;
import java.lang.reflect.Parameter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 存放单个参数
* @author tanghc
*/
public class SingleParameterContext {
private static SingleParameterClassCreator singleFieldWrapper = new SingleParameterClassCreator();
private static final Map<String, SingleParameterContextValue> context = new ConcurrentHashMap<>(16);
/**
* 添加单个参数
* @param parameter 接口单个参数
* @param open open注解
*/
public static void add(Parameter parameter, Open open) {
String version = open.version();
version = "".equals(version) ? ServiceConfig.getInstance().getDefaultVersion() : version;
String key = open.value() + version;
String parameterName = parameter.getName();
Class<?> wrapClass = singleFieldWrapper.create(parameter, parameterName);
SingleParameterContextValue value = new SingleParameterContextValue();
value.setParameterName(parameterName);
value.setWrapClass(wrapClass);
context.put(key, value);
}
public static SingleParameterContextValue get(String name, String version) {
return context.get(name + version);
}
public static void setSingleFieldWrapper(SingleParameterClassCreator singleFieldWrapper) {
SingleParameterContext.singleFieldWrapper = singleFieldWrapper;
}
}

@ -0,0 +1,24 @@
package com.gitee.sop.servercommon.param;
public class SingleParameterContextValue {
/** 参数名称 */
private String parameterName;
private Class<?> wrapClass;
public String getParameterName() {
return parameterName;
}
public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}
public Class<?> getWrapClass() {
return wrapClass;
}
public void setWrapClass(Class<?> wrapClass) {
this.wrapClass = wrapClass;
}
}

@ -0,0 +1,27 @@
package com.gitee.sop.servercommon.param;
/**
* @author tanghc
*/
public class SingleParameterWrapper {
/** 包裹类实例 */
private Object wrapperObject;
/** 参数值 */
private Object paramValue;
public Object getWrapperObject() {
return wrapperObject;
}
public void setWrapperObject(Object wrapperObject) {
this.wrapperObject = wrapperObject;
}
public Object getParamValue() {
return paramValue;
}
public void setParamValue(Object paramValue) {
this.paramValue = paramValue;
}
}

@ -0,0 +1,128 @@
package com.gitee.sop.servercommon.util;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ClassUtils;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
/**
* @author tanghc
*/
public class FieldUtil {
private static final Logger log = LoggerFactory.getLogger(FieldUtil.class);
private static final String CLASS_SUFFIX = ".class";
private FieldUtil() {
}
/**
* 判断这个字段是否是数字类型或字符串类型或枚举类型
*
* @param type 字段类型
* @return true是数字或字符串类型或枚举类型
*/
public static boolean isNumberStringEnumType(Class<?> type) {
if (type == String.class) {
return true;
}
if (type.getGenericSuperclass() == Number.class) {
return true;
}
if (type.isPrimitive()) {
return true;
}
if (type.isEnum()) {
return true;
}
return false;
}
/**
* 获取指定类指定方法的参数名
* @param clazz 要获取参数名的方法所属的类
* @param method 要获取参数名的方法
* @param index 参数索引从0开始
* @return 返回指定类指定方法的参数名没有返回空字符串
*/
public static String getMethodParameterName(Class<?> clazz, final Method method, int index) {
String[] names = getMethodParameterNamesByAsm(clazz, method);
if (names.length == 0) {
return "";
}
return names[index];
}
/**
* 获取指定类指定方法的参数名
*
* @param clazz 要获取参数名的方法所属的类
* @param method 要获取参数名的方法
* @return 按参数顺序排列的参数名列表如果没有参数则返回空数组
*/
public static String[] getMethodParameterNamesByAsm(Class<?> clazz, final Method method) {
final Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes == null || parameterTypes.length == 0) {
return new String[0];
}
final Type[] types = new Type[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
types[i] = Type.getType(parameterTypes[i]);
}
final String[] parameterNames = new String[parameterTypes.length];
// 解决clazz对象是cglib对象导致空指针异常
// 获取真实的class,如果是cglib类,则返回父类class
Class<?> realClass = ClassUtils.getUserClass(clazz);
String className = realClass.getName();
int lastDotIndex = className.lastIndexOf('.');
className = className.substring(lastDotIndex + 1) + CLASS_SUFFIX;
InputStream is = realClass.getResourceAsStream(className);
try {
ClassReader classReader = new ClassReader(is);
classReader.accept(new ClassVisitor(Opcodes.ASM6) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// 只处理指定的方法
Type[] argumentTypes = Type.getArgumentTypes(desc);
if (!method.getName().equals(name) || !Arrays.equals(argumentTypes, types)) {
return null;
}
return new MethodVisitor(Opcodes.ASM6) {
@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
int i = index - 1;
// 如果是静态方法,则第一就是参数
// 如果不是静态方法,则第一个是"this",然后才是方法的参数
if (Modifier.isStatic(method.getModifiers())) {
i = index;
}
if (i >= 0 && i < parameterNames.length) {
parameterNames[i] = name;
}
super.visitLocalVariable(name, desc, signature, start,
end, index);
}
};
}
}, 0);
} catch (IOException e) {
log.error("生成asm失败,oriClass:{}, realClass:{} method:{}", clazz.getName(), realClass.getName(), method.toGenericString(), e);
}
return parameterNames;
}
}

@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -4,7 +4,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -35,7 +35,6 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@ -137,14 +136,6 @@ public class Example1001_BaseController {
@Open("story.system.param.get4")
@RequestMapping("/get/system/param/v4")
public Object addGoods3(HttpServletRequest request, StoryParam param) {
param.setRemark(request.getRequestURI());
return param;
}
@Open("story.system.param.get5")
@RequestMapping("/get/system/param/v5")
public Object get5(HttpServletRequest request, HttpServletResponse response, StoryParam param) {
param.setRemark(request.getRequestURI() + ", getCharacterEncoding:" + response.getCharacterEncoding());
return param;
}
@ -160,7 +151,9 @@ public class Example1001_BaseController {
// 参数绑定
@Open(value = "story.oneparam", version = "1.1")
@GetMapping("/oneParam/v2")
public StoryResult oneParamV2(Integer id) {
public StoryResult oneParamV2(
@NotNull(message = "id不能为空")
@Min(value = 1, message = "id必须大于0") Integer id) {
StoryResult result = new StoryResult();
result.setName("id:" + id);
return result;
@ -178,7 +171,7 @@ public class Example1001_BaseController {
// 参数绑定
@Open(value = "story.param.bind", mergeResult = false)
@RequestMapping("/get/param/v1")
public StoryResult param(String id, String name) {
public StoryResult param(@RequestParam("id") Integer id, @RequestParam String name) {
StoryResult result = new StoryResult();
result.setName("参数绑定:id:" + id + ", name:" + name);
return result;

@ -4,7 +4,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -5,7 +5,6 @@ import com.gitee.sop.gatewaycommon.interceptor.RouteInterceptorContext;
import com.gitee.sop.gatewaycommon.param.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import java.net.URI;
@ -35,10 +34,6 @@ public class MyRouteInterceptor implements RouteInterceptor {
@Override
public void afterRoute(RouteInterceptorContext context) {
String serviceErrorMsg = context.getServiceErrorMsg();
if (StringUtils.hasText(serviceErrorMsg)) {
log.error("错误信息:{}", serviceErrorMsg);
}
}
@Override

@ -35,7 +35,7 @@ spring.datasource.hikari.pool-name=HikariCP
spring.datasource.hikari.max-lifetime=500000
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
#spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.enabled=true
# \u54CD\u5E94\u8D85\u65F6\uFF0C\u9ED8\u8BA410\u79D2\uFF0810000\uFF09
spring.cloud.gateway.httpclient.response-timeout=10000
spring.cloud.gateway.httpclient.pool.max-idle-time=60000

@ -6,7 +6,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -4,13 +4,13 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sdk-java</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<properties>
<!-- Generic properties -->

@ -157,7 +157,7 @@ public class OpenClient {
form.put(this.openConfig.getAppKeyName(), this.appId);
String content = SopSignature.getSignContent(form);
String sign;
String sign = null;
try {
sign = SopSignature.rsaSign(content, privateKey, openConfig.getCharset(), openConfig.getSignType());
} catch (SopSignException e) {

@ -44,8 +44,6 @@ public abstract class BaseRequest<T extends BaseResponse> {
private String bizContent = EMPTY_JSON;
private Object bizModel;
private RequestMethod requestMethod = RequestMethod.POST;
/**
* 上传文件
*/
@ -146,12 +144,13 @@ public abstract class BaseRequest<T extends BaseResponse> {
return responseClass;
}
public RequestMethod getRequestMethod() {
return requestMethod;
/**
* 指定HTTP请求method,默认POST
*
* @return
*/
protected RequestMethod getRequestMethod() {
return RequestMethod.POST;
}
public void setRequestMethod(RequestMethod requestMethod) {
this.requestMethod = requestMethod;
}
}

@ -3,7 +3,6 @@ package com.gitee.sop.sdk;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gitee.sop.sdk.client.OpenClient;
import com.gitee.sop.sdk.common.RequestMethod;
import com.gitee.sop.sdk.common.UploadFile;
import com.gitee.sop.sdk.model.DemoFileUploadModel;
import com.gitee.sop.sdk.model.GetStoryModel;
@ -66,7 +65,6 @@ public class SdkTest extends TestCase {
Map<String, Object> bizModel = new HashMap<>();
bizModel.put("name", "白雪公主");
request.setBizModel(bizModel);
// request.setRequestMethod(RequestMethod.GET);
// 发送请求
CommonResponse response = client.execute(request);

@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -422,24 +422,6 @@ public class AllInOneTest extends TestBase {
client.execute(requestBuilder);
}
public void testParamBind2() {
Client.RequestBuilder requestBuilder = new Client.RequestBuilder()
.method("story.system.param.get5")
.version("1.0")
.bizContent(new BizContent().add("id", "1").add("name", "葫芦娃"))
.postJson(true)
.httpMethod(HttpTool.HTTPMethod.POST)
.callback((requestInfo, responseData) -> {
System.out.println(responseData);
String node = requestInfo.getDataNode();
JSONObject jsonObject = JSON.parseObject(responseData).getJSONObject(node);
Assert.assertEquals(1L, jsonObject.getLongValue("id"));
Assert.assertEquals("葫芦娃", jsonObject.getString("name"));
});
client.execute(requestBuilder);
}
/**
* 未知异常
*/

@ -19,7 +19,6 @@ public class OneParamTest extends TestBase {
// 平台提供的私钥
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=";
// 演示没有biz_content,用于绑定单个参数
@Test
public void testGet() throws Exception {
@ -34,9 +33,11 @@ public class OneParamTest extends TestBase {
params.put("version", "1.0");
// 业务参数
params.put("id", "aaa");
params.put("name", "jim");
Map<String, Object> bizContent = new HashMap<>();
bizContent.put("id", "aaa");
bizContent.put("name", "jim");
params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
@ -67,8 +68,10 @@ public class OneParamTest extends TestBase {
params.put("version", "1.1");
// 业务参数
params.put("id", "1");
Map<String, Object> bizContent = new HashMap<>();
bizContent.put("id", "1");
params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
@ -99,8 +102,10 @@ public class OneParamTest extends TestBase {
params.put("version", "1.2");
// 业务参数
params.put("typeEnum", "MOBILE");
Map<String, Object> bizContent = new HashMap<>();
bizContent.put("typeEnum", "MOBILE");
params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);

@ -6,7 +6,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-website</artifactId>
<version>4.4.2-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>

@ -17,7 +17,7 @@
<el-table-column prop="versionValue" width="120" />
</el-table>
<h3>接口描述</h3>
<div class="doc-overview" v-html="docInfo.description || docInfo.title"></div>
<div class="doc-overview">{{ docInfo.description || docInfo.title }}</div>
<h3>请求地址</h3>
<el-table
:data="[{ envLabel: '环境', envValue: '正式环境', urlLabel: '请求地址', urlValue: urlProd }]"

Loading…
Cancel
Save