diff --git a/changelog.md b/changelog.md
index b42abd68..f2e4c18c 100755
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,7 @@
## 日常更新
+- 2025-11-05:添加SDK示例,返回List
- 2025-11-01:添加回调处理。有升级SQL,见:[sop-20251101.sql](./upgrade/sop-20251101.sql)
- 2025-09-12:修复推送文档报找不到@Open注解问题
- 2025-08-29:smart-doc升级到3.1.1
diff --git a/sop-example/example-payment/payment-api/pom.xml b/sop-example/example-payment/payment-api/pom.xml
index 077adf1e..d5fb6f2d 100644
--- a/sop-example/example-payment/payment-api/pom.xml
+++ b/sop-example/example-payment/payment-api/pom.xml
@@ -11,6 +11,25 @@
8
8
UTF-8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.13.0
+
+ ${java.version}
+ ${java.version}
+ UTF-8
+
+ -parameters
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sop-example/example-payment/payment-service/src/main/java/com/gitee/sop/payment/open/OpenPayment.java b/sop-example/example-payment/payment-service/src/main/java/com/gitee/sop/payment/open/OpenPayment.java
index 007122b2..9e9c645e 100755
--- a/sop-example/example-payment/payment-service/src/main/java/com/gitee/sop/payment/open/OpenPayment.java
+++ b/sop-example/example-payment/payment-service/src/main/java/com/gitee/sop/payment/open/OpenPayment.java
@@ -6,6 +6,8 @@ import com.gitee.sop.payment.open.resp.PayOrderSearchResponse;
import com.gitee.sop.payment.open.resp.PayTradeWapPayResponse;
import com.gitee.sop.support.annotation.Open;
+import java.util.List;
+
/**
* 支付接口
*
@@ -34,4 +36,13 @@ public interface OpenPayment {
@Open("pay.order.search")
PayOrderSearchResponse orderSearch(PayOrderSearchRequest request);
+ /**
+ * 订单查询接口
+ *
+ * @param request
+ * @return
+ */
+ @Open("pay.order.searchlist")
+ List orderSearchList(PayOrderSearchRequest request);
+
}
diff --git a/sop-example/example-payment/payment-service/src/main/java/com/gitee/sop/payment/open/impl/OpenPaymentImpl.java b/sop-example/example-payment/payment-service/src/main/java/com/gitee/sop/payment/open/impl/OpenPaymentImpl.java
index 8b4838c8..06faf493 100755
--- a/sop-example/example-payment/payment-service/src/main/java/com/gitee/sop/payment/open/impl/OpenPaymentImpl.java
+++ b/sop-example/example-payment/payment-service/src/main/java/com/gitee/sop/payment/open/impl/OpenPaymentImpl.java
@@ -5,6 +5,10 @@ import com.gitee.sop.payment.open.req.PayOrderSearchRequest;
import com.gitee.sop.payment.open.req.PayTradeWapPayRequest;
import com.gitee.sop.payment.open.resp.PayOrderSearchResponse;
import com.gitee.sop.payment.open.resp.PayTradeWapPayResponse;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.UUID;
import com.gitee.sop.story.api.ProductService;
@@ -52,4 +56,9 @@ public class OpenPaymentImpl implements OpenPayment {
}
return payOrderSearchResponse;
}
+
+ @Override
+ public List orderSearchList(PayOrderSearchRequest request) {
+ return Collections.singletonList(orderSearch(request));
+ }
}
diff --git a/sop-example/example-product/pom.xml b/sop-example/example-product/pom.xml
index 943335f1..15d0dd3e 100755
--- a/sop-example/example-product/pom.xml
+++ b/sop-example/example-product/pom.xml
@@ -9,6 +9,15 @@
5.0.0-SNAPSHOT
pom
+
+ 8
+ 8
+ UTF-8
+ 1.8
+
+ 3.2.16
+
+
product-api
product-service
diff --git a/sop-example/example-product/product-api/pom.xml b/sop-example/example-product/product-api/pom.xml
index 47e43a79..3c8b1740 100644
--- a/sop-example/example-product/product-api/pom.xml
+++ b/sop-example/example-product/product-api/pom.xml
@@ -11,6 +11,25 @@
8
8
UTF-8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.13.0
+
+ ${java.version}
+ ${java.version}
+ UTF-8
+
+ -parameters
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/internal/ResultRouteInterceptor.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/internal/ResultRouteInterceptor.java
index f205b1c8..eb3e86af 100755
--- a/sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/internal/ResultRouteInterceptor.java
+++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/internal/ResultRouteInterceptor.java
@@ -57,11 +57,6 @@ public class ResultRouteInterceptor implements RouteInterceptor {
return fileData;
}
}
-
- // 其它情况
- if (result instanceof Map) {
- ((Map, ?>) result).remove(CLASS);
- }
return result;
}
diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/service/impl/SerdeImpl.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/service/impl/SerdeImpl.java
index 19e49d97..6fbe3d41 100755
--- a/sop-gateway/src/main/java/com/gitee/sop/gateway/service/impl/SerdeImpl.java
+++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/service/impl/SerdeImpl.java
@@ -2,6 +2,7 @@ package com.gitee.sop.gateway.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
+import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitee.sop.gateway.config.ApiConfig;
import com.gitee.sop.gateway.service.Serde;
@@ -10,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
+import java.util.HashMap;
import java.util.Map;
/**
@@ -19,6 +21,16 @@ public class SerdeImpl implements Serde {
static JSONWriter.Context writeContext;
+ /**
+ * remove specify class field refer to dubbo generic invoke
+ */
+ private static final SimplePropertyPreFilter CLASS_NAME_PRE_FILTER = new SimplePropertyPreFilter(HashMap.class);
+
+ static {
+ CLASS_NAME_PRE_FILTER.getExcludes().add("class");
+ }
+
+
@Autowired
protected ApiConfig apiConfig;
@@ -48,6 +60,8 @@ public class SerdeImpl implements Serde {
public void init() {
writeContext = new JSONWriter.Context();
writeContext.setDateFormat(dateFormat);
+ // 移除泛化调用返回class属性
+ writeContext.setPropertyPreFilter(CLASS_NAME_PRE_FILTER);
this.doInit();
}
diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java
index 0dfce630..536e19e1 100755
--- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java
+++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/client/OpenClient.java
@@ -1,6 +1,7 @@
package com.gitee.sop.sdk.client;
import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.gitee.sop.sdk.common.DataNameBuilder;
@@ -17,14 +18,12 @@ import com.gitee.sop.sdk.request.DownloadRequest;
import com.gitee.sop.sdk.sign.SignUtil;
import com.gitee.sop.sdk.sign.SopSignException;
import com.gitee.sop.sdk.sign.StringUtils;
-import com.gitee.sop.sdk.util.FileUtil;
import okhttp3.Headers;
import okhttp3.Response;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
-import java.io.InputStream;
import java.util.Collections;
import java.util.Map;
@@ -236,7 +235,7 @@ public class OpenClient {
String method = request.getMethod();
String rootNodeName = dataNameBuilder.build(method);
JSONObject jsonObject = JSON.parseObject(resp, Feature.OrderedField);
- JSONObject data = jsonObject.getJSONObject(rootNodeName);
+
String sign = jsonObject.getString(openConfig.getSignName());
// 是否要验证返回的sign
if (StringUtils.areNotEmpty(sign, publicKeyPlatform)) {
@@ -246,10 +245,15 @@ public class OpenClient {
}
}
Result result = jsonObject.toJavaObject(Result.class);
- if (data != null) {
- T dataObj = data.toJavaObject(request.getResponseClass());
- result.setData(dataObj);
+ Object data = jsonObject.get(rootNodeName);
+ T dataObj;
+ if (data instanceof JSONArray) {
+ JSONArray arr = (JSONArray) data;
+ dataObj = (T) arr.toJavaList(request.getResponseClass());
+ } else {
+ dataObj = ((JSONObject) data).toJavaObject(request.getResponseClass());
}
+ result.setData(dataObj);
return result;
}
diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java
index 86d25e45..8b264a8f 100755
--- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java
+++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/BaseRequest.java
@@ -76,6 +76,10 @@ public abstract class BaseRequest {
return version;
}
+ public boolean isResponseArray() {
+ return ClassUtil.isArray(this.getClass(), 0);
+ }
+
/**
* 添加上传文件
*
diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/PayTradeWapPayListRequest.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/PayTradeWapPayListRequest.java
new file mode 100755
index 00000000..82e8c9e2
--- /dev/null
+++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/request/PayTradeWapPayListRequest.java
@@ -0,0 +1,31 @@
+package com.gitee.sop.sdk.request;
+
+import com.gitee.sop.sdk.response.PayOrderSearchResponse;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * pay.trade.wap.pay(手机网站支付接口)
+ *
+ * @author 六如
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class PayTradeWapPayListRequest extends BaseRequest> {
+
+ private String outTradeNo;
+
+ private BigDecimal totalAmount;
+
+ private String subject;
+
+ private String productCode;
+
+ @Override
+ protected String method() {
+ return "pay.order.searchlist";
+ }
+}
diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/PayOrderSearchResponse.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/PayOrderSearchResponse.java
new file mode 100644
index 00000000..8efa27bb
--- /dev/null
+++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/response/PayOrderSearchResponse.java
@@ -0,0 +1,35 @@
+package com.gitee.sop.sdk.response;
+
+import lombok.Data;
+
+/**
+ * @author 六如
+ */
+@Data
+public class PayOrderSearchResponse {
+
+ /**
+ * 订单编号
+ */
+ private String orderNo;
+
+ /**
+ * 支付编号
+ */
+ private String payNo;
+
+ /**
+ * 支付人id
+ */
+ private Long payUserId;
+
+ /**
+ * 支付人姓名
+ */
+ private String payUserName;
+
+ /**
+ * 备注
+ */
+ private String remark;
+}
diff --git a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/util/ClassUtil.java b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/util/ClassUtil.java
index b0855ef3..dbeeb6e3 100755
--- a/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/util/ClassUtil.java
+++ b/sop-sdk/sdk-java/src/main/java/com/gitee/sop/sdk/util/ClassUtil.java
@@ -18,6 +18,7 @@ package com.gitee.sop.sdk.util;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -26,7 +27,6 @@ import java.util.Map;
*/
public class ClassUtil {
- private static Map> classGenricTypeCache = new HashMap<>(16);
/**
* 返回定义类时的泛型参数的类型.
@@ -40,12 +40,6 @@ public class ClassUtil {
* @param index 泛型参数索引,从0开始
*/
public static Class> getSuperClassGenricType(Class> clazz, int index) throws IndexOutOfBoundsException {
- String cacheKey = clazz.getName() + index;
- Class> cachedClass = classGenricTypeCache.get(cacheKey);
- if (cachedClass != null) {
- return cachedClass;
- }
-
Type genType = clazz.getGenericSuperclass();
// 没有泛型参数
@@ -57,15 +51,44 @@ public class ClassUtil {
if (index >= params.length || index < 0) {
throw new RuntimeException("泛型索引不正确,index:" + index);
}
+ Type cls = params[index];
+ if (cls instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) cls;
+ Type rawType = parameterizedType.getRawType();
+ if (Collection.class.isAssignableFrom((Class>) rawType)) {
+ Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0];
+ return (Class>) actualTypeArgument;
+ } else {
+ return (Class>) cls;
+ }
+ }
if (!(params[index] instanceof Class)) {
throw new RuntimeException(params[index] + "不是Class类型");
}
- Class> retClass = (Class>) params[index];
- // 缓存起来
- classGenricTypeCache.put(cacheKey, retClass);
+ return (Class>) params[index];
+ }
+ }
- return retClass;
+ public static boolean isArray(Class> clazz, int index) {
+ Type genType = clazz.getGenericSuperclass();
+
+ // 没有泛型参数
+ if (!(genType instanceof ParameterizedType)) {
+ throw new RuntimeException("class " + clazz.getName() + " 没有指定父类泛型");
+ } else {
+ Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
+
+ if (index >= params.length || index < 0) {
+ throw new RuntimeException("泛型索引不正确,index:" + index);
+ }
+ Type cls = params[index];
+ if (cls instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) cls;
+ Type rawType = parameterizedType.getRawType();
+ return Collection.class.isAssignableFrom((Class>) rawType);
+ }
+ return false;
}
}
diff --git a/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java b/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java
index 204cbbd5..6a386441 100755
--- a/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java
+++ b/sop-sdk/sdk-java/src/test/java/com/gitee/sop/sdk/SdkTest.java
@@ -9,11 +9,13 @@ import com.gitee.sop.sdk.model.DemoFileUploadModel;
import com.gitee.sop.sdk.model.GetStoryModel;
import com.gitee.sop.sdk.request.DemoFileUploadRequest;
import com.gitee.sop.sdk.request.GetProductRequest;
+import com.gitee.sop.sdk.request.PayTradeWapPayListRequest;
import com.gitee.sop.sdk.request.PayTradeWapPayModel;
import com.gitee.sop.sdk.request.PayTradeWapPayRequest;
import com.gitee.sop.sdk.request.ProductDownloadModel;
import com.gitee.sop.sdk.request.ProductDownloadRequest;
import com.gitee.sop.sdk.response.GetProductResponse;
+import com.gitee.sop.sdk.response.PayOrderSearchResponse;
import com.gitee.sop.sdk.response.PayTradeWapPayResponse;
import junit.framework.TestCase;
import okhttp3.Headers;
@@ -26,6 +28,7 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.List;
public class SdkTest extends TestCase {
@@ -63,6 +66,28 @@ public class SdkTest extends TestCase {
}
}
+ /**
+ * 返回数组
+ */
+ @Test
+ public void testList() {
+ PayTradeWapPayListRequest request = new PayTradeWapPayListRequest();
+ PayTradeWapPayModel model = new PayTradeWapPayModel();
+ model.setOutTradeNo("70501111111S001111119");
+ model.setTotalAmount(new BigDecimal("1000"));
+ model.setSubject("衣服");
+ model.setProductCode("QUICK_WAP_WAY");
+ request.setBizModel(model);
+
+ Result> result = client.execute(request);
+ if (result.isSuccess()) {
+ List data = result.getData();
+ System.out.println(data);
+ } else {
+ System.out.println(result);
+ }
+ }
+
@Test
public void testGet() {
// 创建请求对象