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() { // 创建请求对象