From 1532f3addc6d62471077e3bbe479adb6835a3733 Mon Sep 17 00:00:00 2001 From: tanghc Date: Fri, 13 Dec 2019 11:36:48 +0800 Subject: [PATCH 1/9] 2.5.7 --- .../route/EurekaRegistryListener.java | 75 ++++++++++++++----- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRegistryListener.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRegistryListener.java index 5bc9a403..6eb37113 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRegistryListener.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/EurekaRegistryListener.java @@ -6,6 +6,8 @@ import com.gitee.sop.gatewaycommon.manager.EnvironmentKeys; import com.netflix.appinfo.InstanceInfo; import com.netflix.discovery.shared.Application; import com.netflix.discovery.shared.Applications; +import lombok.AllArgsConstructor; +import lombok.Data; import org.apache.commons.collections.CollectionUtils; import org.springframework.cloud.netflix.eureka.CloudEurekaClient; import org.springframework.context.ApplicationEvent; @@ -27,50 +29,77 @@ public class EurekaRegistryListener extends BaseRegistryListener { System.setProperty(EnvironmentKeys.ZUUL_CUSTOM_RULE_CLASSNAME.getKey(), EurekaEnvironmentServerChooser.class.getName()); } - private Set cacheServices = new HashSet<>(); + private Set cacheServices = new HashSet<>(); - /** - * 注册中心触发事件,可以从中获取服务
- * - * 这个方法做的事情有2个:
- * - * 1. 找出新注册的服务,调用pullRoutes方法
- * 2. 找出删除的服务,调用removeRoutes方法
- * - * @param applicationEvent 事件体 - */ @Override public void onEvent(ApplicationEvent applicationEvent) { Object source = applicationEvent.getSource(); CloudEurekaClient cloudEurekaClient = (CloudEurekaClient) source; Applications applications = cloudEurekaClient.getApplications(); List registeredApplications = applications.getRegisteredApplications(); - List serviceList = registeredApplications + + List serviceList = registeredApplications .stream() - .map(Application::getName) + .filter(application -> CollectionUtils.isNotEmpty(application.getInstances())) + .map(Application::getInstances) + .map(instanceInfos -> { + // 根据更新时间倒叙 + instanceInfos.sort(Comparator.comparing(InstanceInfo::getLastUpdatedTimestamp).reversed()); + // 获取最新的个服务实例,说明这个服务实例刚刚重启过 + return instanceInfos.get(0); + }) + .map(instanceInfo -> new ServiceHolder(instanceInfo.getAppName(), instanceInfo.getLastUpdatedTimestamp())) .collect(Collectors.toList()); - final Set currentServices = new HashSet<>(serviceList); + final Set currentServices = new HashSet<>(serviceList); currentServices.removeAll(cacheServices); // 如果有新的服务注册进来 if (currentServices.size() > 0) { List newApplications = registeredApplications.stream() - .filter(application -> this.canOperator(application.getName()) - && currentServices.contains(application.getName())) + .filter(application -> + this.canOperator(application.getName()) && containsService(currentServices, application.getName())) .collect(Collectors.toList()); this.doRegister(newApplications); } - cacheServices.removeAll(new HashSet<>(serviceList)); + Set removedServiceIdList = getRemovedServiceId(serviceList); // 如果有服务删除 - if (cacheServices.size() > 0) { - this.doRemove(cacheServices); + if (removedServiceIdList.size() > 0) { + this.doRemove(removedServiceIdList); } - // 缓存最新服务 + cacheServices = new HashSet<>(serviceList); } + /** + * 获取已经下线的serviceId + * + * @param serviceList 最新的serviceId集合 + * @return 返回已下线的serviceId + */ + private Set getRemovedServiceId(List serviceList) { + Set cache = cacheServices.stream() + .map(ServiceHolder::getServiceId) + .collect(Collectors.toSet()); + + Set newList = serviceList.stream() + .map(ServiceHolder::getServiceId) + .collect(Collectors.toSet()); + + cache.removeAll(newList); + return cache; + } + + private static boolean containsService(Set currentServices, String serviceId) { + for (ServiceHolder currentService : currentServices) { + if (currentService.getServiceId().equalsIgnoreCase(serviceId)) { + return true; + } + } + return false; + } + private void doRegister(List registeredApplications) { registeredApplications.forEach(application -> { List instances = application.getInstances(); @@ -92,4 +121,10 @@ public class EurekaRegistryListener extends BaseRegistryListener { deletedServices.forEach(this::removeRoutes); } + @Data + @AllArgsConstructor + private static class ServiceHolder { + private String serviceId; + private long lastUpdatedTimestamp; + } } From f2d3ee1af979cf83186167cf9102036708212742 Mon Sep 17 00:00:00 2001 From: tanghc Date: Fri, 13 Dec 2019 13:29:27 +0800 Subject: [PATCH 2/9] 2.5.7 --- sop-admin/sop-admin-server/pom.xml | 2 +- .../common/MyApiSessionManager.java | 58 ------------------- .../sop/adminserver/config/WebConfig.java | 3 +- 3 files changed, 2 insertions(+), 61 deletions(-) delete mode 100644 sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/MyApiSessionManager.java diff --git a/sop-admin/sop-admin-server/pom.xml b/sop-admin/sop-admin-server/pom.xml index 671563ac..0a5c6f60 100644 --- a/sop-admin/sop-admin-server/pom.xml +++ b/sop-admin/sop-admin-server/pom.xml @@ -42,7 +42,7 @@ net.oschina.durcframework easyopen-spring-boot-starter - 1.16.2 + 1.16.5 diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/MyApiSessionManager.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/MyApiSessionManager.java deleted file mode 100644 index 4a0dcd27..00000000 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/common/MyApiSessionManager.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.gitee.sop.adminserver.common; - -import com.gitee.easyopen.exception.ApiException; -import com.gitee.easyopen.session.ApiSessionManager; -import com.google.common.cache.LoadingCache; -import lombok.extern.slf4j.Slf4j; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpSession; - -/** - * @author tanghc - */ -@Slf4j -public class MyApiSessionManager extends ApiSessionManager { - - private volatile LoadingCache cache; - - @Override - public HttpSession getSession(String sessionId) { - if (sessionId == null) { - return this.createSession(sessionId); - } - try { - return getCache().get(sessionId); - } catch (Exception e) { - log.error(e.getMessage(), e); - throw new ApiException("create session error"); - } - } - - /** - * 创建一个session - * - * @param sessionId 传null将返回一个新session - * @return 返回session - */ - @Override - protected HttpSession createSession(String sessionId) { - ServletContext servletContext = getServletContext(); - HttpSession session = this.newSession(sessionId, servletContext); - session.setMaxInactiveInterval(getSessionTimeout()); - getCache().put(session.getId(), session); - return session; - } - - public LoadingCache getCache() { - if (cache == null) { - synchronized (ApiSessionManager.class) { - if (cache == null) { - cache = buildCache(); - } - } - } - return cache; - } - -} diff --git a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java index 4ca883fc..2284a716 100644 --- a/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java +++ b/sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/config/WebConfig.java @@ -8,7 +8,6 @@ import com.gitee.easyopen.ApiParamParser; import com.gitee.easyopen.ParamNames; import com.gitee.easyopen.interceptor.ApiInterceptor; import com.gitee.easyopen.session.ApiSessionManager; -import com.gitee.sop.adminserver.common.MyApiSessionManager; import com.gitee.sop.adminserver.interceptor.LoginInterceptor; import com.gitee.sop.adminserver.service.RegistryService; import com.gitee.sop.adminserver.service.impl.RegistryServiceEurekaImpl; @@ -49,7 +48,7 @@ public class WebConfig { , SerializerFeature.WriteDateUseDateFormat) ); - ApiSessionManager apiSessionManager = new MyApiSessionManager(); + ApiSessionManager apiSessionManager = new ApiSessionManager(); // session有效期 int timeout = NumberUtils.toInt(accessTokenTimeout, 30); apiSessionManager.setSessionTimeout(timeout); From fdd5d3b00d0107d47ef9eec022e894b57ecb9b9c Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 19 Dec 2019 11:30:50 +0800 Subject: [PATCH 3/9] 2.5.7 --- .../storyweb/controller/AlipayController.java | 12 ++++++++++++ .../java/com/gitee/sop/test/AllInOneTest.java | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java index 5215183d..b0530de1 100644 --- a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java +++ b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController.java @@ -18,6 +18,7 @@ import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -141,6 +142,17 @@ public class AlipayController { return story; } + // http://localhost:2222/getStory33 + // 遗留接口具备开放平台能力 + @ApiAbility + @PostMapping("getStory33") + public StoryResult getStory22(@RequestBody StoryParam param) { + StoryResult story = new StoryResult(); + story.setId(1L); + story.setName("遗留接口,param:" + param); + return story; + } + // http://localhost:2222/getStory2?version=2.1 // 遗留接口具备开放平台能力,在原来的基础上加版本号 @ApiAbility(version = "2.1") diff --git a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java index 793725c8..e60efc29 100644 --- a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java +++ b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java @@ -64,6 +64,22 @@ public class AllInOneTest extends TestBase { client.execute(requestBuilder); } + /** + * 测试遗留接口 + * 以json方式提交(application/json) + */ + public void testPostJSON2() { + Client.RequestBuilder requestBuilder = new Client.RequestBuilder() + .method("getStory33") + .version("1.0") + // 以json方式提交 + .postJson(true) + .bizContent(new BizContent().add("id", "1").add("name", "葫芦娃")) + .httpMethod(HttpTool.HTTPMethod.POST); + + client.execute(requestBuilder); + } + /** * 测试feign。gateway -> book-service(consumer) -> story-service(provider) */ From 5d02c8f60804795a6bbedbc72e7a5b23a2002074 Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 19 Dec 2019 11:41:05 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-admin/sop-admin-vue/src/views/isv/keys.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sop-admin/sop-admin-vue/src/views/isv/keys.vue b/sop-admin/sop-admin-vue/src/views/isv/keys.vue index c44e861e..2016f895 100644 --- a/sop-admin/sop-admin-vue/src/views/isv/keys.vue +++ b/sop-admin/sop-admin-vue/src/views/isv/keys.vue @@ -41,7 +41,7 @@
- 平台公私钥 + 平台公私钥[可选] 重新生成 From eaf501b3d0973c75cfcaf55acff2c71b825d5379 Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 19 Dec 2019 12:02:02 +0800 Subject: [PATCH 5/9] 2.5.7 --- sop-test/src/main/java/com/gitee/sop/test/Client.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sop-test/src/main/java/com/gitee/sop/test/Client.java b/sop-test/src/main/java/com/gitee/sop/test/Client.java index 398996c7..3d641df8 100644 --- a/sop-test/src/main/java/com/gitee/sop/test/Client.java +++ b/sop-test/src/main/java/com/gitee/sop/test/Client.java @@ -133,7 +133,7 @@ public class Client { private String url; private String method; private String version = DEFAULT_VERSION; - private Map bizContent; + private Map bizContent; private HttpTool.HTTPMethod httpMethod; private Map header; private boolean ignoreSign; @@ -181,7 +181,7 @@ public class Client { * @param bizContent 业务参数 * @return 返回RequestBuilder */ - public RequestBuilder bizContent(Map bizContent) { + public RequestBuilder bizContent(Map bizContent) { this.bizContent = bizContent; return this; } @@ -227,6 +227,9 @@ public class Client { */ public RequestBuilder postJson(boolean postJson) { this.postJson = postJson; + if (postJson) { + this.httpMethod(HttpTool.HTTPMethod.POST); + } return this; } From 49615e64764a204615017684541fae8fe36620e5 Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 19 Dec 2019 12:02:57 +0800 Subject: [PATCH 6/9] 2.5.7 --- .../sop-admin-server/src/main/resources/public/index.html | 2 +- .../resources/public/static/js/chunk-73b2dcec.05b5ee28.js | 1 - .../resources/public/static/js/chunk-73b2dcec.24dc2be7.js | 1 + .../src/test/java/com/gitee/sop/test/AllInOneTest.java | 7 +++---- 4 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-73b2dcec.05b5ee28.js create mode 100644 sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-73b2dcec.24dc2be7.js diff --git a/sop-admin/sop-admin-server/src/main/resources/public/index.html b/sop-admin/sop-admin-server/src/main/resources/public/index.html index 359b4615..4245c34c 100644 --- a/sop-admin/sop-admin-server/src/main/resources/public/index.html +++ b/sop-admin/sop-admin-server/src/main/resources/public/index.html @@ -1 +1 @@ -SOP Admin
\ No newline at end of file +SOP Admin
\ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-73b2dcec.05b5ee28.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-73b2dcec.05b5ee28.js deleted file mode 100644 index b3ef66f0..00000000 --- a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-73b2dcec.05b5ee28.js +++ /dev/null @@ -1 +0,0 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-73b2dcec"],{"29fd":function(e,t,s){},"3bf7":function(e,t,s){"use strict";s.r(t);var a=function(){var e=this,t=e.$createElement,s=e._self._c||t;return s("div",{staticClass:"app-container"},[s("el-button",{staticClass:"el-icon-back",attrs:{type:"text"},on:{click:e.onBack}},[e._v("返回")]),e._v(" "),s("el-form",{ref:"isvKeysForm",staticStyle:{width:"700px"},attrs:{rules:e.rulesIsvKeysForm,model:e.isvKeysFormData,"label-width":"160px",size:"mini"}},[s("el-form-item",{attrs:{label:""}},[s("el-alert",{attrs:{title:"带 ★ 的分配给开发者",type:"warning",closable:!1}})],1),e._v(" "),s("el-form-item",{attrs:{label:e.selfLabel("appId")}},[s("div",[e._v(e._s(e.isvKeysFormData.appKey))])]),e._v(" "),s("el-form-item",{directives:[{name:"show",rawName:"v-show",value:e.showKeys(),expression:"showKeys()"}],attrs:{label:"秘钥格式"}},[s("el-radio-group",{model:{value:e.isvKeysFormData.keyFormat,callback:function(t){e.$set(e.isvKeysFormData,"keyFormat",t)},expression:"isvKeysFormData.keyFormat"}},[s("el-radio",{attrs:{label:1,name:"keyFormat"}},[e._v("PKCS8(JAVA适用)")]),e._v(" "),s("el-radio",{attrs:{label:2,name:"keyFormat"}},[e._v("PKCS1(非JAVA适用)")])],1)],1),e._v(" "),s("el-form-item",{directives:[{name:"show",rawName:"v-show",value:2===e.isvKeysFormData.signType,expression:"isvKeysFormData.signType === 2"}],attrs:{prop:"secret",label:e.selfLabel("secret")}},[s("el-input",{model:{value:e.isvKeysFormData.secret,callback:function(t){e.$set(e.isvKeysFormData,"secret",t)},expression:"isvKeysFormData.secret"}}),e._v(" "),s("el-button",{attrs:{type:"text"},on:{click:e.onGenSecret}},[e._v("重新生成")])],1),e._v(" "),s("fieldset",{directives:[{name:"show",rawName:"v-show",value:e.showKeys(),expression:"showKeys()"}]},[s("legend",[e._v("ISV公私钥")]),e._v(" "),s("el-form-item",{staticClass:"gen-key"},[s("el-button",{attrs:{type:"text"},on:{click:e.onGenKeysIsv}},[e._v("重新生成")])],1),e._v(" "),s("el-form-item",{attrs:{prop:"publicKeyIsv",label:"ISV公钥"}},[s("el-input",{attrs:{type:"textarea"},model:{value:e.isvKeysFormData.publicKeyIsv,callback:function(t){e.$set(e.isvKeysFormData,"publicKeyIsv",t)},expression:"isvKeysFormData.publicKeyIsv"}})],1),e._v(" "),s("el-form-item",{attrs:{prop:"privateKeyIsv",label:e.selfLabel("ISV私钥")}},[s("el-input",{attrs:{type:"textarea"},model:{value:e.isvKeysFormData.privateKeyIsv,callback:function(t){e.$set(e.isvKeysFormData,"privateKeyIsv",t)},expression:"isvKeysFormData.privateKeyIsv"}})],1)],1),e._v(" "),s("fieldset",{directives:[{name:"show",rawName:"v-show",value:e.showKeys(),expression:"showKeys()"}]},[s("legend",[e._v("平台公私钥")]),e._v(" "),s("el-form-item",{staticClass:"gen-key"},[s("el-button",{attrs:{type:"text"},on:{click:e.onGenKeysPlatform}},[e._v("重新生成")])],1),e._v(" "),s("el-form-item",{attrs:{prop:"publicKeyPlatform",label:e.selfLabel("平台公钥")}},[s("el-input",{attrs:{type:"textarea"},model:{value:e.isvKeysFormData.publicKeyPlatform,callback:function(t){e.$set(e.isvKeysFormData,"publicKeyPlatform",t)},expression:"isvKeysFormData.publicKeyPlatform"}})],1),e._v(" "),s("el-form-item",{attrs:{prop:"privateKeyPlatform",label:"平台私钥"}},[s("el-input",{attrs:{type:"textarea"},model:{value:e.isvKeysFormData.privateKeyPlatform,callback:function(t){e.$set(e.isvKeysFormData,"privateKeyPlatform",t)},expression:"isvKeysFormData.privateKeyPlatform"}})],1)],1),e._v(" "),s("el-form-item",[s("el-button",{attrs:{type:"primary"},on:{click:e.onSubmit}},[e._v("保存")]),e._v(" "),s("el-button",{on:{click:e.onBack}},[e._v("取消")])],1)],1)],1)},i=[],r={data:function(){var e=this,t=function(t,s,a){2===e.isvKeysFormData.signType&&(""===s&&a(new Error("不能为空")),s.length>200&&a(new Error("长度不能超过200"))),a()},s=function(t,s,a){1===e.isvKeysFormData.signType&&""===s&&a(new Error("不能为空")),a()};return{isvKeysFormData:{appKey:"",secret:"",keyFormat:1,publicKeyIsv:"",privateKeyIsv:"",publicKeyPlatform:"",privateKeyPlatform:"",signType:1},rulesIsvKeysForm:{secret:[{validator:t,trigger:"blur"}],publicKeyIsv:[{validator:s,trigger:"blur"}],privateKeyIsv:[{validator:s,trigger:"blur"}]}}},created:function(){var e=this.$route.query;this.isvKeysFormData.appKey=e.appKey,this.loadForm()},methods:{loadForm:function(){this.post("isv.keys.get",{appKey:this.isvKeysFormData.appKey},function(e){Object.assign(this.isvKeysFormData,e.data)})},selfLabel:function(e){return"★ "+e},onSubmit:function(){var e=this;this.$refs.isvKeysForm.validate(function(t){t&&e.post("isv.keys.update",e.isvKeysFormData,function(){this.tip("保存成功")})})},onBack:function(){this.$router.push({path:"list"})},onGenKeysPlatform:function(){this.post("isv.keys.gen",{},function(e){this.tip("生成公私钥成功");var t=e.data;this.isvKeysFormData.publicKeyPlatform=t.publicKey,this.isvKeysFormData.privateKeyPlatform=t.privateKey})},onGenKeysIsv:function(){this.post("isv.keys.gen",{keyFormat:this.isvKeysFormData.keyFormat},function(e){this.tip("生成公私钥成功");var t=e.data;this.isvKeysFormData.publicKeyIsv=t.publicKey,this.isvKeysFormData.privateKeyIsv=t.privateKey})},onGenSecret:function(){this.post("isv.secret.gen",{},function(e){this.isvKeysFormData.secret=e.data})},showKeys:function(){return 1===this.isvKeysFormData.signType}}},o=r,l=(s("8b91"),s("2877")),n=Object(l["a"])(o,a,i,!1,null,null,null);t["default"]=n.exports},"8b91":function(e,t,s){"use strict";var a=s("29fd"),i=s.n(a);i.a}}]); \ No newline at end of file diff --git a/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-73b2dcec.24dc2be7.js b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-73b2dcec.24dc2be7.js new file mode 100644 index 00000000..8c132ec0 --- /dev/null +++ b/sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-73b2dcec.24dc2be7.js @@ -0,0 +1 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-73b2dcec"],{"29fd":function(e,t,s){},"3bf7":function(e,t,s){"use strict";s.r(t);var a=function(){var e=this,t=e.$createElement,s=e._self._c||t;return s("div",{staticClass:"app-container"},[s("el-button",{staticClass:"el-icon-back",attrs:{type:"text"},on:{click:e.onBack}},[e._v("返回")]),e._v(" "),s("el-form",{ref:"isvKeysForm",staticStyle:{width:"700px"},attrs:{rules:e.rulesIsvKeysForm,model:e.isvKeysFormData,"label-width":"160px",size:"mini"}},[s("el-form-item",{attrs:{label:""}},[s("el-alert",{attrs:{title:"带 ★ 的分配给开发者",type:"warning",closable:!1}})],1),e._v(" "),s("el-form-item",{attrs:{label:e.selfLabel("appId")}},[s("div",[e._v(e._s(e.isvKeysFormData.appKey))])]),e._v(" "),s("el-form-item",{directives:[{name:"show",rawName:"v-show",value:e.showKeys(),expression:"showKeys()"}],attrs:{label:"秘钥格式"}},[s("el-radio-group",{model:{value:e.isvKeysFormData.keyFormat,callback:function(t){e.$set(e.isvKeysFormData,"keyFormat",t)},expression:"isvKeysFormData.keyFormat"}},[s("el-radio",{attrs:{label:1,name:"keyFormat"}},[e._v("PKCS8(JAVA适用)")]),e._v(" "),s("el-radio",{attrs:{label:2,name:"keyFormat"}},[e._v("PKCS1(非JAVA适用)")])],1)],1),e._v(" "),s("el-form-item",{directives:[{name:"show",rawName:"v-show",value:2===e.isvKeysFormData.signType,expression:"isvKeysFormData.signType === 2"}],attrs:{prop:"secret",label:e.selfLabel("secret")}},[s("el-input",{model:{value:e.isvKeysFormData.secret,callback:function(t){e.$set(e.isvKeysFormData,"secret",t)},expression:"isvKeysFormData.secret"}}),e._v(" "),s("el-button",{attrs:{type:"text"},on:{click:e.onGenSecret}},[e._v("重新生成")])],1),e._v(" "),s("fieldset",{directives:[{name:"show",rawName:"v-show",value:e.showKeys(),expression:"showKeys()"}]},[s("legend",[e._v("ISV公私钥")]),e._v(" "),s("el-form-item",{staticClass:"gen-key"},[s("el-button",{attrs:{type:"text"},on:{click:e.onGenKeysIsv}},[e._v("重新生成")])],1),e._v(" "),s("el-form-item",{attrs:{prop:"publicKeyIsv",label:"ISV公钥"}},[s("el-input",{attrs:{type:"textarea"},model:{value:e.isvKeysFormData.publicKeyIsv,callback:function(t){e.$set(e.isvKeysFormData,"publicKeyIsv",t)},expression:"isvKeysFormData.publicKeyIsv"}})],1),e._v(" "),s("el-form-item",{attrs:{prop:"privateKeyIsv",label:e.selfLabel("ISV私钥")}},[s("el-input",{attrs:{type:"textarea"},model:{value:e.isvKeysFormData.privateKeyIsv,callback:function(t){e.$set(e.isvKeysFormData,"privateKeyIsv",t)},expression:"isvKeysFormData.privateKeyIsv"}})],1)],1),e._v(" "),s("fieldset",{directives:[{name:"show",rawName:"v-show",value:e.showKeys(),expression:"showKeys()"}]},[s("legend",[e._v("平台公私钥[可选]")]),e._v(" "),s("el-form-item",{staticClass:"gen-key"},[s("el-button",{attrs:{type:"text"},on:{click:e.onGenKeysPlatform}},[e._v("重新生成")])],1),e._v(" "),s("el-form-item",{attrs:{prop:"publicKeyPlatform",label:e.selfLabel("平台公钥")}},[s("el-input",{attrs:{type:"textarea"},model:{value:e.isvKeysFormData.publicKeyPlatform,callback:function(t){e.$set(e.isvKeysFormData,"publicKeyPlatform",t)},expression:"isvKeysFormData.publicKeyPlatform"}})],1),e._v(" "),s("el-form-item",{attrs:{prop:"privateKeyPlatform",label:"平台私钥"}},[s("el-input",{attrs:{type:"textarea"},model:{value:e.isvKeysFormData.privateKeyPlatform,callback:function(t){e.$set(e.isvKeysFormData,"privateKeyPlatform",t)},expression:"isvKeysFormData.privateKeyPlatform"}})],1)],1),e._v(" "),s("el-form-item",[s("el-button",{attrs:{type:"primary"},on:{click:e.onSubmit}},[e._v("保存")]),e._v(" "),s("el-button",{on:{click:e.onBack}},[e._v("取消")])],1)],1)],1)},i=[],r={data:function(){var e=this,t=function(t,s,a){2===e.isvKeysFormData.signType&&(""===s&&a(new Error("不能为空")),s.length>200&&a(new Error("长度不能超过200"))),a()},s=function(t,s,a){1===e.isvKeysFormData.signType&&""===s&&a(new Error("不能为空")),a()};return{isvKeysFormData:{appKey:"",secret:"",keyFormat:1,publicKeyIsv:"",privateKeyIsv:"",publicKeyPlatform:"",privateKeyPlatform:"",signType:1},rulesIsvKeysForm:{secret:[{validator:t,trigger:"blur"}],publicKeyIsv:[{validator:s,trigger:"blur"}],privateKeyIsv:[{validator:s,trigger:"blur"}]}}},created:function(){var e=this.$route.query;this.isvKeysFormData.appKey=e.appKey,this.loadForm()},methods:{loadForm:function(){this.post("isv.keys.get",{appKey:this.isvKeysFormData.appKey},function(e){Object.assign(this.isvKeysFormData,e.data)})},selfLabel:function(e){return"★ "+e},onSubmit:function(){var e=this;this.$refs.isvKeysForm.validate(function(t){t&&e.post("isv.keys.update",e.isvKeysFormData,function(){this.tip("保存成功")})})},onBack:function(){this.$router.push({path:"list"})},onGenKeysPlatform:function(){this.post("isv.keys.gen",{},function(e){this.tip("生成公私钥成功");var t=e.data;this.isvKeysFormData.publicKeyPlatform=t.publicKey,this.isvKeysFormData.privateKeyPlatform=t.privateKey})},onGenKeysIsv:function(){this.post("isv.keys.gen",{keyFormat:this.isvKeysFormData.keyFormat},function(e){this.tip("生成公私钥成功");var t=e.data;this.isvKeysFormData.publicKeyIsv=t.publicKey,this.isvKeysFormData.privateKeyIsv=t.privateKey})},onGenSecret:function(){this.post("isv.secret.gen",{},function(e){this.isvKeysFormData.secret=e.data})},showKeys:function(){return 1===this.isvKeysFormData.signType}}},o=r,l=(s("8b91"),s("2877")),n=Object(l["a"])(o,a,i,!1,null,null,null);t["default"]=n.exports},"8b91":function(e,t,s){"use strict";var a=s("29fd"),i=s.n(a);i.a}}]); \ No newline at end of file diff --git a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java index e60efc29..a6034f43 100644 --- a/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java +++ b/sop-test/src/test/java/com/gitee/sop/test/AllInOneTest.java @@ -58,8 +58,7 @@ public class AllInOneTest extends TestBase { .version("1.0") // 以json方式提交 .postJson(true) - .bizContent(new BizContent().add("id", "1").add("name", "葫芦娃")) - .httpMethod(HttpTool.HTTPMethod.POST); + .bizContent(new BizContent().add("id", "1").add("name", "葫芦娃")); client.execute(requestBuilder); } @@ -314,8 +313,8 @@ public class AllInOneTest extends TestBase { client.execute(requestBuilder); } - class BizContent extends HashMap { - public BizContent add(String key, String value) { + class BizContent extends HashMap { + public BizContent add(String key, Object value) { this.put(key, value); return this; } From 05395ea0b9db1784d52691d756a623ba20b9a0ab Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 19 Dec 2019 15:28:41 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapping/ApiMappingHandlerMapping.java | 14 ++------ .../param/ApiArgumentResolver.java | 11 ++++--- .../gitee/sop/servercommon/util/OpenUtil.java | 21 ++++++++++++ .../controller/AlipayController2.java | 32 +++++++++++++++++++ 4 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController2.java diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java index 074cead3..17f4b765 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java @@ -4,8 +4,8 @@ import com.gitee.sop.servercommon.annotation.ApiAbility; import com.gitee.sop.servercommon.annotation.ApiMapping; import com.gitee.sop.servercommon.bean.ServiceConfig; import com.gitee.sop.servercommon.bean.ServiceContext; +import com.gitee.sop.servercommon.util.OpenUtil; import org.springframework.core.PriorityOrdered; -import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.StringValueResolver; import org.springframework.web.servlet.mvc.condition.RequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; @@ -26,7 +26,7 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple String sopMvc = System.getProperty(ServiceContext.SOP_MVC); boolean isMvc = sopMvc != null; ApiMapping apiMapping = method.getAnnotation(ApiMapping.class); - ApiAbility apiAbility = method.getAnnotation(ApiAbility.class); + ApiAbility apiAbility = OpenUtil.getAnnotationFromMethodOrClass(method, ApiAbility.class); StringValueResolver valueResolver = null; if (apiMapping != null || apiAbility != null) { valueResolver = isMvc ? stringValueResolverMVC : stringValueResolver; @@ -53,7 +53,7 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple permission = apiMapping.permission(); needToken = apiMapping.needToken(); } else { - ApiAbility apiAbility = this.findApiAbilityAnnotation(method); + ApiAbility apiAbility = OpenUtil.getAnnotationFromMethodOrClass(method, ApiAbility.class); if (apiAbility != null) { version = apiAbility.version(); ignoreValidate = apiAbility.ignoreValidate(); @@ -88,12 +88,4 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple return new ApiMappingRequestCondition(apiMappingInfo); } - protected ApiAbility findApiAbilityAnnotation(Method method) { - ApiAbility apiAbility = method.getAnnotation(ApiAbility.class); - if (apiAbility == null) { - Class controllerClass = method.getDeclaringClass(); - apiAbility = AnnotationUtils.findAnnotation(controllerClass, ApiAbility.class); - } - return apiAbility; - } } \ No newline at end of file diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java index 82c3be81..d099b0b5 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/param/ApiArgumentResolver.java @@ -21,7 +21,6 @@ import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.MultipartRequest; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; -import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor; import org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver; import javax.servlet.ServletRequest; @@ -40,7 +39,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; @@ -85,9 +83,7 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { // 是否有注解 - boolean hasAnnotation = methodParameter.hasMethodAnnotation(ApiMapping.class) - || methodParameter.hasMethodAnnotation(ApiAbility.class); - if (hasAnnotation) { + if (hasApiAnnotation(methodParameter)) { openApiParams.add(methodParameter); } Class paramType = methodParameter.getParameterType(); @@ -116,6 +112,11 @@ public class ApiArgumentResolver implements SopHandlerMethodArgumentResolver { return !exclude; } + private boolean hasApiAnnotation(MethodParameter methodParameter) { + return methodParameter.hasMethodAnnotation(ApiMapping.class) + || OpenUtil.getAnnotationFromMethodOrClass(methodParameter.getMethod(), ApiAbility.class) != null; + } + @Override public Object resolveArgument( MethodParameter methodParameter diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/OpenUtil.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/OpenUtil.java index 0c77c01f..04a8461e 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/OpenUtil.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/util/OpenUtil.java @@ -5,10 +5,13 @@ import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.http.MediaType; import org.springframework.util.DigestUtils; import javax.servlet.http.HttpServletRequest; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; @@ -90,4 +93,22 @@ public class OpenUtil { String serverSign = DigestUtils.md5DigestAsHex(source.getBytes()); return serverSign.equals(sign); } + + /** + * 在方法或方法对应的类上找指定的注解 + * @param method 方法 + * @param annotationClass 指定的注解 + * @param + * @return 返回指定注解,没有返回null + */ + public static T getAnnotationFromMethodOrClass(Method method, Class annotationClass) { + if (method == null) { + return null; + } + T annotation = AnnotationUtils.findAnnotation(method, annotationClass); + if (annotation == null) { + annotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), annotationClass); + } + return annotation; + } } diff --git a/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController2.java b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController2.java new file mode 100644 index 00000000..88629888 --- /dev/null +++ b/sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/AlipayController2.java @@ -0,0 +1,32 @@ +package com.gitee.sop.storyweb.controller; + +import com.gitee.sop.servercommon.annotation.ApiAbility; +import com.gitee.sop.storyweb.controller.param.StoryParam; +import com.gitee.sop.storyweb.controller.result.StoryResult; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * 支付宝服务端,假设签名验证通过后,到达这里进行具体的业务处理。 + * + * @author tanghc + */ +@RestController +@Slf4j +// 注解放在这里,表示类中的方法都具备接口开放能力 +@ApiAbility +public class AlipayController2 { + + // http://localhost:2222/getStory44 + // 遗留接口具备开放平台能力 + @PostMapping("/getStory44") + public StoryResult getStory22(@RequestBody StoryParam param) { + StoryResult story = new StoryResult(); + story.setId(1L); + story.setName("遗留接口44,param:" + param); + return story; + } +} From 93b48088e3f8b86bc7fd8fa7f077b8d0d6d15831 Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 19 Dec 2019 15:29:45 +0800 Subject: [PATCH 8/9] 2.5.8 --- changelog.md | 4 ++++ sop-auth/pom.xml | 2 +- sop-common/pom.xml | 2 +- sop-common/sop-gateway-common/pom.xml | 4 ++-- sop-common/sop-service-common/pom.xml | 4 ++-- sop-example/sop-book/sop-book-web/pom.xml | 2 +- sop-example/sop-easyopen/pom.xml | 2 +- sop-example/sop-springmvc/pom.xml | 2 +- sop-example/sop-story/sop-story-web/pom.xml | 2 +- sop-gateway/pom.xml | 2 +- sop-website/pom.xml | 2 +- 11 files changed, 16 insertions(+), 12 deletions(-) diff --git a/changelog.md b/changelog.md index 33c4d8ab..49e32814 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # changelog +## 2.5.8 + +- 优化参数绑定 + ## 2.5.7 - 优化restful接口调用 diff --git a/sop-auth/pom.xml b/sop-auth/pom.xml index ebd0a69e..9097898a 100644 --- a/sop-auth/pom.xml +++ b/sop-auth/pom.xml @@ -26,7 +26,7 @@ com.gitee.sop sop-service-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT diff --git a/sop-common/pom.xml b/sop-common/pom.xml index 4fee2370..dc84cd09 100644 --- a/sop-common/pom.xml +++ b/sop-common/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.gitee.sop sop-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT pom diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml index 2bcb7cdb..e5de7f61 100644 --- a/sop-common/sop-gateway-common/pom.xml +++ b/sop-common/sop-gateway-common/pom.xml @@ -5,11 +5,11 @@ com.gitee.sop sop-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT ../pom.xml sop-gateway-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT jar sop-gateway-common diff --git a/sop-common/sop-service-common/pom.xml b/sop-common/sop-service-common/pom.xml index 089f3346..372dfb50 100644 --- a/sop-common/sop-service-common/pom.xml +++ b/sop-common/sop-service-common/pom.xml @@ -6,11 +6,11 @@ com.gitee.sop sop-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT ../pom.xml sop-service-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT jar sop-service-common diff --git a/sop-example/sop-book/sop-book-web/pom.xml b/sop-example/sop-book/sop-book-web/pom.xml index f1671681..97679424 100644 --- a/sop-example/sop-book/sop-book-web/pom.xml +++ b/sop-example/sop-book/sop-book-web/pom.xml @@ -28,7 +28,7 @@ com.gitee.sop sop-service-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT com.gitee.sop diff --git a/sop-example/sop-easyopen/pom.xml b/sop-example/sop-easyopen/pom.xml index 8fcaa615..0b169726 100644 --- a/sop-example/sop-easyopen/pom.xml +++ b/sop-example/sop-easyopen/pom.xml @@ -29,7 +29,7 @@ com.gitee.sop sop-service-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT diff --git a/sop-example/sop-story/sop-story-web/pom.xml b/sop-example/sop-story/sop-story-web/pom.xml index 7275e91a..6ee32a77 100644 --- a/sop-example/sop-story/sop-story-web/pom.xml +++ b/sop-example/sop-story/sop-story-web/pom.xml @@ -28,7 +28,7 @@ com.gitee.sop sop-service-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT com.gitee.sop diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index 827bafe6..10c993e2 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -29,7 +29,7 @@ com.gitee.sop sop-gateway-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT diff --git a/sop-website/pom.xml b/sop-website/pom.xml index 124a18c7..b1e519ad 100644 --- a/sop-website/pom.xml +++ b/sop-website/pom.xml @@ -35,7 +35,7 @@ com.gitee.sop sop-gateway-common - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT From dfcd4d42d75fcee4bc9e84d4becf32e8b790cfe8 Mon Sep 17 00:00:00 2001 From: tanghc Date: Thu, 19 Dec 2019 15:36:48 +0800 Subject: [PATCH 9/9] 2.5.8 --- .../sop/servercommon/mapping/ApiMappingHandlerMapping.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java index 17f4b765..76f24c78 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java @@ -31,7 +31,9 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple if (apiMapping != null || apiAbility != null) { valueResolver = isMvc ? stringValueResolverMVC : stringValueResolver; } - this.setEmbeddedValueResolver(valueResolver); + if (valueResolver != null) { + this.setEmbeddedValueResolver(valueResolver); + } return super.getMappingForMethod(method, handlerType); }