diff --git a/pom.xml b/pom.xml index d100bd3b..9dd70299 100644 --- a/pom.xml +++ b/pom.xml @@ -17,15 +17,16 @@ doc - sop-common - sop-auth + + sop-example sop-admin - sop-gateway + sop-test sop-sdk - sop-website + sop-index + sop-spring-boot-starter @@ -57,7 +58,7 @@ 1.2 2.0.1.Final 6.0.13.Final - 2.4.8 + 3.0.10 3.5.3.1 29.0-jre 3.0.2 @@ -99,6 +100,12 @@ ${dubbo.version} + + com.alibaba.boot + nacos-discovery-spring-boot-starter + 0.2.1 + + com.google.guava guava diff --git a/sop-auth/pom.xml b/sop-auth/pom.xml index 843589f6..9c978920 100644 --- a/sop-auth/pom.xml +++ b/sop-auth/pom.xml @@ -25,7 +25,7 @@ com.gitee.sop sop-service-common - ${project.version} + 5.0.0-SNAPSHOT diff --git a/sop-common/sop-bridge-nacos/pom.xml b/sop-common/sop-bridge-nacos/pom.xml index 777683da..cf80c52e 100644 --- a/sop-common/sop-bridge-nacos/pom.xml +++ b/sop-common/sop-bridge-nacos/pom.xml @@ -5,7 +5,7 @@ com.gitee.sop sop-common - 4.4.2-SNAPSHOT + 5.0.0-SNAPSHOT ../pom.xml 4.0.0 @@ -15,7 +15,7 @@ com.gitee.sop sop-gateway-common - ${project.version} + 5.0.0-SNAPSHOT diff --git a/sop-example/pom.xml b/sop-example/pom.xml index 55501b45..e675beda 100644 --- a/sop-example/pom.xml +++ b/sop-example/pom.xml @@ -15,6 +15,5 @@ sop-story - sop-springmvc diff --git a/sop-example/sop-springmvc/.gitignore b/sop-example/sop-springmvc/.gitignore deleted file mode 100644 index c456c4a3..00000000 --- a/sop-example/sop-springmvc/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -/target/ -!.mvn/wrapper/maven-wrapper.jar - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -/build/ diff --git a/sop-example/sop-springmvc/pom.xml b/sop-example/sop-springmvc/pom.xml deleted file mode 100644 index bdb5a8bf..00000000 --- a/sop-example/sop-springmvc/pom.xml +++ /dev/null @@ -1,181 +0,0 @@ - - - - - com.gitee.sop - sop-parent - 5.0.0-SNAPSHOT - ../../pom.xml - - - 4.0.0 - sop-springmvc - sop-springmvc - war - - - 1.8 - 5.0.7.RELEASE - 1.6.10 - 1.7.25 - - - - - - com.gitee.sop - sop-service-common - ${project.version} - - - - com.alibaba.nacos - nacos-spring-context - 0.3.3 - - - - - - - - org.springframework - spring-context - ${org.springframework-version} - - - org.springframework - spring-webmvc - ${org.springframework-version} - - - - org.hibernate.validator - hibernate-validator - - - - - com.fasterxml.jackson.core - jackson-core - 2.9.6 - - - com.fasterxml.jackson.core - jackson-databind - 2.9.6 - - - com.fasterxml.jackson.core - jackson-annotations - 2.9.6 - - - - - org.aspectj - aspectjrt - ${org.aspectj-version} - - - - - org.slf4j - slf4j-api - ${org.slf4j-version} - - - org.slf4j - jcl-over-slf4j - ${org.slf4j-version} - runtime - - - org.slf4j - slf4j-log4j12 - ${org.slf4j-version} - runtime - - - log4j - log4j - 1.2.17 - - - - - io.springfox - springfox-swagger2 - - - - - javax.inject - javax.inject - 1 - - - - - javax.servlet - servlet-api - 2.5 - provided - - - javax.servlet.jsp - jsp-api - 2.1 - provided - - - javax.servlet - jstl - 1.2 - - - - - junit - junit - 4.8 - test - - - org.springframework - spring-tx - 5.1.5.RELEASE - compile - - - org.projectlombok - lombok - 1.18.4 - provided - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.18.1 - - true - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java-version} - ${java-version} - UTF-8 - - - - - diff --git a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/MyPropertySourcesPlaceholderConfigurer.java b/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/MyPropertySourcesPlaceholderConfigurer.java deleted file mode 100644 index c6b2b9c8..00000000 --- a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/MyPropertySourcesPlaceholderConfigurer.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.gitee.app.config; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.EnvironmentAware; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.core.env.Environment; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.PropertySources; -import org.springframework.web.context.support.StandardServletEnvironment; - -import java.util.Map; -import java.util.Properties; - -/** - * @author tanghc - */ -public class MyPropertySourcesPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer implements EnvironmentAware { - - private Environment environment; - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - super.postProcessBeanFactory(beanFactory); - if (environment instanceof StandardServletEnvironment) { - PropertySources appliedPropertySources = this.getAppliedPropertySources(); - for (PropertySource propertySource : appliedPropertySources) { - Object source = propertySource.getSource(); - if (source instanceof Map) { - Map map = (Map)source; - map.forEach((key, value)-> { - System.setProperty(key.toString(), value.toString()); - }); - } - } - } - } -} diff --git a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServiceConfig.java b/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServiceConfig.java deleted file mode 100644 index ff464c16..00000000 --- a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServiceConfig.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.gitee.app.config; - -import com.alibaba.nacos.api.annotation.NacosInjected; -import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.api.naming.NamingService; -import com.alibaba.nacos.api.naming.pojo.Instance; -import com.alibaba.nacos.api.utils.NetUtils; -import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery; -import com.gitee.sop.servercommon.configuration.SpringmvcConfiguration; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; - -/** - * 使用支付宝开放平台功能 - * - * @author tanghc - */ -@Slf4j -@EnableNacosDiscovery -public class OpenServiceConfig extends SpringmvcConfiguration { - - - public static final String SPRING_APPLICATION_NAME = "spring.application.name"; - public static final String SERVER_CONTEXT_PATH = "server.servlet.context-path"; - public static final String SERVER_IP = "server.ip"; - public static final String SERVER_PORT = "server.port"; - public static final String METADATA_TIME_STARTUP = "server.startup-time"; - - @Value("${spring.application.name}") - private String serviceId; - @Value("${server.port}") - private int port; - @Value("${server.servlet.context-path}") - private String contextPath; - - @NacosInjected - private NamingService namingService; - - @Override - protected void doAfter() { - super.doAfter(); - try { - String ip = NetUtils.localIP(); - System.setProperty(SPRING_APPLICATION_NAME, serviceId); - System.setProperty(SERVER_IP, ip); - System.setProperty(SERVER_PORT, String.valueOf(port)); - System.setProperty(SERVER_CONTEXT_PATH, contextPath); - - Instance instance = this.getInstance(serviceId, ip, port, contextPath); - namingService.registerInstance(serviceId, instance); - log.info("注册到nacos, serviceId: {}, ip: {}, port: {}, contextPath: {}", serviceId, ip, port, contextPath); - } catch (NacosException e) { - log.error("注册nacos失败", e); - throw new RuntimeException("注册nacos失败", e); - } - } - - private Instance getInstance(String serviceId, String ip, int port, String contextPath) { - Instance instance = new Instance(); - instance.setServiceName(serviceId); - instance.setIp(ip); - instance.setPort(port); - instance.getMetadata().put(METADATA_SERVER_CONTEXT_PATH, contextPath); - instance.getMetadata().put(METADATA_TIME_STARTUP, String.valueOf(System.currentTimeMillis())); - return instance; - } - -} diff --git a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServletContextListener.java b/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServletContextListener.java deleted file mode 100644 index 8b65ed64..00000000 --- a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServletContextListener.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.gitee.app.config; - -import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.api.naming.NamingService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.WebApplicationContextUtils; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -/** - * 容器销毁注销nacos,配置见web.xml - */ -@Slf4j -public class OpenServletContextListener implements ServletContextListener { - - private static WebApplicationContext webApplicationContext; - - @Override - public void contextDestroyed(ServletContextEvent sce) { - String serviceId = System.getProperty(OpenServiceConfig.SPRING_APPLICATION_NAME); - String ip = System.getProperty(OpenServiceConfig.SERVER_IP); - String port = System.getProperty(OpenServiceConfig.SERVER_PORT); - - log.info("注销nacos,serviceId:{}, ip:{}, port:{}", serviceId, ip, port); - - NamingService namingService = webApplicationContext.getBean(NamingService.class); - try { - namingService.deregisterInstance(serviceId, ip, Integer.parseInt(port)); - } catch (NacosException e) { - log.error("注销nacos服务失败,serviceId:{}, ip:{}, port:{}", serviceId, ip, port); - } - } - - @Override - public void contextInitialized(ServletContextEvent sce) { - webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()); - } - -} \ No newline at end of file diff --git a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/Swagger2.java b/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/Swagger2.java deleted file mode 100644 index d09fd292..00000000 --- a/sop-example/sop-springmvc/src/main/java/com/gitee/app/config/Swagger2.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.gitee.app.config; - -import com.gitee.sop.servercommon.swagger.SwaggerSupport; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -/** - * 开启文档,本地微服务文档地址:http://localhost:2222/doc.html - * http://ip:port/v2/api-docs - */ -@EnableSwagger2 -public class Swagger2 extends SwaggerSupport { - @Override - protected String getDocTitle() { - return "MVC_API"; - } - - @Override - protected boolean swaggerAccessProtected() { - return false; - } -} \ No newline at end of file diff --git a/sop-example/sop-springmvc/src/main/java/com/gitee/app/controller/HomeController.java b/sop-example/sop-springmvc/src/main/java/com/gitee/app/controller/HomeController.java deleted file mode 100644 index 8141a359..00000000 --- a/sop-example/sop-springmvc/src/main/java/com/gitee/app/controller/HomeController.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.gitee.app.controller; - -import com.gitee.app.model.Goods; -import com.gitee.app.model.StoryParam; -import com.gitee.sop.servercommon.annotation.Open; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -import java.math.BigDecimal; -import java.text.DateFormat; -import java.util.Date; -import java.util.Locale; - -/** - * Handles requests for the application home page. - */ -@Api(tags = "MVC接口") -@Controller -public class HomeController { - - private static final Logger logger = LoggerFactory.getLogger(HomeController.class); - - /** - * Simply selects the home view to render by returning its name. - */ - @RequestMapping(value = "/", method = RequestMethod.GET) - public String home(Locale locale, Model model) { - logger.info("Welcome home! The client locale is {}.", locale); - - Date date = new Date(); - DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); - - String formattedDate = dateFormat.format(date); - - model.addAttribute("serverTime", formattedDate ); - - return "home"; - } - - - @ApiOperation(value="获取商品", notes = "获取商品说明") - @Open("springmvc.goods.get") - @RequestMapping("/goods/get") - @ResponseBody - public Goods getGoods(Goods param) { - Goods goods = new Goods(); - goods.setId(1L); - goods.setGoods_name(param.getGoods_name() + " 1"); - goods.setPrice(new BigDecimal(5000)); - return goods; - } - - @Open("springmvc.path.same") - @RequestMapping("iam_same_path") - @ResponseBody - public Object iam_same_path(StoryParam param) { - param.setName(param.getName() + " mvc.."); - return param; - } - -} diff --git a/sop-example/sop-springmvc/src/main/java/com/gitee/app/model/Goods.java b/sop-example/sop-springmvc/src/main/java/com/gitee/app/model/Goods.java deleted file mode 100644 index b5331a0a..00000000 --- a/sop-example/sop-springmvc/src/main/java/com/gitee/app/model/Goods.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.app.model; - - -import lombok.Data; - -import javax.validation.constraints.NotBlank; -import java.math.BigDecimal; - -@Data -public class Goods { - - private Long id; - @NotBlank(message = "goods_name不能为空") - private String goods_name; - private BigDecimal price; - -} diff --git a/sop-example/sop-springmvc/src/main/java/com/gitee/app/model/StoryParam.java b/sop-example/sop-springmvc/src/main/java/com/gitee/app/model/StoryParam.java deleted file mode 100644 index 5fcebfff..00000000 --- a/sop-example/sop-springmvc/src/main/java/com/gitee/app/model/StoryParam.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.gitee.app.model; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.Max; -import javax.validation.constraints.NotBlank; - -@Data -public class StoryParam { - @ApiModelProperty(value = "故事ID", example = "111") - private int id; - - @NotBlank(message = "name不能为空") - @Length(max = 20, message = "name长度不能超过20") - @ApiModelProperty(value = "故事名称", required = true, example = "白雪公主", position = 3) - private String name; - - @ApiModelProperty(value = "备注 (第二)", example = "xx", position = 2) - @Length(max = 64, message = "长度不能超过64") - private String remark; -} \ No newline at end of file diff --git a/sop-example/sop-springmvc/src/main/resources/application.properties b/sop-example/sop-springmvc/src/main/resources/application.properties deleted file mode 100644 index 131f56dc..00000000 --- a/sop-example/sop-springmvc/src/main/resources/application.properties +++ /dev/null @@ -1,5 +0,0 @@ -spring.application.name=sop-springmvc -server.port=2223 -server.servlet.context-path=/sop-springmvc - -nacos.server-addr=127.0.0.1:8848 diff --git a/sop-example/sop-springmvc/src/main/resources/log4j.xml b/sop-example/sop-springmvc/src/main/resources/log4j.xml deleted file mode 100644 index ef6038bc..00000000 --- a/sop-example/sop-springmvc/src/main/resources/log4j.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sop-example/sop-springmvc/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml b/sop-example/sop-springmvc/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml deleted file mode 100644 index b5893103..00000000 --- a/sop-example/sop-springmvc/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - classpath:application.properties - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sop-example/sop-springmvc/src/main/webapp/WEB-INF/spring/root-context.xml b/sop-example/sop-springmvc/src/main/webapp/WEB-INF/spring/root-context.xml deleted file mode 100644 index 3040fd18..00000000 --- a/sop-example/sop-springmvc/src/main/webapp/WEB-INF/spring/root-context.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - classpath:application.properties - - - - - - - - - - diff --git a/sop-example/sop-springmvc/src/main/webapp/WEB-INF/views/home.jsp b/sop-example/sop-springmvc/src/main/webapp/WEB-INF/views/home.jsp deleted file mode 100644 index e65155c0..00000000 --- a/sop-example/sop-springmvc/src/main/webapp/WEB-INF/views/home.jsp +++ /dev/null @@ -1,15 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ page session="false" pageEncoding="utf-8" %> - - - - Home - - -

- Hello world! -

- -

The time on the server is ${serverTime}.

- - diff --git a/sop-example/sop-springmvc/src/main/webapp/WEB-INF/web.xml b/sop-example/sop-springmvc/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 630564eb..00000000 --- a/sop-example/sop-springmvc/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - contextConfigLocation - /WEB-INF/spring/root-context.xml - - - - - org.springframework.web.context.ContextLoaderListener - - - - - com.gitee.app.config.OpenServletContextListener - - - - - appServlet - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - /WEB-INF/spring/appServlet/servlet-context.xml - - 1 - - - - - appServlet - /v2/api-docs - - - appServlet - /swagger-resources - - - appServlet - /swagger-resources/configuration/ui - - - appServlet - /swagger-resources/configuration/security - - - - appServlet - /v2/api-docs-ext - - - - appServlet - / - - - diff --git a/sop-example/sop-springmvc/src/test/resources/log4j.xml b/sop-example/sop-springmvc/src/test/resources/log4j.xml deleted file mode 100644 index e807a3a7..00000000 --- a/sop-example/sop-springmvc/src/test/resources/log4j.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sop-example/sop-story/pom.xml b/sop-example/sop-story/pom.xml index 9d9e05b2..9dcd2551 100644 --- a/sop-example/sop-story/pom.xml +++ b/sop-example/sop-story/pom.xml @@ -10,6 +10,7 @@ 4.0.0 sop-story + sop-story 1.8 @@ -18,8 +19,8 @@ com.gitee.sop - sop-service-common - ${project.version} + sop-spring-boot-starter + 5.0.0-SNAPSHOT @@ -27,32 +28,25 @@ spring-boot-starter-web - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - - - - - - - org.springframework.cloud - spring-cloud-starter-openfeign - - - - - io.springfox - springfox-boot-starter + org.apache.dubbo + dubbo-spring-boot-starter - com.github.xiaoymin - knife4j-spring-boot-starter + com.alibaba.boot + nacos-discovery-spring-boot-starter + 0.2.1 + + + + org.apache.commons + commons-lang3 + + + + org.springframework.boot + spring-boot-starter-validation @@ -63,7 +57,7 @@ org.projectlombok lombok - 1.18.4 + 1.18.34 provided diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/SopStoryApplication.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/SopStoryApplication.java index 3cccb4ae..e78bbf68 100644 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/SopStoryApplication.java +++ b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/SopStoryApplication.java @@ -1,11 +1,11 @@ package com.gitee.sop.storyweb; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -@EnableDiscoveryClient @SpringBootApplication +@EnableDubbo public class SopStoryApplication { public static void main(String[] args) { diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/StoryGlobalExceptionHandler.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/StoryGlobalExceptionHandler.java deleted file mode 100644 index 78451b3e..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/StoryGlobalExceptionHandler.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.gitee.sop.storyweb; - -import com.gitee.sop.servercommon.exception.ExceptionHolder; -import com.gitee.sop.servercommon.exception.ServiceException; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * 全局异常处理 - * - * @author tanghc - */ -@ControllerAdvice -@Slf4j -public class StoryGlobalExceptionHandler { - - - /** - * 捕获手动抛出的异常 - * - * @param request request - * @param response response - * @param exception 异常信息 - * @return 返回提示信息 - */ - @ExceptionHandler(Exception.class) - @ResponseBody - public Object exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) { - // 在返回前加这一句 - ExceptionHolder.hold(request, response, exception); - // 下面可以实现自己的全局异常处理 - return new ErrorResult(500, exception.getMessage()); - } - - @Data - @AllArgsConstructor - public static class ErrorResult { - private int code; - private String msg; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/config/OpenServiceConfig.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/config/OpenServiceConfig.java deleted file mode 100644 index 25ec0a3a..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/config/OpenServiceConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.gitee.sop.storyweb.config; - -import com.gitee.sop.servercommon.bean.ServiceConfig; -import com.gitee.sop.servercommon.configuration.AlipayServiceConfiguration; -import com.gitee.sop.servercommon.swagger.SwaggerSupport; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -/** - * 开放平台功能 - * @author tanghc - */ -@Configuration -public class OpenServiceConfig extends AlipayServiceConfiguration { - - static { - ServiceConfig.getInstance().getI18nModules().add("i18n/isp/goods_error"); - } - - - /** - * 开启文档,本地微服务文档地址:http://localhost:2222/doc.html - * http://ip:port/v2/api-docs - */ - @Configuration - @EnableSwagger2 - public static class Swagger2 extends SwaggerSupport { - @Override - protected String getDocTitle() { - return "故事API"; - } - - @Override - protected boolean swaggerAccessProtected() { - return false; - } - } - -} - diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java deleted file mode 100644 index 27ef9059..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java +++ /dev/null @@ -1,329 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.gitee.sop.servercommon.annotation.BizCode; -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.servercommon.bean.OpenContext; -import com.gitee.sop.servercommon.bean.ServiceContext; -import com.gitee.sop.servercommon.exception.ServiceException; -import com.gitee.sop.storyweb.controller.param.ArrayElementParam; -import com.gitee.sop.storyweb.controller.param.CategoryParam; -import com.gitee.sop.storyweb.controller.param.GoodsParam; -import com.gitee.sop.storyweb.controller.param.LargeTextParam; -import com.gitee.sop.storyweb.controller.param.MemberInfoGetParam; -import com.gitee.sop.storyweb.controller.param.StoryParam; -import com.gitee.sop.storyweb.controller.param.TypeEnum; -import com.gitee.sop.storyweb.controller.result.CategoryResult; -import com.gitee.sop.storyweb.controller.result.MemberInfoGetResult; -import com.gitee.sop.storyweb.controller.result.MemberInfoGetResultMemberInfo; -import com.gitee.sop.storyweb.controller.result.StoryResult; -import com.gitee.sop.storyweb.controller.result.TestResult; -import com.gitee.sop.storyweb.controller.result.TreeResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.util.StringUtils; -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.RequestParam; -import org.springframework.web.bind.annotation.RestController; -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; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * 签名验证通过后,到达这里进行具体的业务处理。 - * - * @author tanghc - */ -@RestController -@RequestMapping("story") -@Slf4j -@Api(tags = "故事接口") -public class Example1001_BaseController { - - @Value("${server.port}") - private int port; - - // http://localhost:2222/stroy/get - // 原生的接口,可正常调用 - @RequestMapping("/get") - public StoryResult get() { - StoryResult result = new StoryResult(); - result.setId(1L); - result.setName("海底小纵队(原生)"); - return result; - } - - // 基础用法 - @ApiOperation(value = "获取故事信息(首位)", notes = "获取故事信息的详细信息", position = -100/* position默认0,值越小越靠前 */) - @Open(value = "story.get", bizCode = { - // 定义业务错误码,用于文档显示 - @BizCode(code = "100001", msg = "姓名错误", solution = "填写正确的姓名"), - @BizCode(code = "100002", msg = "备注错误", solution = "填写正确备注"), - }) - @RequestMapping("/get/v1") - public StoryResult get_v1(StoryParam param) { - StoryResult story = new StoryResult(); - story.setId(1L); - story.setName("海底小纵队(story.get1.0), " + "param:" + param + ", port:" + port); - return story; - } - - // 指定版本号 - @ApiOperation(value = "获取故事信息", notes = "获取故事信息的详细信息") - @Open(value = "story.get", version = "2.0", bizCode = { - // 定义业务错误码,用于文档显示 - @BizCode(code = "100001", msg = "姓名错误", solution = "填写正确的姓名"), - @BizCode(code = "100002", msg = "备注错误", solution = "填写正确备注"), - }) - @RequestMapping("/get/v2") - public StoryResult get_v2(StoryParam param) { - StoryResult story = new StoryResult(); - story.setId(1L); - story.setName("海底小纵队(story.get2.0), " + "param:" + param); - return story; - } - - @Open(value = "story.system.param.get") - @GetMapping("/get/system/param/v1") - public StoryResult systemParam(StoryParam param) { - StoryResult result = new StoryResult(); - OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext(); - System.out.println(param == openContext.getBizObject()); - System.out.println("app_id:" + openContext.getAppId()); - System.out.println("token:" + openContext.getAppAuthToken()); - result.setName("系统参数:" + openContext); - return result; - } - - @Open(value = "story.system.param.get2") - @GetMapping("/get/system/param/v2") - public StoryResult systemParam2() { - StoryResult result = new StoryResult(); - OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext(); - String token = openContext.getAppAuthToken(); - result.setName(token); - return result; - } - - @Open(value = "story.system.param.get3") - @GetMapping("/get/system/param/v3") - public StoryResult systemParam3(HttpServletRequest request) { - System.out.println(request.getParameter("app_id")); - StoryResult result = new StoryResult(); - OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext(); - String token = openContext.getAppAuthToken(); - result.setName(token); - return result; - } - - @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; - } - - // 参数绑定,少量参数可以这样写,参数多了建议放进类里面 - @Open(value = "story.oneparam") - @GetMapping("/oneParam/v1") - public StoryResult oneParam(@NotBlank(message = "id不能为空") String id, @NotBlank(message = "name不能为空") String name) { - StoryResult result = new StoryResult(); - result.setName("id:" + id + ", name:" + name); - return result; - } - - // 参数绑定 - @Open(value = "story.oneparam", version = "1.1") - @GetMapping("/oneParam/v2") - public StoryResult oneParamV2(Integer id) { - StoryResult result = new StoryResult(); - result.setName("id:" + id); - return result; - } - - // 参数绑定,枚举 - @Open(value = "story.oneparam", version = "1.2") - @GetMapping("/oneParam/v3") - public StoryResult oneParamV2(@NotNull(message = "typeEnum不能为空") TypeEnum typeEnum) { - StoryResult result = new StoryResult(); - result.setName("typeEnum:" + typeEnum.name()); - return result; - } - - // 参数绑定 - @Open(value = "story.param.bind", mergeResult = false) - @RequestMapping("/get/param/v1") - public StoryResult param(String id, String name) { - StoryResult result = new StoryResult(); - result.setName("参数绑定:id:" + id + ", name:" + name); - return result; - } - - // 忽略验证 - @ApiOperation(value = "忽略签名验证", notes = "忽略签名验证") - @Open(value = "story.get.ignore", ignoreValidate = true) - @RequestMapping(value = "/get/ignore/v1") - public StoryResult getStory21(@RequestBody StoryParam story) { - StoryResult result = new StoryResult(); - result.setId((long) story.getId()); - result.setName(story.getName() + ", ignoreValidate = true"); - return result; - } - - @ApiOperation(value = "接收数组", notes = "接收数组") - @Open(value = "story.listparam") - @PostMapping(value = "/get/listparam/v1") - public StoryResult listparam(@RequestBody ArrayElementParam story) { - StoryResult result = new StoryResult(); - result.setId(11L); - result.setName(JSON.toJSONString(story)); - return result; - } - - @Open(value = "story.get.large") - @RequestMapping("/get/large/v1") - public StoryResult getStoryLarge(LargeTextParam param) { - StoryResult result = new StoryResult(); - int length = param.getContent().getBytes(StandardCharsets.UTF_8).length; - result.setName("length:" + length); - return result; - } - - // 绑定复杂对象 - @Open(value = "sdt.get",version = "4.0") - @RequestMapping("/get/v4") - public TestResult getV4(@RequestBody TestResult testResult) { - if(StringUtils.isEmpty(testResult.getType())) { - throw new ServiceException("testResult.getType() 不能为null"); - } - return testResult; - } - - // 获取header - @Open(value = "test.head",version = "1.0") - @GetMapping("/get/header/v1") - public StoryResult header(@RequestBody StoryParam story, HttpServletRequest request) { - HttpServletRequest servletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); - StoryResult storyResult = new StoryResult(); - storyResult.setId(1L); - storyResult.setName(story.getName() - + ", token1:" + request.getHeader("token") - + ", token2:" + servletRequest.getHeader("token")); - return storyResult; - } - - // 返回数组结果 - @ApiOperation(value = "返回数组结果(第二)", notes = "返回数组结果", position = -99) - @Open("story.list") - @RequestMapping("/list/v1") - public List getStory3(StoryParam story) { - int index = 0; - StoryResult storyVO = new StoryResult(); - storyVO.setId(1L); - storyVO.setName("白雪公主, index:" + index++); - storyVO.setGmt_create(new Date()); - - StoryResult storyVO2 = new StoryResult(); - storyVO2.setId(1L); - storyVO2.setName("白雪公主, index:" + index++); - storyVO2.setGmt_create(new Date()); - - return Arrays.asList(storyVO, storyVO2); - } - - // 演示文档表格树 - @ApiOperation(value = "获取分类信息", notes = "演示表格树") - @Open("category.get") - @PostMapping("/category/get/v1") - public CategoryResult getCategory(CategoryParam param) { - System.out.println(param); - StoryResult result = new StoryResult(); - result.setId(1L); - result.setName("白雪公主"); - result.setGmt_create(new Date()); - CategoryResult categoryResult = new CategoryResult(); - categoryResult.setCategoryName("娱乐"); - categoryResult.setStoryResult(result); - return categoryResult; - } - - // 演示文档页树状返回 - @ApiOperation(value = "树状返回", notes = "树状返回") - @Open("story.tree.get") - @PostMapping("/tree/v1") - public TreeResult tree(StoryParam param) { - int id = 0; - TreeResult parent = new TreeResult(); - parent.setId(++id); - parent.setName("父节点"); - parent.setPid(0); - - TreeResult child1 = new TreeResult(); - child1.setId(++id); - child1.setName("子节点1"); - child1.setPid(1); - - TreeResult child2 = new TreeResult(); - child2.setId(++id); - child2.setName("子节点2"); - child2.setPid(1); - - parent.setChildren(Arrays.asList(child1, child2)); - - return parent; - } - - private static String json = "{\"flightDate\":\"2020-09-01\",\"flightNo\":\"HO1705\",\"departureAirport\":\"ZSCN\",\"arrivalAirport\":\"ZPLJ\",\"ycy\":\"11521\",\"lcy\":\"4354\",\"cr\":\"145\",\"et\":\"1\",\"ye\":\"0\",\"td\":\"0\",\"gw\":\"0\",\"ew\":\"146\",\"xl\":\"1018\",\"yj\":\"0\",\"hw\":\"635\"}"; - // 返回大数据 - @Open(value = "bigdata.get") - @RequestMapping("/bigdata/v1") - public Map bigData(StoryParam param) { - int len = 2000; - List list = new ArrayList<>(len); - for (int i = 0; i < len; i++) { - list.add(JSON.parseObject(json)); - } - Map map = new HashMap<>(); - map.put("data", list); - return map; - } - - @Open(value = "member.info.get") - @RequestMapping("/member/info/get") - public MemberInfoGetResult memberInfoGet(MemberInfoGetParam param) { - MemberInfoGetResult result = new MemberInfoGetResult(); - MemberInfoGetResultMemberInfo memberInfo = new MemberInfoGetResultMemberInfo(); - memberInfo.setIsVip((byte)1); - memberInfo.setVipEndtime(new Date()); - result.setName(JSON.toJSONString(param)); - result.setId(11); - result.setMemberInfo(memberInfo); - return result; - } - -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1002_FileUploadController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1002_FileUploadController.java deleted file mode 100644 index accfa90c..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1002_FileUploadController.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.servercommon.util.UploadUtil; -import com.gitee.sop.storyweb.controller.param.FileUploadParam; -import com.gitee.sop.storyweb.controller.param.FileUploadParam2; -import com.gitee.sop.storyweb.controller.result.FileUploadResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; -import org.apache.commons.io.IOUtils; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Optional; - -/** - * 演示文件上传 - * - * @author tanghc - */ -@RestController -@RequestMapping("upload") -@Api(tags = "文件上传", position = 2) -public class Example1002_FileUploadController { - - /** - * 方式1:将文件写在参数中,可直接获取。好处是可以校验是否上传 - * @param param - * @return - */ - @ApiOperation(value = "文件上传例1", notes = "上传文件demo") - @Open("file.upload") - @PostMapping(value = "file1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public FileUploadResult file1(FileUploadParam param) { - // 获取上传的文件 - MultipartFile file1 = param.getFile1(); - MultipartFile file2 = param.getFile2(); - - FileUploadResult result = new FileUploadResult(); - FileUploadResult.FileMeta fileMeta1 = buildFileMeta(file1); - FileUploadResult.FileMeta fileMeta2 = buildFileMeta(file2); - - result.setRemark(param.getRemark()); - result.getFiles().add(fileMeta1); - result.getFiles().add(fileMeta2); - return result; - } - - /** - * 方式2:从request中获取上传文件 - * - * @param param - * @return - */ - @ApiOperation(value = "文件上传例2", notes = "可上传多个文件" - // 多文件上传、不确定文件数量上传,必须申明下面这句,否则沙盒界面不会出现上传控件 - , extensions = @Extension(properties = @ExtensionProperty(name = "multiple", value = "multiple"))) - @Open("file.upload2") - @PostMapping(value = "file2", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public FileUploadResult file2(FileUploadParam2 param, HttpServletRequest request) { - System.out.println(param.getRemark()); - FileUploadResult result = new FileUploadResult(); - // 获取上传的文件 - Collection uploadFiles = UploadUtil.getUploadFiles(request); - for (MultipartFile multipartFile : uploadFiles) { - FileUploadResult.FileMeta fileMeta = buildFileMeta(multipartFile); - result.getFiles().add(fileMeta); - } - return result; - } - - @Open("file.upload3") - @PostMapping(value = "file3", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public FileUploadResult file3(FileUploadParam2 param, HttpServletRequest request) { - System.out.println(param.getRemark()); - FileUploadResult result = new FileUploadResult(); - // 获取上传的文件 - Collection uploadFiles = UploadUtil.getUploadFiles(request); - Optional first = uploadFiles.stream().findFirst(); - if (first.isPresent()) { - MultipartFile multipartFile = first.get(); - try { - String path = System.getProperty("user.dir"); - multipartFile.transferTo(new File(path + "/img_"+System.currentTimeMillis()+".png")); - } catch (IOException e) { - e.printStackTrace(); - } - } - return result; - } - - private FileUploadResult.FileMeta buildFileMeta(MultipartFile multipartFile) { - // 文件名 - String fileName = multipartFile.getOriginalFilename(); - // 文件大小 - long size = multipartFile.getSize(); - // 文件内容 - String fileContent = null; - try { - fileContent = IOUtils.toString(multipartFile.getInputStream(), StandardCharsets.UTF_8); - } catch (IOException e) { - e.printStackTrace(); - } - return new FileUploadResult.FileMeta(fileName, size, fileContent); - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1003_DownloadController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1003_DownloadController.java deleted file mode 100644 index 54441368..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1003_DownloadController.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.storyweb.controller.param.StoryParam; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.apache.commons.io.IOUtils; -import org.springframework.core.io.ClassPathResource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -import java.io.IOException; - -/** - * 演示文件下载 - * - * @author tanghc - */ -@Api(tags = "文件下载", position = 3) -@Controller -@RequestMapping("download") -public class Example1003_DownloadController { - - @ApiOperation(value = "文件下载", notes = "演示文件下载") - @Open("file.download") - @RequestMapping(value = "file1", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE/* 这个一定要加,不然沙箱文档不起作用 */) - public ResponseEntity download(StoryParam param) throws IOException { - - HttpHeaders headers = new HttpHeaders(); - // 假设下载classpath下的application.properties文件 - ClassPathResource resource = new ClassPathResource("/application.properties"); - - headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); - headers.setContentDispositionFormData("attachment", resource.getFilename()); - - return ResponseEntity - .ok() - .headers(headers) - .body(IOUtils.toByteArray(resource.getInputStream())); - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1004_JSR303Controller.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1004_JSR303Controller.java deleted file mode 100644 index d7f69249..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1004_JSR303Controller.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.storyweb.controller.param.GoodsParam; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; - -/** - * 演示参数验证 - * @author tanghc - */ -@RestController -public class Example1004_JSR303Controller { - - @Open("goods.add") - @RequestMapping("jsr303") - public Object addGoods(GoodsParam param, HttpServletRequest request) { - System.out.println(request.getParameter("method")); - return param; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1005_PermissionController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1005_PermissionController.java deleted file mode 100644 index 7d3e2ea1..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1005_PermissionController.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.storyweb.controller.result.StoryResult; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * 支付宝服务端,假设签名验证通过后,到达这里进行具体的业务处理。 - * 这里演示如何接受业务参数。 - * @author tanghc - */ -@RestController -public class Example1005_PermissionController { - - @Open(value = "story.get.permission", permission = true) - @RequestMapping("perm/get") - public StoryResult getStory() { - StoryResult story = new StoryResult(); - story.setId(1L); - story.setName("海底小纵队(story.get.permission)"); - return story; - } - -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1005_ThrowExceptionController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1005_ThrowExceptionController.java deleted file mode 100644 index 7fc5fb11..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1005_ThrowExceptionController.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.servercommon.exception.ServiceException; -import com.gitee.sop.storyweb.controller.param.GoodsUpdateParam; -import com.gitee.sop.storyweb.message.GoodsErrorEnum; -import org.apache.commons.lang3.StringUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * 演示如何抛出异常 - * @author tanghc - */ -@RestController -public class Example1005_ThrowExceptionController { - - @Open("goods.update") - @RequestMapping("ex") - public Object updateGoods(GoodsUpdateParam param) { - // 方式1 - if ("iphone6".equals(param.getGoods_name())) { - throw new ServiceException("不能更新iphone6"); - } - // 方式2,国际化 - if (StringUtils.isEmpty(param.getGoods_name())) { - throw GoodsErrorEnum.NO_GOODS_NAME.getErrorMeta().getException(); - } - // 方式3,国际化传参 - if (param.getGoods_name().length() <= 3) { - throw GoodsErrorEnum.LESS_GOODS_NAME_LEN.getErrorMeta().getException(3); - } - return param; - } - - @Open("goods.update2") - @RequestMapping("ex2") - public Object updateGoods2(GoodsUpdateParam param) { - int i = 1/0; - return param; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1007_TokenController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1007_TokenController.java deleted file mode 100644 index af36b77e..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1007_TokenController.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.servercommon.bean.OpenContext; -import com.gitee.sop.servercommon.bean.ParamNames; -import com.gitee.sop.servercommon.bean.ServiceContext; -import com.gitee.sop.storyweb.controller.param.StoryParam; -import com.gitee.sop.storyweb.controller.result.StoryResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; - -/** - * @author tanghc - */ -@RestController -@Slf4j -@Api(tags = "故事接口") -public class Example1007_TokenController { - - @ApiOperation(value="传递token", notes = "传递token") - @Open(value = "story.get.token", needToken = true/* 设置true,网关会校验token是否存在 */) - @RequestMapping("token") - public StoryResult token(StoryParam story, HttpServletRequest request) { - OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext(); - StoryResult result = new StoryResult(); - result.setName("appAuthToken:" + openContext.getAppAuthToken()); - return result; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1008_RestfulController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1008_RestfulController.java deleted file mode 100644 index 2c7af9e7..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1008_RestfulController.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.util.UploadUtil; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.Data; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import java.math.BigDecimal; -import java.util.Collection; - -/** - * 传统web开发实例 - * - * @author tanghc - */ -@RestController -@RequestMapping("food") -@Api(tags = "食物接口") -public class Example1008_RestfulController { - - @Autowired - private Environment environment; - - // http://localhost:8081/rest/story-service/food/getFoodById?id=1 网关入口 - // http://localhost:2222/food/getFoodById/?id=12 本地入口 - @ApiOperation(value="获取食物", notes = "根据id获取食物") - @RequestMapping(value = "getFoodById", method = RequestMethod.GET) - public Food getFoodById(Integer id) { - Food food = new Food(); - food.setId(id); - food.setName("香蕉, " + environment.getProperty("server.port")); - food.setPrice(new BigDecimal(20.00)); - return food; - } - - // http://localhost:8081/rest/story-service/food/getFoodByObj?id=2 - @RequestMapping(value = "getFoodByObj", method = RequestMethod.GET) - public Food getFoodByObj(Food food) { - return food; - } - - // http://localhost:8081/rest/story-service/food/saveFood - @RequestMapping(value = "saveFood", method = RequestMethod.POST) - public Food saveFood(@RequestBody Food food) { - food.setId(3); - return food; - } - - @RequestMapping(value = "foodUpload", method = RequestMethod.POST) - public Food upload(Food food, HttpServletRequest request) { - // 获取上传的文件 - Collection uploadFiles = UploadUtil.getUploadFiles(request); - StringBuilder sb = new StringBuilder(); - for (MultipartFile multipartFile : uploadFiles) { - sb.append(multipartFile.getOriginalFilename()); - } - food.setId(4); - food.setName("文件名称+" + sb.toString()); - return food; - } - - @RequestMapping(value = "foodUpload3", method = RequestMethod.POST) - public Food upload3(Food food, MultipartFile file) { - food.setId(5); - food.setName("文件名称+" + file.getOriginalFilename()); - return food; - } - - @RequestMapping(value = "foodUpload2", method = RequestMethod.POST) - public Food upload2(Food food, MultipartFile file) { - food.setId(4); - food.setName("文件名称2+" + file.getOriginalFilename()); - return food; - } - - // http://localhost:2222/food/get/3 本地 - // http://localhost:8081/rest/story-service/food/get/3 网关访问 - @RequestMapping("/get/{id}") - public Food getById(@PathVariable("id") Integer id) { - Food food = new Food(); - food.setId(id); - food.setName("香蕉"); - food.setPrice(BigDecimal.valueOf(100)); - return food; - } - - @Data - public static class Food { - private Integer id; - private String name; - private BigDecimal price; - } - -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1009_TimeoutController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1009_TimeoutController.java deleted file mode 100644 index 0079893f..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1009_TimeoutController.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.storyweb.controller.param.StoryParam; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.concurrent.TimeUnit; - -/** - * 模拟超时设置 - * - * @author tanghc - */ -@RestController -public class Example1009_TimeoutController { - - @Open("goods.timeout") - @RequestMapping("timeoutTest") - public Object timeout(StoryParam param) { - // 模拟耗时操作,耗时10秒 - try { - TimeUnit.SECONDS.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return param; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1010_SamePathController.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1010_SamePathController.java deleted file mode 100644 index 11c1fc8c..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1010_SamePathController.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.gitee.sop.storyweb.controller; - -import com.gitee.sop.servercommon.annotation.Open; -import com.gitee.sop.storyweb.controller.param.StoryParam; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * 模拟超时设置 - * - * @author tanghc - */ -@RestController -public class Example1010_SamePathController { - - @Open("story.path.same") - @RequestMapping("iam_same_path") - public Object iam_same_path(StoryParam param) { - param.setName(param.getName() + " story.."); - return param; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/ArrayElementParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/ArrayElementParam.java deleted file mode 100644 index 0f2073bd..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/ArrayElementParam.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; - -/** - * @author tanghc - */ -@Data -public class ArrayElementParam { - - @ApiModelProperty(value = "名字", required = true, example = "白雪公主", position = 1) - private String name; - - @ApiModelProperty(value = "数组", required = true, dataType = "List", example = "白雪公主", position = 2) - private List list; - -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/CategoryParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/CategoryParam.java deleted file mode 100644 index 0fd791e5..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/CategoryParam.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.io.Serializable; -import java.util.Date; - -@Data -public class CategoryParam { - @ApiModelProperty(value = "分类名称", example = "娱乐") - private String categoryName; - - @ApiModelProperty(value = "创建时间", example = "2019-09-25 17:12:52") - private Date createTime; - - @ApiModelProperty(value = "分类故事") - private StoryParam storyParam; -} \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/FileUploadParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/FileUploadParam.java deleted file mode 100644 index 2be7875c..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/FileUploadParam.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.web.multipart.MultipartFile; - -import javax.validation.constraints.NotNull; - -/** - * @author tanghc - */ -@Data -public class FileUploadParam { - private String remark; - - // 上传文件,字段名称对应表单中的name属性值 - @NotNull(message = "请上传文件1") - @ApiModelProperty(value = "文件1", required = true) - private MultipartFile file1; - - @NotNull(message = "请上传文件2") - @ApiModelProperty(value = "文件2", required = true) - private MultipartFile file2; -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/FileUploadParam2.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/FileUploadParam2.java deleted file mode 100644 index 385da278..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/FileUploadParam2.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -import lombok.Data; - -/** - * @author tanghc - */ -@Data -public class FileUploadParam2 { - private String remark; - -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/GoodsParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/GoodsParam.java deleted file mode 100644 index 00eeebca..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/GoodsParam.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotBlank; - -@Data -public class GoodsParam { - @NotBlank(message = "商品名称不能为空") - private String goods_name; - - @NotBlank(message = "{goods.remark.notNull}") - private String goods_remark; - - // 传参的格式:{xxx}=value1,value2... - @Length(min = 3, max = 20, message = "{goods.comment.length}=3,20") - private String goods_comment; -} \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/GoodsUpdateParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/GoodsUpdateParam.java deleted file mode 100644 index c159c689..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/GoodsUpdateParam.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -import lombok.Data; - -@Data -public class GoodsUpdateParam { - private String goods_name; - -} \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/LargeTextParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/LargeTextParam.java deleted file mode 100644 index 62740655..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/LargeTextParam.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -import lombok.Data; - -/** - * @author tanghc - */ -@Data -public class LargeTextParam { - private String content; -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/MemberInfoGetParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/MemberInfoGetParam.java deleted file mode 100644 index 4f17974d..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/MemberInfoGetParam.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -/** - * 请求参数 - */ -public class MemberInfoGetParam { - private String name; - private Integer age; - private String address; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getAge() { - return age; - } - - public void setAge(Integer age) { - this.age = age; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/StoryParam.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/StoryParam.java deleted file mode 100644 index 84ae44ea..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/StoryParam.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.Max; -import javax.validation.constraints.NotBlank; - -@Data -public class StoryParam { - @ApiModelProperty(value = "故事ID", example = "111") - private int id; - - @NotBlank(message = "name不能为空") - @Length(max = 20, message = "name长度不能超过20") - @ApiModelProperty(value = "故事名称", required = true, example = "白雪公主", position = 3) - private String name; - - @ApiModelProperty(value = "备注 (第二)", example = "xx", position = 2) - @Length(max = 64, message = "长度不能超过64") - private String remark; -} \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/TypeEnum.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/TypeEnum.java deleted file mode 100644 index 56e387f5..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/TypeEnum.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.gitee.sop.storyweb.controller.param; - -/** - * @author tanghc - */ -public enum TypeEnum { - MOBILE, COMPUTER -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/CategoryResult.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/CategoryResult.java deleted file mode 100644 index 47311198..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/CategoryResult.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.sop.storyweb.controller.result; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -@Data -public class CategoryResult { - @ApiModelProperty(value = "分类名称", example = "娱乐") - private String categoryName; - - @ApiModelProperty(value = "分类故事") - private StoryResult storyResult; -} \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/FileUploadResult.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/FileUploadResult.java deleted file mode 100644 index 11f20176..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/FileUploadResult.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.gitee.sop.storyweb.controller.result; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author tanghc - */ -@Data -public class FileUploadResult { - - private List files = new ArrayList(); - private String remark; - - @Data - public static class FileMeta { - - public FileMeta(String filename, long size, String content) { - this.filename = filename; - this.size = size; - this.content = content; - } - - public FileMeta() { - } - - @ApiModelProperty(value = "文件名称", example = "1.txt") - private String filename; - @ApiModelProperty(value = "文件大小", example = "109") - private long size; - @ApiModelProperty(value = "文件内容", example = "啊啊啊") - private String content; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/MemberInfoGetResult.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/MemberInfoGetResult.java deleted file mode 100644 index 5dd5c69f..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/MemberInfoGetResult.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.gitee.sop.storyweb.controller.result; - -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * 接口返回结果 - */ -public class MemberInfoGetResult { - - private Integer id; - private String name; - - @JsonProperty("member_info") - private MemberInfoGetResultMemberInfo memberInfo; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public MemberInfoGetResultMemberInfo getMemberInfo() { - return memberInfo; - } - - public void setMemberInfo(MemberInfoGetResultMemberInfo memberInfo) { - this.memberInfo = memberInfo; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/MemberInfoGetResultMemberInfo.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/MemberInfoGetResultMemberInfo.java deleted file mode 100644 index 9b04cdd1..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/MemberInfoGetResultMemberInfo.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.gitee.sop.storyweb.controller.result; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Date; - -public class MemberInfoGetResultMemberInfo { - @JsonProperty("is_vip") - private Byte isVip; - - @JsonProperty("vip_endtime") - private Date vipEndtime; - - public Byte getIsVip() { - return isVip; - } - - public void setIsVip(Byte isVip) { - this.isVip = isVip; - } - - public Date getVipEndtime() { - return vipEndtime; - } - - public void setVipEndtime(Date vipEndtime) { - this.vipEndtime = vipEndtime; - } -} \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/StoryResult.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/StoryResult.java deleted file mode 100644 index 80f6f69b..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/StoryResult.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.sop.storyweb.controller.result; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotBlank; -import java.util.Date; - -/** - * @author tanghc - */ -@Data -public class StoryResult { - @ApiModelProperty(value = "故事ID", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "故事名称", required = true, example = "海底小纵队") - @Length(max = 20) - private String name; - - @ApiModelProperty(value = "创建时间", example = "2019-04-14 19:02:12") - private Date gmt_create; -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/TestResult.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/TestResult.java deleted file mode 100644 index bc0d26f7..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/TestResult.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gitee.sop.storyweb.controller.result; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; - -@Data -public class TestResult { - - @ApiModelProperty(value = "标签", example = "学习") - private String label; - - @ApiModelProperty(value = "类型", example = "1 超管 2 普管") - private String type; - - @ApiModelProperty(value = "集合", example = "集合") - List ss; - -} \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/TreeResult.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/TreeResult.java deleted file mode 100644 index 58ecf0ae..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/result/TreeResult.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.sop.storyweb.controller.result; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; - -/** - * @author tanghc - */ -@Data -public class TreeResult { - @ApiModelProperty(value = "id") - private Integer id; - - @ApiModelProperty(value = "名称") - private String name; - - @ApiModelProperty(value = "父id") - private Integer pid; - - @ApiModelProperty(value = "子节点") - private List children; -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/message/GoodsErrorEnum.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/message/GoodsErrorEnum.java deleted file mode 100644 index c3d3e9c3..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/message/GoodsErrorEnum.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gitee.sop.storyweb.message; - -import com.gitee.sop.servercommon.message.ServiceErrorMeta; - -public enum GoodsErrorEnum { - /** 参数错误 */ - NO_GOODS_NAME("100"), - /** 参数长度太短 */ - LESS_GOODS_NAME_LEN("101"), - ; - private ServiceErrorMeta errorMeta; - - GoodsErrorEnum(String subCode) { - this.errorMeta = new ServiceErrorMeta("isp.goods_error_", subCode); - } - - public ServiceErrorMeta getErrorMeta() { - return errorMeta; - } -} \ No newline at end of file diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/message/StoryErrorEnum.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/message/StoryErrorEnum.java deleted file mode 100644 index 95739417..00000000 --- a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/message/StoryErrorEnum.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.gitee.sop.storyweb.message; - -import com.gitee.sop.servercommon.message.ServiceErrorMeta; - -/** - * @author tanghc - */ -public enum StoryErrorEnum { - /** 参数错误 */ - param_error("isv.invalid-parameter"), - ; - private ServiceErrorMeta errorMeta; - - StoryErrorEnum(String subCode) { - this.errorMeta = new ServiceErrorMeta("isp.error_", subCode); - } - - public ServiceErrorMeta getErrorMeta() { - return errorMeta; - } -} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/StoryService.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/StoryService.java new file mode 100644 index 00000000..ed727055 --- /dev/null +++ b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/StoryService.java @@ -0,0 +1,15 @@ +package com.gitee.sop.storyweb.open; + +import com.gitee.sop.storyweb.open.req.StorySaveDTO; +import com.gitee.sop.storyweb.open.resp.StoryResponse; + +/** + * @author 六如 + */ +public interface StoryService { + + Integer save(StorySaveDTO storySaveDTO); + + StoryResponse getById(Integer id); + +} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/impl/StoreyServiceImpl.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/impl/StoreyServiceImpl.java new file mode 100644 index 00000000..b58edbeb --- /dev/null +++ b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/impl/StoreyServiceImpl.java @@ -0,0 +1,35 @@ +package com.gitee.sop.storyweb.open.impl; + +import com.gitee.sop.springboot.starter.annotation.Open; +import com.gitee.sop.storyweb.open.StoryService; +import com.gitee.sop.storyweb.open.req.StorySaveDTO; +import com.gitee.sop.storyweb.open.resp.StoryResponse; +import org.apache.dubbo.config.annotation.DubboService; + +import javax.validation.constraints.NotNull; + + +/** + * 开放接口实现 + * + * @author 六如 + */ +@DubboService(validation = "true") +public class StoreyServiceImpl implements StoryService { + + @Open("story.save") + @Override + public Integer save(StorySaveDTO storySaveDTO) { + System.out.println("save storySaveDTO:" + storySaveDTO); + return 1; + } + + @Open("story.get") + @Override + public StoryResponse getById(@NotNull(message = "id必填") Integer id) { + StoryResponse storyResponse = new StoryResponse(); + storyResponse.setId(id); + storyResponse.setName("乌鸦喝水"); + return storyResponse; + } +} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/req/StorySaveDTO.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/req/StorySaveDTO.java new file mode 100644 index 00000000..995ae1c7 --- /dev/null +++ b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/req/StorySaveDTO.java @@ -0,0 +1,23 @@ +package com.gitee.sop.storyweb.open.req; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; + +/** + * @author 六如 + */ +@Data +public class StorySaveDTO implements Serializable { + private static final long serialVersionUID = -1214422742659231037L; + + @NotBlank(message = "故事名称必填") + private String storyName; + + @NotNull(message = "添加时间必填") + private Date addTime; + +} diff --git a/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/resp/StoryResponse.java b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/resp/StoryResponse.java new file mode 100644 index 00000000..124eaa49 --- /dev/null +++ b/sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/open/resp/StoryResponse.java @@ -0,0 +1,18 @@ +package com.gitee.sop.storyweb.open.resp; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author 六如 + */ +@Data +public class StoryResponse implements Serializable { + private static final long serialVersionUID = -3743413007549072654L; + + private Integer id; + + private String name; + +} diff --git a/sop-example/sop-story/src/main/resources/application-dev.properties b/sop-example/sop-story/src/main/resources/application-dev.properties index b54bc292..641cfe3d 100644 --- a/sop-example/sop-story/src/main/resources/application-dev.properties +++ b/sop-example/sop-story/src/main/resources/application-dev.properties @@ -1,9 +1,9 @@ -server.port=2222 +server.port=8082 spring.application.name=story-service -register.url=127.0.0.1:8848 -# \u6CE8\u518C\u4E2D\u5FC3 -spring.cloud.nacos.discovery.server-addr=${register.url} +# nacos +nacos.host=127.0.0.1:8848 -# \u4E0A\u4F20\u6587\u4EF6\u6700\u5927\u503C -spring.servlet.multipart.max-file-size=20MB -spring.servlet.multipart.max-request-size=20MB \ No newline at end of file +dubbo.protocol.name=dubbo +dubbo.protocol.port=-1 +dubbo.application.qos-enable=false +dubbo.registry.address=nacos://${nacos.host} diff --git a/sop-example/sop-story/src/main/resources/application.properties b/sop-example/sop-story/src/main/resources/application.properties index 3ab49793..cbb42d2a 100644 --- a/sop-example/sop-story/src/main/resources/application.properties +++ b/sop-example/sop-story/src/main/resources/application.properties @@ -1,2 +1 @@ spring.profiles.active=dev -spring.mvc.pathmatch.matching-strategy=ant_path_matcher \ No newline at end of file diff --git a/sop-index/pom.xml b/sop-index/pom.xml index 47f8e36e..ed8b8d48 100644 --- a/sop-index/pom.xml +++ b/sop-index/pom.xml @@ -9,60 +9,14 @@ ../pom.xml sop-index - 5.0.0-SNAPSHOT + pom sop-index sop-index - - 1.8 - + + sop-index-api + sop-index-service + - - - org.springframework.boot - spring-boot-starter - - - - org.springframework.boot - spring-boot-starter-web - - - - org.apache.dubbo - dubbo-spring-boot-starter - - - - commons-codec - commons-codec - - - - org.hibernate - hibernate-validator - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.projectlombok - lombok - true - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - diff --git a/sop-index/sop-index-api/pom.xml b/sop-index/sop-index-api/pom.xml new file mode 100644 index 00000000..ac326907 --- /dev/null +++ b/sop-index/sop-index-api/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + com.gitee.sop + sop-index + 5.0.0-SNAPSHOT + + + sop-index-api + + + 8 + 8 + UTF-8 + + + + + org.projectlombok + lombok + true + + + + diff --git a/sop-index/sop-index-api/src/main/java/com/gitee/sop/index/api/ApiRegisterService.java b/sop-index/sop-index-api/src/main/java/com/gitee/sop/index/api/ApiRegisterService.java new file mode 100644 index 00000000..15f1a685 --- /dev/null +++ b/sop-index/sop-index-api/src/main/java/com/gitee/sop/index/api/ApiRegisterService.java @@ -0,0 +1,13 @@ +package com.gitee.sop.index.api; + +/** + * @author 六如 + */ +public interface ApiRegisterService { + /** + * 接口注册 + * + * @param registerDTO 接口信息 + */ + void register(RegisterDTO registerDTO); +} diff --git a/sop-index/sop-index-api/src/main/java/com/gitee/sop/index/api/RegisterDTO.java b/sop-index/sop-index-api/src/main/java/com/gitee/sop/index/api/RegisterDTO.java new file mode 100644 index 00000000..dbcb55d9 --- /dev/null +++ b/sop-index/sop-index-api/src/main/java/com/gitee/sop/index/api/RegisterDTO.java @@ -0,0 +1,35 @@ +package com.gitee.sop.index.api; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author 六如 + */ +@Data +public class RegisterDTO implements Serializable { + private static final long serialVersionUID = 2183251167679411550L; + + private String application; + + private String apiName; + + private String apiVersion; + + private String interfaceClassName; + + private String methodName; + + private String paramName; + + private String paramTypeName; + + private Integer isIgnoreValidate; + + private Integer isPermission; + + private Integer isNeedToken; + + +} diff --git a/sop-index/sop-index-service/pom.xml b/sop-index/sop-index-service/pom.xml new file mode 100644 index 00000000..ca2f91c0 --- /dev/null +++ b/sop-index/sop-index-service/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + com.gitee.sop + sop-index + 5.0.0-SNAPSHOT + + + sop-index-service + + + 8 + 8 + UTF-8 + + + + + com.gitee.sop + sop-index-api + 5.0.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-web + + + + org.apache.dubbo + dubbo-spring-boot-starter + + + + com.alibaba.boot + nacos-discovery-spring-boot-starter + 0.2.1 + + + + + commons-codec + commons-codec + + + org.apache.commons + commons-lang3 + + + + org.hibernate + hibernate-validator + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/sop-index/src/main/java/com/gitee/sop/index/SopIndexApplication.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/SopIndexApplication.java similarity index 79% rename from sop-index/src/main/java/com/gitee/sop/index/SopIndexApplication.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/SopIndexApplication.java index 07b6c2e3..b470841d 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/SopIndexApplication.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/SopIndexApplication.java @@ -1,9 +1,11 @@ package com.gitee.sop.index; +import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication +@EnableDubbo public class SopIndexApplication { public static void main(String[] args) { diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/common/ApiInfoDTO.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/common/ApiInfoDTO.java new file mode 100644 index 00000000..39eac51b --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/common/ApiInfoDTO.java @@ -0,0 +1,38 @@ +package com.gitee.sop.index.common; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author 六如 + */ +@Data +public class ApiInfoDTO implements Serializable { + private static final long serialVersionUID = 2183251167679411550L; + + private String application; + + private String apiName; + + private String apiVersion; + + private String interfaceClassName; + + private String methodName; + + private String paramName; + + private String paramTypeName; + + private Integer isIgnoreValidate; + + private Integer isPermission; + + private Integer isNeedToken; + + public String buildApiNameVersion() { + return apiName + apiVersion; + } + +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/common/ParamNames.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/common/ParamNames.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/common/ParamNames.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/common/ParamNames.java diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/common/SopConstants.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/common/SopConstants.java new file mode 100644 index 00000000..5aff57d8 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/common/SopConstants.java @@ -0,0 +1,64 @@ +package com.gitee.sop.index.common; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + * @author tanghc + */ +public class SopConstants { + + private SopConstants() {} + + public static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8; + public static final String UTF8 = "UTF-8"; + public static final String FORMAT_JSON = "json"; + public static final String DEFAULT_SIGN_METHOD = "md5"; + public static final String EMPTY_JSON = "{}"; + + public static final String METADATA_SERVER_CONTEXT_PATH = "server.servlet.context-path"; + + public static final String METADATA_SERVER_CONTEXT_PATH_COMPATIBILITY = "context-path"; + + /** + * 在拦截器中调用获取参数: + * String cachedBody = (String)exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_OBJECT_KEY); + */ + public static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject"; + + /** + * 在拦截器中调用获取参数: + * Map params = exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_FOR_MAP); + */ + public static final String CACHE_REQUEST_BODY_FOR_MAP = "cacheRequestBodyForMap"; + + public static final String CACHE_API_PARAM = "cacheApiParam"; + + public static final String CACHE_UPLOAD_REQUEST = "cacheUploadRequest"; + + public static final String X_SERVICE_ERROR_CODE = "x-service-error-code"; + + public static final String X_SERVICE_ERROR_MESSAGE = "x-service-error-message"; + + public static final String X_SERVICE_ERROR_RESPONSE = "x-service-error-response"; + + public static final int BIZ_ERROR_STATUS = 4000; + public static final int UNKNOWN_ERROR_STATUS = 5050; + + public static final String UNKNOWN_SERVICE= "_sop_unknown_service_"; + public static final String UNKNOWN_METHOD = "_sop_unknown_method_"; + public static final String UNKNOWN_VERSION = "_sop_unknown_version_"; + + public static final String METADATA_ENV_KEY = "env"; + public static final String METADATA_ENV_PRE_VALUE = "pre"; + public static final String METADATA_ENV_GRAY_VALUE = "gray"; + + public static final String CACHE_ROUTE_INTERCEPTOR_CONTEXT = "cacheRouteInterceptorContext"; + public static final String TARGET_SERVICE = "sop-target-service"; + public static final String RESTFUL_REQUEST = "sop-restful-request"; + + public static final String METADATA_KEY_TIME_STARTUP = "server.startup-time"; + + public static final String CACHE_ROUTE_INFO = "cacheRouteInfo"; + +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/config/ApiConfig.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/config/ApiConfig.java new file mode 100644 index 00000000..b6ed3d3c --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/config/ApiConfig.java @@ -0,0 +1,30 @@ +package com.gitee.sop.index.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @author 六如 + */ +@Configuration +@ConfigurationProperties(prefix = "api") +@Data +public class ApiConfig { + + /** + * 超时时间 + */ + private int timeoutSeconds = 60 * 5; + + /** + * 是否开启限流功能 + */ + private boolean openLimit = true; + + /** + * 显示返回sign + */ + private boolean showReturnSign = true; + +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/config/IndexConfig.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/config/IndexConfig.java new file mode 100644 index 00000000..0588ed9f --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/config/IndexConfig.java @@ -0,0 +1,34 @@ +package com.gitee.sop.index.config; + +import com.gitee.sop.index.service.manager.impl.LocalApiCacheManagerImpl; +import com.gitee.sop.index.service.manager.impl.LocalSecretManagerImpl; +import com.gitee.sop.index.service.manager.impl.RedisApiCacheManagerImpl; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author 六如 + */ +@Configuration +public class IndexConfig { + + @Bean + @ConditionalOnProperty(value = "manager.api-cache", havingValue = "local", matchIfMissing = true) + public LocalApiCacheManagerImpl localApiCacheManager() { + return new LocalApiCacheManagerImpl(); + } + + @Bean + @ConditionalOnProperty(value = "manager.api-cache", havingValue = "redis") + public RedisApiCacheManagerImpl redisApiCacheManager() { + return new RedisApiCacheManagerImpl(); + } + + @Bean + @ConditionalOnProperty(value = "manager.secret", havingValue = "local", matchIfMissing = true) + public LocalSecretManagerImpl localSecretManager() { + return new LocalSecretManagerImpl(); + } + +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/controller/IndexController.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/controller/IndexController.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/controller/IndexController.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/controller/IndexController.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/controller/param/ApiRequest.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/controller/param/ApiRequest.java similarity index 95% rename from sop-index/src/main/java/com/gitee/sop/index/controller/param/ApiRequest.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/controller/param/ApiRequest.java index b145c7f2..05ac2dc7 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/controller/param/ApiRequest.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/controller/param/ApiRequest.java @@ -1,5 +1,7 @@ package com.gitee.sop.index.controller.param; +import com.alibaba.fastjson2.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import org.hibernate.validator.constraints.Length; @@ -117,7 +119,9 @@ public class ApiRequest implements Serializable { @NotBlank(message = "biz_content不能为空") private String biz_content; - public String takeApiName() { + @JsonIgnore + @JSONField(serialize = false) + public String takeNameVersion() { return method + version; } } diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/controller/param/ApiResponse.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/controller/param/ApiResponse.java new file mode 100644 index 00000000..d43dc865 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/controller/param/ApiResponse.java @@ -0,0 +1,118 @@ +package com.gitee.sop.index.controller.param; + +import com.gitee.sop.index.exception.ApiException; +import com.gitee.sop.index.message.ErrorEnum; +import com.gitee.sop.index.message.ErrorMeta; +import com.gitee.sop.index.message.IError; +import lombok.Data; + +import java.util.Locale; + + +/** + * 默认的结果封装类. + *
+ *
+ * xml返回结果:
+ * 
+ *     50
+ *     Remote service error
+ *     isv.invalid-parameter
+ *     非法参数
+ * 
+ * 成功情况:
+ * 
+ *     0
+ *     成功消息
+ *     
+ *         ...返回内容
+ *     
+ * 
+ *
+ * json返回格式:
+ * {
+ *  "code":"50",
+ * 	"msg":"Remote service error",
+ * 	"sub_code":"isv.invalid-parameter",
+ * 	"sub_msg":"非法参数"
+ * }
+ * 成功情况:
+ * {
+ *  "code":"0",
+ * 	"msg":"成功消息内容。。。",
+ * 	"data":{
+ * 	    ...返回内容
+ *    }
+ * }
+ * 
+ *

+ * 字段说明: + * code:网关异常码
+ * msg:网关异常信息
+ * sub_code:业务异常码
+ * sub_msg:业务异常信息
+ * + * @author tanghc + */ +@Data +public class ApiResponse { + + public static final String SUCCESS_CODE = "0"; + public static final String SUCCESS_MSG = "success"; + /** + * 网关异常码,范围0~100 成功返回"0" + */ + private String code = SUCCESS_CODE; + + /** + * 网关异常信息 + */ + private String msg; + + /** + * 业务异常码 + */ + private String sub_code; + + /** + * 业务异常信息 + */ + private String sub_msg; + + /** + * 返回对象 + */ + private Object data; + + public static ApiResponse success(Object data) { + ApiResponse apiResponse = new ApiResponse(); + apiResponse.setCode(SUCCESS_CODE); + apiResponse.setMsg(SUCCESS_MSG); + apiResponse.setData(data); + return apiResponse; + } + + + public static ApiResponse error(ErrorEnum errorEnum) { + ApiResponse apiResponse = new ApiResponse(); + ErrorMeta errorMeta = errorEnum.getErrorMeta(); + IError error = errorMeta.getError(Locale.SIMPLIFIED_CHINESE); + apiResponse.setCode(error.getCode()); + apiResponse.setMsg(error.getMsg()); + apiResponse.setSub_code(error.getSub_code()); + apiResponse.setSub_msg(error.getSub_msg()); + return apiResponse; + } + + public static ApiResponse error(ErrorEnum errorEnum, String subMsg) { + ApiResponse apiResponse = new ApiResponse(); + ErrorMeta errorMeta = errorEnum.getErrorMeta(); + IError error = errorMeta.getError(Locale.SIMPLIFIED_CHINESE); + apiResponse.setCode(error.getCode()); + apiResponse.setMsg(error.getMsg()); + apiResponse.setSub_code(error.getSub_code()); + apiResponse.setSub_msg(subMsg); + return apiResponse; + } + +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/dubbo/ApiRegisterServiceImpl.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/dubbo/ApiRegisterServiceImpl.java new file mode 100644 index 00000000..835398cf --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/dubbo/ApiRegisterServiceImpl.java @@ -0,0 +1,29 @@ +package com.gitee.sop.index.dubbo; + +import com.gitee.sop.index.api.ApiRegisterService; +import com.gitee.sop.index.api.RegisterDTO; +import com.gitee.sop.index.common.ApiInfoDTO; +import com.gitee.sop.index.service.manager.ApiCacheManager; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author 六如 + */ +@Slf4j +@DubboService +public class ApiRegisterServiceImpl implements ApiRegisterService { + + @Autowired + private ApiCacheManager apiCache; + + @Override + public void register(RegisterDTO registerDTO) { + log.info("收到接口注册, registerDTO={}", registerDTO); + ApiInfoDTO apiInfoDTO = new ApiInfoDTO(); + BeanUtils.copyProperties(registerDTO, apiInfoDTO); + apiCache.save(apiInfoDTO); + } +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/exception/ApiException.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/exception/ApiException.java similarity index 83% rename from sop-index/src/main/java/com/gitee/sop/index/exception/ApiException.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/exception/ApiException.java index fd543e1d..87c2c4cf 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/exception/ApiException.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/exception/ApiException.java @@ -1,9 +1,9 @@ package com.gitee.sop.index.exception; - import com.gitee.sop.index.message.ErrorFactory; import com.gitee.sop.index.message.ErrorMeta; +import com.gitee.sop.index.message.IError; import java.util.Locale; @@ -11,8 +11,9 @@ import java.util.Locale; * @author tanghc */ public class ApiException extends RuntimeException { + private static final long serialVersionUID = 8278005515613227643L; - private transient Error error; + private transient IError error; private transient ErrorMeta errorMeta; private transient Object[] params; @@ -28,7 +29,7 @@ public class ApiException extends RuntimeException { this.params = params; } - public Error getError(Locale locale) { + public IError getError(Locale locale) { if (error == null) { error = ErrorFactory.getError(this.errorMeta, locale, params); } diff --git a/sop-index/src/main/java/com/gitee/sop/index/message/ErrorEnum.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorEnum.java similarity index 98% rename from sop-index/src/main/java/com/gitee/sop/index/message/ErrorEnum.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorEnum.java index b9ab6791..00b44861 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/message/ErrorEnum.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorEnum.java @@ -51,6 +51,8 @@ public enum ErrorEnum { /** 参数无效 */ ISV_INVALID_PARAMETER(Codes.CODE_INVALID, "isv.invalid-parameter"), + /** 参数不正确 */ + ISV_ERROR_PARAMETER(Codes.CODE_INVALID, "isv.error-parameter"), /** 文件上传失败 */ ISV_UPLOAD_FAIL(Codes.CODE_INVALID, "isv.upload-fail"), /** 文件扩展名无效 */ diff --git a/sop-index/src/main/java/com/gitee/sop/index/message/ErrorFactory.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorFactory.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/message/ErrorFactory.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorFactory.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/message/ErrorImpl.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorImpl.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/message/ErrorImpl.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorImpl.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/message/ErrorMeta.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorMeta.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/message/ErrorMeta.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/ErrorMeta.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/message/IError.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/IError.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/message/IError.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/message/IError.java diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/ApiService.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/ApiService.java new file mode 100644 index 00000000..272fa7b6 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/ApiService.java @@ -0,0 +1,25 @@ +package com.gitee.sop.index.service; + +import com.gitee.sop.index.common.ApiInfoDTO; +import com.gitee.sop.index.service.manager.ApiCacheManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author 六如 + */ +@Service +public class ApiService { + + @Autowired + private ApiCacheManager apiCacheManager; + + public ApiInfoDTO getApi(String apiName, String apiVersion) { + return apiCacheManager.getOrElse(apiName, apiVersion, () -> { + ApiInfoDTO record = new ApiInfoDTO(); + + return record; + }); + } + +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/GenericServiceInvoker.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/GenericServiceInvoker.java similarity index 82% rename from sop-index/src/main/java/com/gitee/sop/index/service/GenericServiceInvoker.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/GenericServiceInvoker.java index 85984d9b..73ac1647 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/GenericServiceInvoker.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/GenericServiceInvoker.java @@ -4,41 +4,38 @@ import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.rpc.service.GenericService; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; - -import javax.annotation.PostConstruct; +import org.springframework.stereotype.Service; /** * dubbo泛化调用 * * @author 六如 */ -public class GenericServiceInvoker { +@Service +public class GenericServiceInvoker implements InitializingBean { private ApplicationConfig applicationConfig; @Value("${nacos.host:localhost:8848}") private String nacosHost; - @Value("${nacos.group:DEFAULT}") - private String group; - @Value("${spring.application.name}") private String appName; @Value("${generic.timeout:5000}") private int timeout; - @PostConstruct - public void init() { - RegistryConfig registryConfig = buildRegistryConfig(nacosHost, group); + @Override + public void afterPropertiesSet() throws Exception { + RegistryConfig registryConfig = buildRegistryConfig(nacosHost); applicationConfig = new ApplicationConfig(); applicationConfig.setName(appName + "-generic"); applicationConfig.setRegistry(registryConfig); } - private RegistryConfig buildRegistryConfig(String nacosHost, String group) { + private RegistryConfig buildRegistryConfig(String nacosHost) { RegistryConfig config = new RegistryConfig(); - config.setGroup(group); config.setAddress("nacos://" + nacosHost); return config; } @@ -48,10 +45,7 @@ public class GenericServiceInvoker { reference.setGeneric("true"); reference.setApplication(applicationConfig); reference.setInterface(interfaceName); - reference.setGroup(group); reference.setTimeout(timeout); - reference.setSticky(false); - reference.setCheck(false); try { removeGenericSymbol(parameterTypes); GenericService genericService = reference.get(); @@ -61,6 +55,7 @@ public class GenericServiceInvoker { } } + /** * remove generic from parameterTypes */ diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/RouteService.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/RouteService.java new file mode 100644 index 00000000..8172f433 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/RouteService.java @@ -0,0 +1,122 @@ +package com.gitee.sop.index.service; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.gitee.sop.index.common.ApiInfoDTO; +import com.gitee.sop.index.controller.param.ApiRequest; +import com.gitee.sop.index.controller.param.ApiResponse; +import com.gitee.sop.index.message.ErrorEnum; +import com.gitee.sop.index.service.validate.Validator; +import com.gitee.sop.index.util.ClassUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.common.utils.ClassUtils; +import org.apache.dubbo.rpc.service.GenericException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 接口路由 + * + * @author 六如 + */ +@Service +@Slf4j +public class RouteService { + + private static final String CONSTRAINT_VIOLATION_EXCEPTION = "ConstraintViolationException"; + + @Autowired + private Validator validator; + + @Autowired + private GenericServiceInvoker genericServiceInvoker; + + @Autowired + private ApiService apiService; + + public ApiResponse route(ApiRequest apiRequest) { + // 校验 + validator.validate(apiRequest); + return doRoute(apiRequest); + } + + private ApiResponse doRoute(ApiRequest apiRequest) { + ApiInfoDTO apiInfo = apiService.getApi(apiRequest.getMethod(), apiRequest.getVersion()); + Object result = null; + Exception error = null; + + beforeRoute(apiRequest, apiInfo); + try { + result = genericServiceInvoker.invoke( + apiInfo.getInterfaceClassName(), + apiInfo.getMethodName(), + new String[]{apiInfo.getParamTypeName()}, + new Object[]{buildInvokeParam(apiRequest, apiInfo)} + ); + } catch (Exception e) { + error = e; + log.error("请求服务出错, apiRequest={}, apiInfo={}", apiInfo, apiInfo, e); + return buildApiResponse(e); + } finally { + afterRoute(result, apiRequest, error); + } + return ApiResponse.success(result); + } + + private ApiResponse buildApiResponse(Exception e) { + if (e instanceof GenericException) { + GenericException genericException = (GenericException) e; + String exceptionClass = genericException.getExceptionClass(); + if (exceptionClass.contains(CONSTRAINT_VIOLATION_EXCEPTION)) { + String exceptionMessage = genericException.getExceptionMessage(); + // 参数校验:Failed to validate service: com.gitee.sop.storyweb.open.StoryService, method: save, cause: [ConstraintViolationImpl{interpolatedMessage='故事名称必填', propertyPath=storyName, rootBeanClass=class com.gitee.sop.storyweb.open.req.StorySaveDTO, messageTemplate='故事名称必填'}] + Set msgs = findErrorMsg(exceptionMessage); + return ApiResponse.error(ErrorEnum.ISV_ERROR_PARAMETER, String.join(",", msgs)); + } + } + return ApiResponse.error(ErrorEnum.ISP_SERVICE_UNKNOWN_ERROR); + } + + private Set findErrorMsg(String text) { + Pattern pattern = Pattern.compile("'([^']*)'"); + Matcher matcher = pattern.matcher(text); + Set msgList = new LinkedHashSet<>(); + while (matcher.find()) { + msgList.add(matcher.group(1)); + } + return msgList; + } + + private Object buildInvokeParam(ApiRequest apiRequest, ApiInfoDTO apiInfo) { + if (ObjectUtils.isEmpty(apiInfo.getParamTypeName())) { + return null; + } + String bizContent = apiRequest.getBiz_content(); + JSONObject jsonObject = JSON.parseObject(bizContent); + if (ClassUtil.isPrimitive(apiInfo.getParamTypeName())) { + try { + return jsonObject.getObject(apiInfo.getParamName(), ClassUtils.forName(apiInfo.getParamTypeName())); + } catch (ClassNotFoundException e) { + log.error("找不到参数class, paramTypeName={}, apiRequest={}, apiInfo={}", + apiInfo.getParamTypeName(), apiRequest, apiInfo, e); + throw new RuntimeException(e); + } + } else { + return jsonObject; + } + } + + private void beforeRoute(ApiRequest apiRequest, ApiInfoDTO apiInfo) { + log.info("收到接口请求, apiRequest={}", apiRequest); + } + + private void afterRoute(Object result, ApiRequest apiRequest, Exception e) { + + } +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/ValidateService.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/ValidateService.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/ValidateService.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/ValidateService.java diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/ApiCacheManager.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/ApiCacheManager.java new file mode 100644 index 00000000..e085f0f5 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/ApiCacheManager.java @@ -0,0 +1,25 @@ +package com.gitee.sop.index.service.manager; + +import com.gitee.sop.index.common.ApiInfoDTO; + +import java.util.function.Supplier; + +/** + * @author 六如 + */ +public interface ApiCacheManager { + + void save(ApiInfoDTO apiInfoDTO); + + ApiInfoDTO get(String apiName, String apiVersion); + + default ApiInfoDTO getOrElse(String apiName, String apiVersion, Supplier supplier) { + ApiInfoDTO apiInfoDTO = get(apiName, apiVersion); + if (apiInfoDTO == null) { + apiInfoDTO = supplier.get(); + } + save(apiInfoDTO); + return apiInfoDTO; + } + +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/SecretManager.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/SecretManager.java new file mode 100644 index 00000000..e9d05036 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/SecretManager.java @@ -0,0 +1,19 @@ +package com.gitee.sop.index.service.manager; + +/** + * 秘钥管理 + * + * @author 六如 + */ +public interface SecretManager { + + /** + * 获取用户上传的公钥 + * + * @param appId appId + * @return 返回公钥内容 + */ + String getIsvPublicKey(String appId); + + +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiCacheManagerImpl.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiCacheManagerImpl.java new file mode 100644 index 00000000..3155641a --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/LocalApiCacheManagerImpl.java @@ -0,0 +1,27 @@ +package com.gitee.sop.index.service.manager.impl; + +import com.gitee.sop.index.common.ApiInfoDTO; +import com.gitee.sop.index.service.manager.ApiCacheManager; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 本地存储接口信息. + * @author 六如 + */ +public class LocalApiCacheManagerImpl implements ApiCacheManager { + + private static final Map CACHE = new ConcurrentHashMap<>(); + + @Override + public void save(ApiInfoDTO apiInfoDTO) { + String key = apiInfoDTO.buildApiNameVersion(); + CACHE.put(key, apiInfoDTO); + } + + @Override + public ApiInfoDTO get(String apiName, String apiVersion) { + return CACHE.get(apiName + apiVersion); + } +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/LocalSecretManagerImpl.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/LocalSecretManagerImpl.java new file mode 100644 index 00000000..78d7f7ed --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/LocalSecretManagerImpl.java @@ -0,0 +1,23 @@ +package com.gitee.sop.index.service.manager.impl; + +import com.gitee.sop.index.service.manager.SecretManager; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author 六如 + */ +public class LocalSecretManagerImpl implements SecretManager { + + static Map PUB_KEY_MGR = new HashMap<>(); + static { + PUB_KEY_MGR.put("2019032617262200001", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlyb9aUBaljQP/vjmBFe1mF8HsWSvyfC2NTlpT/V9E+sBxTr8TSkbzJCeeeOEm4LCaVXL0Qz63MZoT24v7AIXTuMdj4jyiM/WJ4tjrWAgnmohNOegfntTto16C3l234vXz4ryWZMR/7W+MXy5B92wPGQEJ0LKFwNEoLspDEWZ7RdE53VH7w6y6sIZUfK+YkXWSwehfKPKlx+lDw3zRJ3/yvMF+U+BAdW/MfECe1GuBnCFKnlMRh3UKczWyXWkL6ItOpYHHJi/jx85op5BWDje2pY9QowzfN94+0DB3T7UvZeweu3zlP6diwAJDzLaFQX8ULfWhY+wfKxIRgs9NoiSAQIDAQAB"); + } + + + @Override + public String getIsvPublicKey(String appId) { + return PUB_KEY_MGR.get(appId); + } +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiCacheManagerImpl.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiCacheManagerImpl.java new file mode 100644 index 00000000..ff72fcb1 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/manager/impl/RedisApiCacheManagerImpl.java @@ -0,0 +1,24 @@ +package com.gitee.sop.index.service.manager.impl; + +import com.gitee.sop.index.common.ApiInfoDTO; +import com.gitee.sop.index.service.manager.ApiCacheManager; + +/** + * redis存储接口信息 + * + * @author 六如 + */ +public class RedisApiCacheManagerImpl implements ApiCacheManager { + + + + @Override + public void save(ApiInfoDTO apiInfoDTO) { + + } + + @Override + public ApiInfoDTO get(String apiName, String apiVersion) { + return null; + } +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/AbstractSigner.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/AbstractSigner.java similarity index 68% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/AbstractSigner.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/AbstractSigner.java index 193a6f22..3cd165db 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/AbstractSigner.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/AbstractSigner.java @@ -1,9 +1,9 @@ package com.gitee.sop.index.service.validate; -import com.gitee.sop.gatewaycommon.message.ErrorEnum; -import com.gitee.sop.gatewaycommon.param.ApiParam; +import com.gitee.sop.index.controller.param.ApiRequest; +import com.gitee.sop.index.message.ErrorEnum; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.apache.dubbo.common.utils.StringUtils; /** * @author tanghc @@ -18,15 +18,15 @@ public abstract class AbstractSigner implements Signer { * @param secret 秘钥 * @return 返回服务端签名串 */ - protected abstract String buildServerSign(ApiParam params, String secret); + protected abstract String buildServerSign(ApiRequest params, String secret); @Override - public boolean checkSign(ApiParam apiParam, String secret) { - String clientSign = apiParam.fetchSignAndRemove(); + public boolean checkSign(ApiRequest apiRequest, String secret) { + String clientSign = apiRequest.getSign(); if (StringUtils.isBlank(clientSign)) { throw ErrorEnum.ISV_MISSING_SIGNATURE.getErrorMeta().getException(); } - String serverSign = buildServerSign(apiParam, secret); + String serverSign = buildServerSign(apiRequest, secret); return clientSign.equals(serverSign); } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiEncrypter.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/ApiEncrypter.java similarity index 91% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiEncrypter.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/ApiEncrypter.java index c590017f..4fd3c3fe 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiEncrypter.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/ApiEncrypter.java @@ -1,14 +1,14 @@ package com.gitee.sop.index.service.validate; +import com.gitee.sop.index.util.AESUtil; +import com.gitee.sop.index.util.RSANewUtil; +import com.gitee.sop.index.util.RSAUtil; import org.apache.commons.codec.digest.DigestUtils; -import com.gitee.sop.gatewaycommon.util.AESUtil; -import com.gitee.sop.gatewaycommon.util.RSANewUtil; -import com.gitee.sop.gatewaycommon.util.RSAUtil; /** * 负责各类加解密 - * @author tanghc * + * @author tanghc */ public class ApiEncrypter implements Encrypter { diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java similarity index 51% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java index c00d7cce..2842d268 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/ApiValidator.java @@ -1,17 +1,21 @@ package com.gitee.sop.index.service.validate; import com.gitee.sop.index.common.ParamNames; +import com.gitee.sop.index.config.ApiConfig; import com.gitee.sop.index.controller.param.ApiRequest; import com.gitee.sop.index.message.ErrorEnum; +import com.gitee.sop.index.service.manager.ApiCacheManager; +import com.gitee.sop.index.service.manager.SecretManager; +import com.gitee.sop.index.service.validate.alipay.AlipaySigner; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.apache.tomcat.util.http.fileupload.UploadContext; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.util.unit.DataSize; import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -25,6 +29,7 @@ import java.util.List; */ @Slf4j @Getter +@Service public class ApiValidator implements Validator { private static final int MILLISECOND_OF_ONE_SECOND = 1000; @@ -44,12 +49,23 @@ public class ApiValidator implements Validator { // @Autowired // private RouteConfigManager routeConfigManager; + private final Signer signer = new AlipaySigner(); + /** * 单个文件大小 */ @Value("${upload.max-file-size:${spring.servlet.multipart.max-file-size:10MB}}") private String maxFileSize; + @Autowired + private ApiConfig apiConfig; + + @Autowired + private ApiCacheManager apiCacheManager; + + @Autowired + private SecretManager secretManager; + @Override public void validate(ApiRequest param) { @@ -57,7 +73,7 @@ public class ApiValidator implements Validator { // TargetRoute targetRoute = checkEnable(param); // initFields(targetRoute, param); // ApiConfig apiConfig = ApiContext.getApiConfig(); - checkAppKey(param); +// checkAppKey(param); // if (apiConfig.isIgnoreValidate() // || BooleanUtils.toBoolean(targetRoute.getRouteDefinition().getIgnoreValidate())) { // if (log.isDebugEnabled()) { @@ -69,9 +85,9 @@ public class ApiValidator implements Validator { checkSign(param); checkTimeout(param); checkFormat(param); - checkUploadFile(param); - checkPermission(param); - checkToken(param); +// checkUploadFile(param); +// checkPermission(param); +// checkToken(param); } /** @@ -100,7 +116,7 @@ public class ApiValidator implements Validator { // if (version == null) { // throw ErrorEnum.ISV_MISSING_VERSION.getErrorMeta().getException(); // } -// String routeId = param.fetchNameVersion(); +// String routeId = param.takeApiName(); // // 检查路由是否存在 // TargetRoute targetRoute = RouteRepositoryContext.getTargetRoute(routeId); // if (targetRoute == null) { @@ -114,50 +130,50 @@ public class ApiValidator implements Validator { // return targetRoute; // } - private void initFields(TargetRoute targetRoute, ApiRequest apiParam) { - apiParam.setServiceId(targetRoute.getServiceDefinition().getServiceId()); - boolean mergeResult; - Boolean defaultSetting = ApiContext.getApiConfig().getMergeResult(); - if (defaultSetting != null) { - mergeResult = defaultSetting; - } else { - RouteDefinition routeDefinition = targetRoute.getRouteDefinition(); - mergeResult = routeDefinition == null || BooleanUtils.toBoolean(routeDefinition.getMergeResult()); - } - apiParam.setMergeResult(mergeResult); - } +// private void initFields(TargetRoute targetRoute, ApiRequest apiParam) { +// apiParam.setServiceId(targetRoute.getServiceDefinition().getServiceId()); +// boolean mergeResult; +// Boolean defaultSetting = ApiContext.getApiConfig().getMergeResult(); +// if (defaultSetting != null) { +// mergeResult = defaultSetting; +// } else { +// RouteDefinition routeDefinition = targetRoute.getRouteDefinition(); +// mergeResult = routeDefinition == null || BooleanUtils.toBoolean(routeDefinition.getMergeResult()); +// } +// apiParam.setMergeResult(mergeResult); +// } /** * 校验上传文件内容 * * @param param */ - protected void checkUploadFile(ApiRequest param) { - UploadContext uploadContext = param.fetchUploadContext(); - if (uploadContext != null) { - try { - List files = uploadContext.getAllFile(); - for (MultipartFile file : files) { - checkSingleFileSize(file); - checkFileMd5(param, file); - } - } catch (IOException e) { - log.error("验证上传文件MD5错误", e); - throw ErrorEnum.ISV_UPLOAD_FAIL.getErrorMeta().getException(); - } - } - } +// protected void checkUploadFile(ApiRequest param) { +// UploadContext uploadContext = param.fetchUploadContext(); +// if (uploadContext != null) { +// try { +// List files = uploadContext.getAllFile(); +// for (MultipartFile file : files) { +// checkSingleFileSize(file); +// checkFileMd5(param, file); +// } +// } catch (IOException e) { +// log.error("验证上传文件MD5错误", e); +// throw ErrorEnum.ISV_UPLOAD_FAIL.getErrorMeta().getException(); +// } +// } +// } - private void checkFileMd5(ApiRequest param, MultipartFile file) throws IOException { - // 客户端传来的文件md5 - String clientMd5 = param.getString(file.getName()); - if (clientMd5 != null) { - String fileMd5 = DigestUtils.md5Hex(file.getBytes()); - if (!clientMd5.equals(fileMd5)) { - throw ErrorEnum.ISV_UPLOAD_FAIL.getErrorMeta().getException(); - } - } - } +// private void checkFileMd5(ApiRequest param, MultipartFile file) throws IOException { +// // 客户端传来的文件md5 +// String clientMd5 = param.getString(file.getName()); +// if (clientMd5 != null) { +// String fileMd5 = DigestUtils.md5Hex(file.getBytes()); +// if (!clientMd5.equals(fileMd5)) { +// throw ErrorEnum.ISV_UPLOAD_FAIL.getErrorMeta().getException(); +// } +// } +// } /** * 校验单个文件大小 @@ -172,7 +188,7 @@ public class ApiValidator implements Validator { } protected void checkTimeout(ApiRequest param) { - int timeoutSeconds = ApiContext.getApiConfig().getTimeoutSeconds(); + int timeoutSeconds = apiConfig.getTimeoutSeconds(); // 如果设置为0,表示不校验 if (timeoutSeconds == 0) { return; @@ -180,7 +196,7 @@ public class ApiValidator implements Validator { if (timeoutSeconds < 0) { throw new IllegalArgumentException("服务端timeoutSeconds设置错误"); } - String requestTime = param.fetchTimestamp(); + String requestTime = param.getTimestamp(); try { Date requestDate = new SimpleDateFormat(ParamNames.TIMESTAMP_PATTERN).parse(requestTime); long requestMilliseconds = requestDate.getTime(); @@ -188,42 +204,42 @@ public class ApiValidator implements Validator { throw ErrorEnum.ISV_INVALID_TIMESTAMP.getErrorMeta().getException(); } } catch (ParseException e) { - throw ErrorEnum.ISV_INVALID_TIMESTAMP.getErrorMeta().getException(param.fetchNameVersion()); + throw ErrorEnum.ISV_INVALID_TIMESTAMP.getErrorMeta().getException(param.takeNameVersion()); } } - protected void checkAppKey(ApiRequest param) { - if (StringUtils.isEmpty(param.fetchAppKey())) { - throw ErrorEnum.ISV_MISSING_APP_ID.getErrorMeta().getException(); - } - Isv isv = isvManager.getIsv(param.fetchAppKey()); - // 没有用户 - if (isv == null) { - throw ErrorEnum.ISV_INVALID_APP_ID.getErrorMeta().getException(); - } - // 禁止访问 - if (isv.getStatus() == null || isv.getStatus() == STATUS_FORBIDDEN) { - throw ErrorEnum.ISV_ACCESS_FORBIDDEN.getErrorMeta().getException(); - } - } +// protected void checkAppKey(ApiRequest param) { +// if (StringUtils.isEmpty(param.fetchAppKey())) { +// throw ErrorEnum.ISV_MISSING_APP_ID.getErrorMeta().getException(); +// } +// Isv isv = isvManager.getIsv(param.fetchAppKey()); +// // 没有用户 +// if (isv == null) { +// throw ErrorEnum.ISV_INVALID_APP_ID.getErrorMeta().getException(); +// } +// // 禁止访问 +// if (isv.getStatus() == null || isv.getStatus() == STATUS_FORBIDDEN) { +// throw ErrorEnum.ISV_ACCESS_FORBIDDEN.getErrorMeta().getException(); +// } +// } protected void checkSign(ApiRequest param) { String clientSign = param.getSign(); try { if (StringUtils.isEmpty(clientSign)) { - throw ErrorEnum.ISV_MISSING_SIGNATURE.getErrorMeta().getException(param.takeApiName(), ParamNames.SIGN_NAME); + throw ErrorEnum.ISV_MISSING_SIGNATURE.getErrorMeta().getException(param.takeNameVersion(), ParamNames.SIGN_NAME); } - ApiConfig apiConfig = ApiContext.getApiConfig(); - // 根据appId获取秘钥 - Isv isvInfo = isvManager.getIsv(param.fetchAppKey()); - String secret = isvInfo.getSecretInfo(); - if (StringUtils.isEmpty(secret)) { - throw ErrorEnum.ISV_MISSING_SIGNATURE_CONFIG.getErrorMeta().getException(); - } - Signer signer = apiConfig.getSigner(); +// ApiConfig apiConfig = ApiContext.getApiConfig(); +// // 根据appId获取秘钥 +// Isv isvInfo = isvManager.getIsv(param.fetchAppKey()); +// String secret = isvInfo.getSecretInfo(); + String secret = secretManager.getIsvPublicKey(param.getApp_id()); +// if (StringUtils.isEmpty(secret)) { +// throw ErrorEnum.ISV_MISSING_SIGNATURE_CONFIG.getErrorMeta().getException(); +// } // 错误的sign if (!signer.checkSign(param, secret)) { - throw ErrorEnum.ISV_INVALID_SIGNATURE.getErrorMeta().getException(param.fetchNameVersion()); + throw ErrorEnum.ISV_INVALID_SIGNATURE.getErrorMeta().getException(param.takeNameVersion()); } } finally { // 校验过程中会移除sign,这里需要重新设置进去 @@ -233,11 +249,11 @@ public class ApiValidator implements Validator { protected void checkFormat(ApiRequest param) { - String format = param.fetchFormat(); + String format = param.getFormat(); boolean contains = FORMAT_LIST.contains(format.toLowerCase()); if (!contains) { - throw ErrorEnum.ISV_INVALID_FORMAT.getErrorMeta().getException(param.fetchNameVersion(), format); + throw ErrorEnum.ISV_INVALID_FORMAT.getErrorMeta().getException(param.takeNameVersion(), format); } } @@ -246,37 +262,37 @@ public class ApiValidator implements Validator { * * @param apiParam 参数 */ - protected void checkPermission(ApiRequest apiParam) { - String routeId = apiParam.fetchNameVersion(); - TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(routeId); - RouteDefinition routeDefinition = targetRoute.getRouteDefinition(); - boolean needCheckPermission = BooleanUtils.toBoolean(routeDefinition.getPermission()); - if (needCheckPermission) { - String appKey = apiParam.fetchAppKey(); - boolean hasPermission = isvRoutePermissionManager.hasPermission(appKey, routeId); - if (!hasPermission) { - throw ErrorEnum.ISV_ROUTE_NO_PERMISSIONS.getErrorMeta().getException(); - } - } - } +// protected void checkPermission(ApiRequest apiParam) { +// String routeId = apiParam.takeApiName(); +// TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(routeId); +// RouteDefinition routeDefinition = targetRoute.getRouteDefinition(); +// boolean needCheckPermission = BooleanUtils.toBoolean(routeDefinition.getPermission()); +// if (needCheckPermission) { +// String appKey = apiParam.fetchAppKey(); +// boolean hasPermission = isvRoutePermissionManager.hasPermission(appKey, routeId); +// if (!hasPermission) { +// throw ErrorEnum.ISV_ROUTE_NO_PERMISSIONS.getErrorMeta().getException(); +// } +// } +// } /** * 校验token * * @param apiParam 参数 */ - protected void checkToken(ApiRequest apiParam) { - String routeId = apiParam.fetchNameVersion(); - TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(routeId); - RouteDefinition routeDefinition = targetRoute.getRouteDefinition(); - boolean needToken = BooleanUtils.toBoolean(routeDefinition.getNeedToken()); - if (needToken) { - TokenValidator tokenValidator = ApiConfig.getInstance().getTokenValidator(); - boolean rightToken = tokenValidator.validateToken(apiParam); - if (!rightToken) { - throw ErrorEnum.AOP_INVALID_APP_AUTH_TOKEN.getErrorMeta().getException(); - } - } - } +// protected void checkToken(ApiRequest apiParam) { +// String routeId = apiParam.takeApiName(); +// TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(routeId); +// RouteDefinition routeDefinition = targetRoute.getRouteDefinition(); +// boolean needToken = BooleanUtils.toBoolean(routeDefinition.getNeedToken()); +// if (needToken) { +// TokenValidator tokenValidator = ApiConfig.getInstance().getTokenValidator(); +// boolean rightToken = tokenValidator.validateToken(apiParam); +// if (!rightToken) { +// throw ErrorEnum.AOP_INVALID_APP_AUTH_TOKEN.getErrorMeta().getException(); +// } +// } +// } } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/Encrypter.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/Encrypter.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/Encrypter.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/Encrypter.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/SignConfig.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/SignConfig.java similarity index 87% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/SignConfig.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/SignConfig.java index ab8703e2..09d0f812 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/SignConfig.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/SignConfig.java @@ -1,6 +1,7 @@ package com.gitee.sop.index.service.validate; -import com.gitee.sop.gatewaycommon.bean.SopConstants; + +import com.gitee.sop.index.common.SopConstants; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -9,7 +10,8 @@ import java.net.URLEncoder; * @author tanghc */ public class SignConfig { - private static volatile Wrapper wrapper = new Wrapper() {}; + private static volatile Wrapper wrapper = new Wrapper() { + }; public static void enableUrlencodeMode() { wrapper = new Wrapper() { diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/SignEncipher.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/SignEncipher.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/SignEncipher.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/SignEncipher.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/SignEncipherMD5.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/SignEncipherMD5.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/SignEncipherMD5.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/SignEncipherMD5.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/Signer.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/Signer.java similarity index 67% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/Signer.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/Signer.java index 0f926da0..06f95192 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/Signer.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/Signer.java @@ -2,8 +2,6 @@ package com.gitee.sop.index.service.validate; import com.gitee.sop.index.controller.param.ApiRequest; -import javax.servlet.http.HttpServletRequest; - /** * 负责签名校验 * @author tanghc @@ -13,10 +11,10 @@ public interface Signer { /** * 签名校验 - * @param apiParam 参数 + * @param apiRequest 参数 * @param secret 秘钥 * @return true签名正确 */ - boolean checkSign(ApiRequest apiParam, String secret); + boolean checkSign(ApiRequest apiRequest, String secret); } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/TokenValidator.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/TokenValidator.java similarity index 55% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/TokenValidator.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/TokenValidator.java index 14186443..8a7d00a6 100644 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/TokenValidator.java +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/TokenValidator.java @@ -1,11 +1,12 @@ package com.gitee.sop.index.service.validate; -import com.gitee.sop.gatewaycommon.param.ApiParam; + +import com.gitee.sop.index.controller.param.ApiRequest; /** * @author tanghc */ @FunctionalInterface public interface TokenValidator { - boolean validateToken(ApiParam apiParam); + boolean validateToken(ApiRequest apiRequest); } diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/Validator.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/Validator.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/Validator.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/Validator.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipayConstants.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipayConstants.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipayConstants.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipayConstants.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySignature.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySignature.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySignature.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySignature.java diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySigner.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySigner.java new file mode 100644 index 00000000..ab44e400 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySigner.java @@ -0,0 +1,76 @@ +package com.gitee.sop.index.service.validate.alipay; + + +import com.gitee.sop.index.common.ParamNames; +import com.gitee.sop.index.controller.param.ApiRequest; +import com.gitee.sop.index.message.ErrorEnum; +import com.gitee.sop.index.service.validate.Signer; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.Map; + +/** + * 支付宝签名验证实现。 + * + * @author tanghc + * @see 支付宝签名 + */ +@Slf4j +public class AlipaySigner implements Signer { + + @Override + public boolean checkSign(ApiRequest apiRequest, String secret) { + // 服务端存的是公钥 + String publicKey = secret; + String charset = apiRequest.getCharset(); + String signType = apiRequest.getSign_type(); + if (signType == null) { + throw ErrorEnum.ISV_DECRYPTION_ERROR_MISSING_ENCRYPT_TYPE.getErrorMeta().getException(); + } + if (charset == null) { + throw ErrorEnum.ISV_INVALID_CHARSET.getErrorMeta().getException(); + } + Map params = buildParams(apiRequest); + try { + return AlipaySignature.rsaCheckV2(params, publicKey, charset, signType); + } catch (Exception e) { + log.error("RSA2解密异常, params={}", params, e); + return false; + } + } + + private static Map buildParams(ApiRequest apiRequest) { + Map params = new SkipNullHashMap(20); + params.put(ParamNames.APP_KEY_NAME, apiRequest.getApp_id()); + params.put(ParamNames.API_NAME, apiRequest.getMethod()); + params.put(ParamNames.FORMAT_NAME, apiRequest.getFormat()); + params.put(ParamNames.CHARSET_NAME, apiRequest.getCharset()); + params.put(ParamNames.SIGN_TYPE_NAME, apiRequest.getSign_type()); + params.put(ParamNames.SIGN_NAME, apiRequest.getSign()); + params.put(ParamNames.TIMESTAMP_NAME, apiRequest.getTimestamp()); + params.put(ParamNames.VERSION_NAME, apiRequest.getVersion()); + params.put(ParamNames.NOTIFY_URL_NAME, apiRequest.getNotify_url()); + params.put(ParamNames.APP_AUTH_TOKEN_NAME, apiRequest.getApp_auth_token()); + params.put(ParamNames.BIZ_CONTENT_NAME, apiRequest.getBiz_content()); + return params; + } + + static class SkipNullHashMap extends HashMap { + private static final long serialVersionUID = -5660619374444097587L; + + public SkipNullHashMap(int initialCapacity) { + super(initialCapacity); + } + + @Override + public String put(String key, String value) { + if (value == null) { + return null; + } + return super.put(key, value); + } + } + + +} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/StreamUtil.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/StreamUtil.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/StreamUtil.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/StreamUtil.java diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/StringUtils.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/StringUtils.java similarity index 100% rename from sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/StringUtils.java rename to sop-index/sop-index-service/src/main/java/com/gitee/sop/index/service/validate/alipay/StringUtils.java diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/AESUtil.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/AESUtil.java new file mode 100644 index 00000000..fafa79b4 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/AESUtil.java @@ -0,0 +1,146 @@ +package com.gitee.sop.index.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Hex; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +/** + * AES-128 ECB加密.
+ * + *

+ * 字符集:UTF-8
+ * 算法模式:ECB
+ * 数据块:128位
+ * 补码方式:PKCS5Padding
+ * 加密结果编码方式:Base64
+ * 
+ * + * @author tanghc + * + */ +public class AESUtil { + private static final String UTF8 = "UTF-8"; + private static final String ALGORITHM = "AES"; + /** 默认的加密算法 */ + private static final String ALGORITHM_CIPHER = "AES/ECB/PKCS5Padding"; + + private static final int LIMIT_LEN = 16; + + /** + * 生成一个SecretKey + * @param password 长度必须小于等于16 + * @return 返回SecretKey + */ + public static SecretKey getSecretKey(String password) { + byte[] passwordData = password.getBytes(); + if(passwordData.length > LIMIT_LEN) { + throw new IllegalArgumentException("password 长度必须小于等于16"); + } + // 创建一个空的16位字节数组(默认值为0),16byte(128bit) + byte[] keyData = new byte[16]; + System.arraycopy(passwordData, 0, keyData, 0, passwordData.length); + + return new SecretKeySpec(keyData, ALGORITHM); + } + + /** + * 加密 + * @param data 待加密数据 + * @param password 密码 + * @return 返回加密成功后数据 + * @throws Exception + */ + public static byte[] encrypt(byte[] data, String password) throws Exception { + SecretKey secretKey = getSecretKey(password); + // Ciphr完成加密或解密工作类 + Cipher cipher = Cipher.getInstance(ALGORITHM_CIPHER); + // 对Cipher初始化,解密模式 + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + // 加密data + return cipher.doFinal(data); + } + + /** + * 解密 + * @param data 待解密数据 + * @param password 密码 + * @return 返回解密后的数据 + * @throws Exception + */ + public static byte[] decrypt(byte[] data, String password) throws Exception { + SecretKey secretKey = getSecretKey(password); + // Cipher完成加密或解密工作类 + Cipher cipher = Cipher.getInstance(ALGORITHM_CIPHER); + // 对Cipher初始化,解密模式 + cipher.init(Cipher.DECRYPT_MODE, secretKey); + // 解密data + return cipher.doFinal(data); + } + + /** + * 文本加密 + * @param content 明文 + * @param password 密码 + * @return 返回base64内容 + * @throws Exception + */ + public static String encryptToBase64String(String content, String password) throws Exception { + byte[] data = content.getBytes(UTF8); + byte[] result = encrypt(data, password); + return Base64.encodeBase64String(result); + } + + /** + * 文本解密 + * @param base64String 待解密文本 + * @param password 密码 + * @return 返回明文 + * @throws Exception + */ + public static String decryptFromBase64String(String base64String, String password) throws Exception { + byte[] data = Base64.decodeBase64(base64String); + byte[] contentData = decrypt(data, password); + return new String(contentData, UTF8); + } + + /** + * 文本加密 + * @param content 明文 + * @param password 密码 + * @return 返回16进制内容 + * @throws Exception + */ + public static String encryptToHex(String content, String password) throws Exception { + byte[] data = content.getBytes(UTF8); + byte[] result = encrypt(data, password); + return Hex.encodeHexString(result); + } + + /** + * 文本解密 + * @param hex 待解密文本 + * @param password 密码 + * @return 返回明文 + * @throws Exception + */ + public static String decryptFromHex(String hex, String password) throws Exception { + byte[] data = Hex.decodeHex(hex); + byte[] contentData = decrypt(data, password); + return new String(contentData,UTF8); + } + + /*public static void main(String[] args) throws Exception { + String content = "我爱你"; + String password = "1234567890123456"; + System.out.println("password:" + password); + + String ret2 = encryptToBase64String(content, password); + System.out.println("密文:" + ret2); + String content3 = decryptFromBase64String(ret2, password); + System.out.println(content.equals(content3)); + }*/ + +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/ClassUtil.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/ClassUtil.java new file mode 100644 index 00000000..1838f40c --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/ClassUtil.java @@ -0,0 +1,64 @@ +package com.gitee.sop.index.util; + +import java.util.Objects; + + +/** + * + */ +public class ClassUtil { + + public static final String PREFIX_JAVA_LANG = "java.lang."; + + /** + * Check if it is the basic data type of json data + * + * @param type0 java class name + * @return boolean + */ + public static boolean isPrimitive(String type0) { + if (Objects.isNull(type0)) { + return true; + } + String type = type0.startsWith(PREFIX_JAVA_LANG) ? type0.substring(type0.lastIndexOf(".") + 1) : type0; + type = type.toLowerCase(); + switch (type) { + case "string": + case "integer": + case "int": + case "object": + case "void": + case "long": + case "double": + case "float": + case "short": + case "bigdecimal": + case "char": + case "character": + case "number": + case "boolean": + case "byte": + case "uuid": + case "biginteger": + case "java.sql.timestamp": + case "java.util.date": + case "java.time.localdatetime": + case "java.time.localtime": + case "localtime": + case "date": + case "localdatetime": + case "localdate": + case "zoneddatetime": + case "java.time.localdate": + case "java.time.zoneddatetime": + case "java.math.bigdecimal": + case "java.math.biginteger": + case "java.util.uuid": + case "java.io.serializable": + return true; + default: + return false; + } + } + +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/KeyStore.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/KeyStore.java new file mode 100644 index 00000000..42a2f7c9 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/KeyStore.java @@ -0,0 +1,25 @@ +package com.gitee.sop.index.util; + +/** + * @author tanghc + */ +public class KeyStore { + private String publicKey; + private String privateKey; + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RSANewUtil.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RSANewUtil.java new file mode 100644 index 00000000..e31d0d1e --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RSANewUtil.java @@ -0,0 +1,208 @@ +package com.gitee.sop.index.util; + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * RSA加解密工具
+ * @author tanghc + */ +public class RSANewUtil { + public static final String RSA_ALGORITHM = "RSA"; + public static final String UTF8 = "UTF-8"; + + /** + * 创建公钥私钥 + * + * @return 返回公私钥对 + * @throws Exception + */ + public static KeyStore createKeys() throws Exception { + KeyPairGenerator keyPairGeno = KeyPairGenerator.getInstance(RSA_ALGORITHM); + keyPairGeno.initialize(1024); + KeyPair keyPair = keyPairGeno.generateKeyPair(); + + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + + KeyStore keyStore = new KeyStore(); + keyStore.setPublicKey(Base64.encodeBase64String(publicKey.getEncoded())); + keyStore.setPrivateKey(Base64.encodeBase64String(privateKey.getEncoded())); + return keyStore; + } + + /** + * 获取公钥对象 + * + * @param pubKeyData 公钥数据 + * @return 公钥对象 + * @throws Exception + */ + public static RSAPublicKey getPublicKey(byte[] pubKeyData) throws Exception { + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKeyData); + KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); + return (RSAPublicKey) keyFactory.generatePublic(keySpec); + } + + /** + * 获取公钥对象 + * + * @param pubKey + * 公钥 + * @return 返回公钥对象 + * @throws Exception + */ + public static RSAPublicKey getPublicKey(String pubKey) throws Exception { + return getPublicKey(Base64.decodeBase64(pubKey)); + + } + + /** + * 获取私钥对象 + * + * @param priKey + * 私钥 + * @return 返回私钥对象 + * @throws Exception + */ + public static RSAPrivateKey getPrivateKey(String priKey) throws Exception { + return getPrivateKey(Base64.decodeBase64(priKey)); + } + + /** + * 通过私钥byte[]将公钥还原,适用于RSA算法 + * + * @param keyBytes 私钥数据 + * @return 返回公钥对象 + * @throws Exception + */ + public static RSAPrivateKey getPrivateKey(byte[] keyBytes) throws Exception { + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); + return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); + + } + + public static String encryptByPublicKey(String data, String publicKey) throws Exception { + return encryptByPublicKey(data, getPublicKey(publicKey)); + } + + /** + * 公钥加密 + * + * @param data 内容 + * @param publicKey 公钥 + * @return 返回密文 + * @throws Exception + */ + public static String encryptByPublicKey(String data, RSAPublicKey publicKey) throws Exception { + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] bytes = cipher.doFinal(data.getBytes(UTF8)); + return Base64.encodeBase64String(bytes); + } + + public static String decryptByPublicKey(String data, String rsaPublicKey) throws Exception { + return decryptByPublicKey(data, getPublicKey(rsaPublicKey)); + } + + /** + * 公钥解密 + * + * @param data 待解密内容 + * @param rsaPublicKey 公钥 + * @return 返回明文 + * @throws Exception + */ + public static String decryptByPublicKey(String data, RSAPublicKey rsaPublicKey) throws Exception { + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, rsaPublicKey); + byte[] inputData = Base64.decodeBase64(data); + byte[] bytes = cipher.doFinal(inputData); + return new String(bytes, UTF8); + } + + public static String encryptByPrivateKey(String data, String privateKey) throws Exception { + return encryptByPrivateKey(data, getPrivateKey(privateKey)); + } + + /** + * 私钥加密 + * + * @param data 内容 + * @param privateKey 私钥 + * @return 返回密文 + * @throws Exception + */ + public static String encryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception { + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + byte[] bytes = cipher.doFinal(data.getBytes(UTF8)); + return Base64.encodeBase64String(bytes); + } + + public static String decryptByPrivateKey(String data, String privateKey) throws Exception { + return decryptByPrivateKey(data, getPrivateKey(privateKey)); + } + + /** + * 私钥解密 + * + * @param data 待解密内容 + * @param privateKey 私钥 + * @return 返回明文 + * @throws Exception + */ + public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception { + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] inputData = Base64.decodeBase64(data); + byte[] bytes = cipher.doFinal(inputData); + return new String(bytes, UTF8); + } + + + /* + pubKey: +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCG/iIZZzb16PxKqslkDMYa4tVFb3IVPBpLj4BgHQmDfe843sG4gkJIPXCm7+t6QxIbfDfynBpqZJLvu0c6E7TqlCtynBIlRFOBZrQVNEFkaanR2Kln3vd3CIidR571UstOC32XDyqAQNlvjD19zeIDVfmLa0Q+Or0zaxY99QwBHwIDAQAB +priKey: +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIb+IhlnNvXo/EqqyWQMxhri1UVvchU8GkuPgGAdCYN97zjewbiCQkg9cKbv63pDEht8N/KcGmpkku+7RzoTtOqUK3KcEiVEU4FmtBU0QWRpqdHYqWfe93cIiJ1HnvVSy04LfZcPKoBA2W+MPX3N4gNV+YtrRD46vTNrFj31DAEfAgMBAAECgYBiNPQdwwcq86rHr2QAE4L0AF3ju+YlKKqAmg9s3PMU5ENq/jO0xZ7u6zPPXu/S7IR51m7lY0ecazqyiW6SA9AzYH7ImWWkZ4stZ03beTB2US3cSeJIkugoexoN5fQRAGZiZezTLs91CeJivESOZyDKnnQdgJ49mveBV5OvievD8QJBAMztpqiWWavdR4tqQ+plat+rwYoXqejsK3Hyfg0pVJqEdazve2sr74rla7yI9P47ZAh1sklCv0CO//ctICv366UCQQCoop3T0FeZtbKJG+fHzZvpAe63tXpdhLMaQvTBuXLG8vi78Wyfhg5r7HOWR0Z1V7nzF1gzMywL53Pmkq9tB65zAkAiHu/A4kfL9ewTqn3kaT6CP3baJ1aDEc+qCVYzms4bbDKruLQ0A/y+g7SMj8E7E2h0gCRPTm3JsgWsgjb5Gy6BAkAA8mjQd6sGQe7utilnBdCKTmh4v5wgSk53J0kYjWIHm/WpmIFzo90Q3hMIFP5gSk3Q/6CPKQpmRrZv5QL3KcPhAkEAuMoQbij/7hyLlIxRHZs2SMXxfHPiZgDc6rVi1KNxeq8HXTlERi7Npc2Uz5TeWN4JwBBx9uA50zowk9iS05nclQ== +用公钥加密mi : c3B0jtMdvkqrgaPxHZCK2cXMUQC2QzLud2ouLMNx0nBAj9k2/ytOuVJViTGe/DozB/ky5jvl4spD9Ey6aTMrwLHfQVhn0gRJ+wHcmx/51dXQDIgsldt6bf7YpdPdnghBjQz2+P5RhqSkeFDbTZKkl2BNaLE78a/OyWWeCGwN+4s= +true +用私钥加密mi2 : QU5vDnQ1ukj8GsauokFlgcB/g61U882tj82wHGrrqHEnvaga+4cXjML9RhjpZtKqwDGZTCujsmpynDk4qek6IGOQ/oxdWLwV4ZNjfa/oqA8OFDothVUT8wpqCu9kOYHrTdGybmXD0dB2Iy1/AMQTAgPNNXXiRXdvsz9xWYTV6z8= +true + */ + /*public static void main(String[] args) throws Exception { + KeyStore keys = createKeys(); + String pubKey = keys.getPublicKey(); + System.out.println("pubKey:"); + System.out.println(pubKey); + String priKey = keys.getPrivateKey(); + System.out.println("priKey:"); + System.out.println(priKey); + + String ming = "1234567890123456"; + // 用公钥加密 + String mi = encryptByPublicKey(ming, pubKey); + System.out.println("用公钥加密mi : " + mi); + // 用私钥解密 + System.out.println(ming.equals(decryptByPrivateKey(mi, priKey))); + + // 用私钥加密 + String mi2 = encryptByPrivateKey(ming, priKey); + + System.out.println("用私钥加密mi2 : " + mi2); + // 用公钥解密 + String ming2 = decryptByPublicKey(mi2, pubKey); + System.out.println(ming.equals(ming2)); + }*/ + +} diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RSAUtil.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RSAUtil.java new file mode 100644 index 00000000..b77ae897 --- /dev/null +++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RSAUtil.java @@ -0,0 +1,312 @@ +package com.gitee.sop.index.util; + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * RSA加解密工具
+ * @author tanghc + */ +public class RSAUtil { + public static String RSA_ALGORITHM = "RSA"; + + /** + * 创建公钥私钥 + * + * @return 返回公私钥对 + * @throws Exception + */ + public static KeyStore createKeys() throws Exception { + KeyPairGenerator keyPairGeno = KeyPairGenerator.getInstance(RSA_ALGORITHM); + keyPairGeno.initialize(1024); + KeyPair keyPair = keyPairGeno.generateKeyPair(); + + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); + + KeyStore keyStore = new KeyStore(); + keyStore.setPublicKey(Base64.encodeBase64String(publicKey.getEncoded())); + keyStore.setPrivateKey(Base64.encodeBase64String(privateKey.getEncoded())); + return keyStore; + } + + /** + * 获取公钥对象 + * + * @param pubKeyData 公钥 + * @return 返回公钥对象 + * @throws Exception + */ + public static RSAPublicKey getPublicKey(byte[] pubKeyData) throws Exception { + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubKeyData); + KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); + return (RSAPublicKey) keyFactory.generatePublic(keySpec); + } + + /** + * 获取公钥对象 + * + * @param pubKey + * 公钥 + * @return 返回私钥对象 + * @throws Exception + */ + public static RSAPublicKey getPublicKey(String pubKey) throws Exception { + return getPublicKey(Base64.decodeBase64(pubKey)); + + } + + /** + * 获取私钥对象 + * + * @param priKey + * 私钥 + * @return 私钥对象 + * @throws Exception + */ + public static RSAPrivateKey getPrivateKey(String priKey) throws Exception { + return getPrivateKey(Base64.decodeBase64(priKey)); + } + + /** + * 通过私钥byte[]将公钥还原,适用于RSA算法 + * + * @param keyBytes + * @return 返回私钥 + * @throws Exception + */ + public static RSAPrivateKey getPrivateKey(byte[] keyBytes) throws Exception { + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); + return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); + + } + + /** + * 公钥加密 + * + * @param data 待加密内容 + * @param publicKey 公钥 + * @return 返回密文 + * @throws Exception + */ + public static String encryptByPublicKey(String data, RSAPublicKey publicKey) throws Exception { + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + // 模长 + int key_len = publicKey.getModulus().bitLength() / 8; + // 加密数据长度 <= 模长-11 + String[] datas = splitString(data, key_len - 11); + String mi = ""; + // 如果明文长度大于模长-11则要分组加密 + for (String s : datas) { + mi += bcd2Str(cipher.doFinal(s.getBytes())); + } + return mi; + } + public static String encryptByPrivateKey(String data, String privateKey) throws Exception { + return encryptByPrivateKey(data, getPrivateKey(privateKey)); + } + + /** + * 私钥加密 + * + * @param data 待加密数据 + * @param privateKey 私钥 + * @return 返回密文 + * @throws Exception + */ + public static String encryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception { + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + // 模长 + int key_len = privateKey.getModulus().bitLength() / 8; + // 加密数据长度 <= 模长-11 + String[] datas = splitString(data, key_len - 11); + String mi = ""; + // 如果明文长度大于模长-11则要分组加密 + for (String s : datas) { + mi += bcd2Str(cipher.doFinal(s.getBytes())); + } + return mi; + } + + public static String decryptByPrivateKey(String data, String privateKey) throws Exception { + return decryptByPrivateKey(data, getPrivateKey(privateKey)); + } + + /** + * 私钥解密 + * + * @param data 待解密内容 + * @param privateKey 私钥 + * @return 返回明文 + * @throws Exception + */ + public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception { + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + // 模长 + int key_len = privateKey.getModulus().bitLength() / 8; + byte[] bytes = data.getBytes(); + byte[] bcd = ASCII_To_BCD(bytes, bytes.length); + // 如果密文长度大于模长则要分组解密 + String ming = ""; + byte[][] arrays = splitArray(bcd, key_len); + for (byte[] arr : arrays) { + ming += new String(cipher.doFinal(arr)); + } + return ming; + } + + /** + * 公钥解密 + * + * @param data 待解密内容 + * @param rsaPublicKey 公钥 + * @return 返回明文 + * @throws Exception + */ + public static String decryptByPublicKey(String data, RSAPublicKey rsaPublicKey) throws Exception { + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, rsaPublicKey); + // 模长 + int key_len = rsaPublicKey.getModulus().bitLength() / 8; + byte[] bytes = data.getBytes(); + byte[] bcd = ASCII_To_BCD(bytes, bytes.length); + // 如果密文长度大于模长则要分组解密 + String ming = ""; + byte[][] arrays = splitArray(bcd, key_len); + for (byte[] arr : arrays) { + ming += new String(cipher.doFinal(arr)); + } + return ming; + } + + + /** + * ASCII码转BCD码 + * + */ + public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) { + byte[] bcd = new byte[asc_len / 2]; + int j = 0; + for (int i = 0; i < (asc_len + 1) / 2; i++) { + bcd[i] = asc_to_bcd(ascii[j++]); + bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++]) & 0xff) + (bcd[i] << 4)); + } + return bcd; + } + + public static byte asc_to_bcd(byte asc) { + byte bcd; + + if ((asc >= '0') && (asc <= '9')) { + bcd = (byte) (asc - '0'); + } else if ((asc >= 'A') && (asc <= 'F')) { + bcd = (byte) (asc - 'A' + 10); + } else if ((asc >= 'a') && (asc <= 'f')) { + bcd = (byte) (asc - 'a' + 10); + } else { + bcd = (byte) (asc - 48); + } + return bcd; + } + + /** + * BCD转字符串 + */ + public static String bcd2Str(byte[] bytes) { + char[] temp = new char[bytes.length * 2]; + char val; + + for (int i = 0; i < bytes.length; i++) { + val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f); + temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0'); + + val = (char) (bytes[i] & 0x0f); + temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0'); + } + return new String(temp); + } + + /** + * 拆分字符串 + */ + public static String[] splitString(String string, int len) { + int x = string.length() / len; + int y = string.length() % len; + int z = 0; + if (y != 0) { + z = 1; + } + String[] strings = new String[x + z]; + String str = ""; + for (int i = 0; i < x + z; i++) { + if (i == x + z - 1 && y != 0) { + str = string.substring(i * len, i * len + y); + } else { + str = string.substring(i * len, i * len + len); + } + strings[i] = str; + } + return strings; + } + + /** + * 拆分数组 + */ + public static byte[][] splitArray(byte[] data, int len) { + int x = data.length / len; + int y = data.length % len; + int z = 0; + if (y != 0) { + z = 1; + } + byte[][] arrays = new byte[x + z][]; + byte[] arr; + for (int i = 0; i < x + z; i++) { + arr = new byte[len]; + if (i == x + z - 1 && y != 0) { + System.arraycopy(data, i * len, arr, 0, y); + } else { + System.arraycopy(data, i * len, arr, 0, len); + } + arrays[i] = arr; + } + return arrays; + } + + /*public static void main(String[] args) throws Exception { + KeyStore keys = createKeys(); + String pubKey = keys.getPublicKey(); + System.out.println("pubKey:"); + System.out.println(pubKey); + String priKey = keys.getPrivateKey(); + System.out.println("priKey:"); + System.out.println(priKey); + + String ming = "6460201d23954f8e90cf79b818844ca0"; + // 用公钥加密 + String mi = encryptByPublicKey(ming, getPublicKey(pubKey)); + System.out.println("mi : " + mi); + // 用私钥解密 + System.out.println("ming : " + decryptByPrivateKey(mi, getPrivateKey(priKey))); + + // 用私钥加密 + String mi2 = encryptByPrivateKey(ming, getPrivateKey(priKey)); + + System.out.println("mi2 : " + mi2); + // 用公钥解密 + System.out.println("ming2 : " + decryptByPublicKey(mi2, getPublicKey(pubKey))); + }*/ + +} diff --git a/sop-index/sop-index-service/src/main/resources/application-dev.properties b/sop-index/sop-index-service/src/main/resources/application-dev.properties new file mode 100644 index 00000000..171e376d --- /dev/null +++ b/sop-index/sop-index-service/src/main/resources/application-dev.properties @@ -0,0 +1,5 @@ +nacos.host=127.0.0.1:8848 + +dubbo.protocol.name=dubbo +dubbo.protocol.port=-1 +dubbo.registry.address=nacos://${nacos.host} diff --git a/sop-index/sop-index-service/src/main/resources/application.properties b/sop-index/sop-index-service/src/main/resources/application.properties new file mode 100644 index 00000000..b92b78f3 --- /dev/null +++ b/sop-index/sop-index-service/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.profiles.active=dev +spring.application.name=sop-index +server.port=8081 diff --git a/sop-index/sop-index-service/src/main/resources/i18n/open/error_en.properties b/sop-index/sop-index-service/src/main/resources/i18n/open/error_en.properties new file mode 100644 index 00000000..2a928dc5 --- /dev/null +++ b/sop-index/sop-index-service/src/main/resources/i18n/open/error_en.properties @@ -0,0 +1,65 @@ +# \u7F51\u5173\u9519\u8BEF\u914D\u7F6E + +open.error_10000=Success + +# \u683C\u5F0F\uFF1A\u524D\u7F00 + \u7F51\u5173\u9519\u8BEF\u7801 + "_"+ \u5B50\u9519\u8BEF\u7801 +# open.error_\uFF08\u524D\u7F00\uFF0920000\uFF08\u7F51\u5173\u9519\u8BEF\u7801\uFF09_isp.unknow-error\uFF08\u5B50\u9519\u8BEF\u7801\uFF09 +open.error_20000=Service is temporarily unavailable +open.error_20000_isp.unknown-error=Service is temporarily unavailable +open.error_20000_isp.service-unknown-error=Service not available +open.error_20000_aop.unknown-error=Service is temporarily unavailable +open.error_20000_isp.service-not-available=Service is temporarily unavailable +open.error_20000_isp.gateway-response-timeout=Gateway response timeout +open.error_20000_isv.service-busy=service busy + +open.error_20001=Insufficient authorization authority +open.error_20001_aop.invalid-auth-token=Invalid access token +open.error_20001_aop.auth-token-time-out=The access token has expired +open.error_20001_aop.invalid-app-auth-token=Invalid application authorization token +open.error_20001_aop.invalid-app-auth-token-no-api=Merchant does not authorize current interface +open.error_20001_aop.app-auth-token-time-out=The application authorization token has expired +open.error_20001_aop.no-product-reg-by-partner=The merchant has not signed any product + +open.error_40001=Missing required parameters +open.error_40001_isv.missing-method=Method name parameter is missing +open.error_40001_isv.missing-signature=Lack of signature parameter +open.error_40001_isv.missing-signature-type=Missing signature type parameter +open.error_40001_isv.missing-signature-key=Lack of signature configuration +open.error_40001_isv.missing-app-id=Missing appId parameter +open.error_40001_isv.missing-timestamp=Missing timestamp parameter +open.error_40001_isv.missing-version=Missing version parameter +open.error_40001_isv.decryption-error-missing-encrypt-type=Decryption error, no encryption algorithm specified + +open.error_40002=Invalid parameter +open.error_40002_isv.invalid-parameter=Parameter is invalid +open.error_40002_isv.error-parameter=Parameter incorrect +open.error_40002_isv.upload-fail=File upload failed +open.error_40002_isv.invalid-file-extension=Invalid file extension +open.error_40002_isv.invalid-file-size=Invalid {0} file size, the max size is {1} +open.error_40002_isv.invalid-method=Nonexistent method name +open.error_40002_isv.invalid-format=Invalid data format +open.error_40002_isv.invalid-signature-type=Invalid signature type +open.error_40002_isv.invalid-signature=Invalid signature +open.error_40002_isv.invalid-encrypt-type=Invalid encryption type +open.error_40002_isv.invalid-encrypt=Decryption exception +open.error_40002_isv.invalid-app-id=Invalid appId parameter +open.error_40002_isv.invalid-timestamp=Invalid timestamp parameter +open.error_40002_isv.invalid-charset=Character set error +open.error_40002_isv.invalid-digest=Digest error +open.error_40002_isv.decryption-error-not-valid-encrypt-type=Decryption error, unsupported encryption algorithm +open.error_40002_isv.decryption-error-not-valid-encrypt-key=Decryption error, unconfigured encryption key or encryption key format error +open.error_40002_isv.decryption-error-unknown=Decryption error, unknown exception +open.error_40002_isv.missing-signature-config=Signature verification error, no public key or certificate of the corresponding signature algorithm is configured +open.error_40002_isv.not-support-app-auth=This interface does not support third-party proxy calls +open.error_40002_isv.suspected-attack=Suspicious attack requests +open.error_40002_isv.invalid-content-type=Invalid content type + +open.error_40004=Business processing failure +open.error_40004_=Business processing failure + +open.error_40006=Insufficient permissions +open.error_40006_isv.insufficient-isv-permissions=Insufficient ISV permissions +open.error_40006_isv.insufficient-user-permissions=Insufficient user permissions +open.error_40006_isv.route-no-permissions=No api permissions +open.error_40006_isv.access-forbidden=Access forbidden +open.error_40006_isv.ip-forbidden=IP access forbidden diff --git a/sop-index/sop-index-service/src/main/resources/i18n/open/error_zh_CN.properties b/sop-index/sop-index-service/src/main/resources/i18n/open/error_zh_CN.properties new file mode 100644 index 00000000..9578df54 --- /dev/null +++ b/sop-index/sop-index-service/src/main/resources/i18n/open/error_zh_CN.properties @@ -0,0 +1,122 @@ +# \u7F51\u5173\u9519\u8BEF\u914D\u7F6E + +#open.error_20000=\u670D\u52A1\u4E0D\u53EF\u7528 +#open.error_20000_isp.unknow-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528 +#open.error_20000_aop.unknow-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528 +#open.error_20000_isp.service-not-available=\u670D\u52A1\u6682\u4E0D\u53EF\u7528 +# +#open.error_20001=\u6388\u6743\u6743\u9650\u4E0D\u8DB3 +#open.error_20001_aop.invalid-auth-token=\u65E0\u6548\u7684\u8BBF\u95EE\u4EE4\u724C +#open.error_20001_aop.auth-token-time-out=\u8BBF\u95EE\u4EE4\u724C\u5DF2\u8FC7\u671F +#open.error_20001_aop.invalid-app-auth-token=\u65E0\u6548\u7684\u5E94\u7528\u6388\u6743\u4EE4\u724C +#open.error_20001_aop.invalid-app-auth-token-no-api=\u5546\u6237\u672A\u6388\u6743\u5F53\u524D\u63A5\u53E3 +#open.error_20001_aop.app-auth-token-time-out=\u5E94\u7528\u6388\u6743\u4EE4\u724C\u5DF2\u8FC7\u671F +#open.error_20001_aop.no-product-reg-by-partner=\u5546\u6237\u672A\u7B7E\u7EA6\u4EFB\u4F55\u4EA7\u54C1 +# +#open.error_40001=\u7F3A\u5C11\u5FC5\u9009\u53C2\u6570 +#open.error_40001_isv.missing-method=\u7F3A\u5C11\u65B9\u6CD5\u540D\u53C2\u6570 +#open.error_40001_isv.missing-signature=\u7F3A\u5C11\u7B7E\u540D\u53C2\u6570 +#open.error_40001_isv.missing-signature-type=\u7F3A\u5C11\u7B7E\u540D\u7C7B\u578B\u53C2\u6570 +#open.error_40001_isv.missing-signature-key=\u7F3A\u5C11\u7B7E\u540D\u914D\u7F6E +#open.error_40001_isv.missing-app-id=\u7F3A\u5C11appId\u53C2\u6570 +#open.error_40001_isv.missing-timestamp=\u7F3A\u5C11\u65F6\u95F4\u6233\u53C2\u6570 +#open.error_40001_isv.missing-version=\u7F3A\u5C11\u7248\u672C\u53C2\u6570 +#open.error_40001_isv.decryption-error-missing-encrypt-type=\u89E3\u5BC6\u51FA\u9519, \u672A\u6307\u5B9A\u52A0\u5BC6\u7B97\u6CD5 +# +#open.error_40002=\u975E\u6CD5\u7684\u53C2\u6570 +#open.error_40002_isv.invalid-parameter=\u53C2\u6570\u65E0\u6548 +#open.error_40002_isv.upload-fail=\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25 +#open.error_40002_isv.invalid-file-extension=\u6587\u4EF6\u6269\u5C55\u540D\u65E0\u6548 +#open.error_40002_isv.invalid-file-size={0}\u6587\u4EF6\u5927\u5C0F\u65E0\u6548\uFF0C\u5355\u6587\u4EF6\u4E0D\u5F97\u8D85\u8FC7{1} +#open.error_40002_isv.invalid-method=\u4E0D\u5B58\u5728\u7684\u65B9\u6CD5\u540D +#open.error_40002_isv.invalid-format=\u65E0\u6548\u7684\u6570\u636E\u683C\u5F0F +#open.error_40002_isv.invalid-signature-type=\u65E0\u6548\u7684\u7B7E\u540D\u7C7B\u578B +#open.error_40002_isv.invalid-signature=\u65E0\u6548\u7B7E\u540D +#open.error_40002_isv.invalid-encrypt-type=\u65E0\u6548\u7684\u52A0\u5BC6\u7C7B\u578B +#open.error_40002_isv.invalid-encrypt=\u89E3\u5BC6\u5F02\u5E38 +#open.error_40002_isv.invalid-app-id=\u65E0\u6548\u7684appId\u53C2\u6570 +#open.error_40002_isv.invalid-timestamp=\u975E\u6CD5\u7684\u65F6\u95F4\u6233\u53C2\u6570 +#open.error_40002_isv.invalid-charset=\u5B57\u7B26\u96C6\u9519\u8BEF +#open.error_40002_isv.invalid-digest=\u6458\u8981\u9519\u8BEF +#open.error_40002_isv.decryption-error-not-valid-encrypt-type=\u89E3\u5BC6\u51FA\u9519\uFF0C\u4E0D\u652F\u6301\u7684\u52A0\u5BC6\u7B97\u6CD5 +#open.error_40002_isv.decryption-error-not-valid-encrypt-key=\u89E3\u5BC6\u51FA\u9519, \u672A\u914D\u7F6E\u52A0\u5BC6\u5BC6\u94A5\u6216\u52A0\u5BC6\u5BC6\u94A5\u683C\u5F0F\u9519\u8BEF +#open.error_40002_isv.decryption-error-unknown=\u89E3\u5BC6\u51FA\u9519\uFF0C\u672A\u77E5\u5F02\u5E38 +#open.error_40002_isv.missing-signature-config=\u9A8C\u7B7E\u51FA\u9519, \u672A\u914D\u7F6E\u5BF9\u5E94\u7B7E\u540D\u7B97\u6CD5\u7684\u516C\u94A5\u6216\u8005\u8BC1\u4E66 +#open.error_40002_isv.not-support-app-auth=\u672C\u63A5\u53E3\u4E0D\u652F\u6301\u7B2C\u4E09\u65B9\u4EE3\u7406\u8C03\u7528 +#open.error_40002_isv.suspected-attack=\u53EF\u7591\u7684\u653B\u51FB\u8BF7\u6C42 +#open.error_40002_isv.invalid-content-type=\u65E0\u6548\u7684content-type +# +#open.error_40004=\u4E1A\u52A1\u5904\u7406\u5931\u8D25 +#open.error_40004_=\u4E1A\u52A1\u5904\u7406\u5931\u8D25 +# +#open.error_40006=\u6743\u9650\u4E0D\u8DB3 +#open.error_40006_isv.insufficient-isv-permissions=\u8BF7\u68C0\u67E5\u914D\u7F6E\u7684\u8D26\u6237\u662F\u5426\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650 +#open.error_40006_isv.insufficient-user-permissions=\u4EE3\u7406\u7684\u5546\u6237\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650 +#open.error_40006_isv.route-no-permissions=\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650 +#open.error_40006_isv.access-forbidden=\u65E0\u6743\u8BBF\u95EE + + +open.error_10000=Success + +# \u683C\u5F0F\uFF1A\u524D\u7F00 + \u7F51\u5173\u9519\u8BEF\u7801 + "_"+ \u5B50\u9519\u8BEF\u7801 +# open.error_\uFF08\u524D\u7F00\uFF0920000\uFF08\u7F51\u5173\u9519\u8BEF\u7801\uFF09_isp.unknow-error\uFF08\u5B50\u9519\u8BEF\u7801\uFF09 +open.error_20000=\u670D\u52A1\u4E0D\u53EF\u7528 +open.error_20000_isp.unknown-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528 +open.error_20000_isp.service-unknown-error=\u670D\u52A1\u4E0D\u53EF\u7528 +open.error_20000_aop.unknown-error=\u670D\u52A1\u6682\u4E0D\u53EF\u7528 +open.error_20000_isp.service-not-available=\u670D\u52A1\u6682\u4E0D\u53EF\u7528 +open.error_20000_isp.gateway-response-timeout=\u7F51\u5173\u54CD\u5E94\u8D85\u65F6 +open.error_20000_isv.service-busy=\u670D\u52A1\u5668\u5FD9 + +open.error_20001=\u6388\u6743\u6743\u9650\u4E0D\u8DB3 +open.error_20001_aop.invalid-auth-token=\u65E0\u6548\u7684\u8BBF\u95EE\u4EE4\u724C +open.error_20001_aop.auth-token-time-out=\u8BBF\u95EE\u4EE4\u724C\u5DF2\u8FC7\u671F +open.error_20001_aop.invalid-app-auth-token=\u65E0\u6548\u7684\u5E94\u7528\u6388\u6743\u4EE4\u724C +open.error_20001_aop.invalid-app-auth-token-no-api=\u5546\u6237\u672A\u6388\u6743\u5F53\u524D\u63A5\u53E3 +open.error_20001_aop.app-auth-token-time-out=\u5E94\u7528\u6388\u6743\u4EE4\u724C\u5DF2\u8FC7\u671F +open.error_20001_aop.no-product-reg-by-partner=\u5546\u6237\u672A\u7B7E\u7EA6\u4EFB\u4F55\u4EA7\u54C1 + +open.error_40001=\u7F3A\u5C11\u5FC5\u9009\u53C2\u6570 +open.error_40001_isv.missing-method=\u7F3A\u5C11\u65B9\u6CD5\u540D\u53C2\u6570 +open.error_40001_isv.missing-signature=\u7F3A\u5C11\u7B7E\u540D\u53C2\u6570 +open.error_40001_isv.missing-signature-type=\u7F3A\u5C11\u7B7E\u540D\u7C7B\u578B\u53C2\u6570 +open.error_40001_isv.missing-signature-key=\u7F3A\u5C11\u7B7E\u540D\u914D\u7F6E +open.error_40001_isv.missing-app-id=\u7F3A\u5C11appId\u53C2\u6570 +open.error_40001_isv.missing-timestamp=\u7F3A\u5C11\u65F6\u95F4\u6233\u53C2\u6570 +open.error_40001_isv.missing-version=\u7F3A\u5C11\u7248\u672C\u53C2\u6570 +open.error_40001_isv.decryption-error-missing-encrypt-type=\u89E3\u5BC6\u51FA\u9519, \u672A\u6307\u5B9A\u52A0\u5BC6\u7B97\u6CD5 + +open.error_40002=\u975E\u6CD5\u7684\u53C2\u6570 +open.error_40002_isv.invalid-parameter=\u53C2\u6570\u65E0\u6548 +open.error_40002_isv.error-parameter=\u53c2\u6570\u4e0d\u6b63\u786e + +open.error_40002_isv.upload-fail=\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25 +open.error_40002_isv.invalid-file-extension=\u6587\u4EF6\u6269\u5C55\u540D\u65E0\u6548 +open.error_40002_isv.invalid-file-size={0}\u6587\u4EF6\u5927\u5C0F\u65E0\u6548\uFF0C\u5355\u6587\u4EF6\u4E0D\u5F97\u8D85\u8FC7{1} +open.error_40002_isv.invalid-method=\u4E0D\u5B58\u5728\u7684\u65B9\u6CD5\u540D +open.error_40002_isv.invalid-format=\u65E0\u6548\u7684\u6570\u636E\u683C\u5F0F +open.error_40002_isv.invalid-signature-type=\u65E0\u6548\u7684\u7B7E\u540D\u7C7B\u578B +open.error_40002_isv.invalid-signature=\u65E0\u6548\u7B7E\u540D +open.error_40002_isv.invalid-encrypt-type=\u65E0\u6548\u7684\u52A0\u5BC6\u7C7B\u578B +open.error_40002_isv.invalid-encrypt=\u89E3\u5BC6\u5F02\u5E38 +open.error_40002_isv.invalid-app-id=\u65E0\u6548\u7684appId\u53C2\u6570 +open.error_40002_isv.invalid-timestamp=\u975E\u6CD5\u7684\u65F6\u95F4\u6233\u53C2\u6570 +open.error_40002_isv.invalid-charset=\u5B57\u7B26\u96C6\u9519\u8BEF +open.error_40002_isv.invalid-digest=\u6458\u8981\u9519\u8BEF +open.error_40002_isv.decryption-error-not-valid-encrypt-type=\u89E3\u5BC6\u51FA\u9519\uFF0C\u4E0D\u652F\u6301\u7684\u52A0\u5BC6\u7B97\u6CD5 +open.error_40002_isv.decryption-error-not-valid-encrypt-key=\u89E3\u5BC6\u51FA\u9519, \u672A\u914D\u7F6E\u52A0\u5BC6\u5BC6\u94A5\u6216\u52A0\u5BC6\u5BC6\u94A5\u683C\u5F0F\u9519\u8BEF +open.error_40002_isv.decryption-error-unknown=\u89E3\u5BC6\u51FA\u9519\uFF0C\u672A\u77E5\u5F02\u5E38 +open.error_40002_isv.missing-signature-config=\u9A8C\u7B7E\u51FA\u9519, \u672A\u914D\u7F6E\u5BF9\u5E94\u7B7E\u540D\u7B97\u6CD5\u7684\u516C\u94A5\u6216\u8005\u8BC1\u4E66 +open.error_40002_isv.not-support-app-auth=\u672C\u63A5\u53E3\u4E0D\u652F\u6301\u7B2C\u4E09\u65B9\u4EE3\u7406\u8C03\u7528 +open.error_40002_isv.suspected-attack=\u53EF\u7591\u7684\u653B\u51FB\u8BF7\u6C42 +open.error_40002_isv.invalid-content-type=\u65E0\u6548\u7684content-type + +open.error_40004=\u4E1A\u52A1\u5904\u7406\u5931\u8D25 +open.error_40004_=\u4E1A\u52A1\u5904\u7406\u5931\u8D25 + +open.error_40006=\u6743\u9650\u4E0D\u8DB3 +open.error_40006_isv.insufficient-isv-permissions=\u8BF7\u68C0\u67E5\u914D\u7F6E\u7684\u8D26\u6237\u662F\u5426\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650 +open.error_40006_isv.insufficient-user-permissions=\u4EE3\u7406\u7684\u5546\u6237\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650 +open.error_40006_isv.route-no-permissions=\u6CA1\u6709\u5F53\u524D\u63A5\u53E3\u6743\u9650 +open.error_40006_isv.access-forbidden=\u65E0\u6743\u8BBF\u95EE +open.error_40006_isv.ip-forbidden=IP\u65E0\u6743\u8BBF\u95EE diff --git a/sop-index/sop-index-service/src/main/resources/i18n/readme.md b/sop-index/sop-index-service/src/main/resources/i18n/readme.md new file mode 100644 index 00000000..08062f2d --- /dev/null +++ b/sop-index/sop-index-service/src/main/resources/i18n/readme.md @@ -0,0 +1 @@ +存放国际化文件 diff --git a/sop-index/src/main/java/com/gitee/sop/index/controller/param/ApiResponse.java b/sop-index/src/main/java/com/gitee/sop/index/controller/param/ApiResponse.java deleted file mode 100644 index 9b031811..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/controller/param/ApiResponse.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.gitee.sop.index.controller.param; - -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Data; - -import java.io.Serializable; - -/** - * 默认的结果封装类. - *
- *
- * xml返回结果:
- * 
- *     50
- *     Remote service error
- *     isv.invalid-parameter
- *     非法参数
- * 
- * 成功情况:
- * 
- *     0
- *     成功消息
- *     
- *         ...返回内容
- *     
- * 
- *
- * json返回格式:
- * {
- *  "code":"50",
- * 	"msg":"Remote service error",
- * 	"sub_code":"isv.invalid-parameter",
- * 	"sub_msg":"非法参数"
- * }
- * 成功情况:
- * {
- *  "code":"0",
- * 	"msg":"成功消息内容。。。",
- * 	"data":{
- * 	    ...返回内容
- *    }
- * }
- * 
- *

- * 字段说明: - * code:网关异常码
- * msg:网关异常信息
- * sub_code:业务异常码
- * sub_msg:业务异常信息
- * - * @author tanghc - */ -@Data -// 驼峰转下划线 -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public class ApiResponse implements Serializable { - private static final long serialVersionUID = 6208496044702199437L; - - /** - * 网关异常码,范围0~100 成功返回"0" - */ - private String code = "0"; - - /** - * 网关异常信息 - */ - private String msg; - - /** - * 业务异常码 - */ - private String subCode; - - /** - * 业务异常信息 - */ - private String subMsg; - - - -} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/RouteService.java b/sop-index/src/main/java/com/gitee/sop/index/service/RouteService.java deleted file mode 100644 index df4ca25b..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/service/RouteService.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.gitee.sop.index.service; - -import com.gitee.sop.index.controller.param.ApiRequest; -import com.gitee.sop.index.controller.param.ApiResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * 接口路由 - * - * @author 六如 - */ -@Service -public class RouteService { - - @Autowired - private ValidateService validateService; - - public ApiResponse route(ApiRequest apiRequest) { - // 签名校验 - validateService.validate(apiRequest); - - return null; - } - - - -} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiSigner.java b/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiSigner.java deleted file mode 100644 index 5c771411..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/ApiSigner.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.gitee.sop.index.service.validate; - - -import com.gitee.sop.gatewaycommon.message.ErrorEnum; -import com.gitee.sop.gatewaycommon.param.ApiParam; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * 签名验证实现 - * - * @author tanghc - */ -public class ApiSigner extends AbstractSigner { - - private Map signEncipherMap = new HashMap<>(); - - public ApiSigner() { - signEncipherMap.put("md5", new SignEncipherMD5()); - signEncipherMap.put("hmac", new SignEncipherHMAC_MD5()); - } - - - @Override - public String buildServerSign(ApiParam param, String secret) { - String signMethod = param.fetchSignMethod(); - SignEncipher signEncipher = signEncipherMap.get(signMethod); - if (signEncipher == null) { - throw ErrorEnum.ISV_INVALID_SIGNATURE_TYPE.getErrorMeta().getException(signMethod); - } - - // 第一步:参数排序 - Set keySet = param.keySet(); - List paramNames = new ArrayList<>(keySet); - Collections.sort(paramNames); - - // 第二步:把所有参数名和参数值串在一起 - StringBuilder paramNameValue = new StringBuilder(); - for (String paramName : paramNames) { - paramNameValue.append(paramName).append(param.get(paramName)); - } - - // 第三步:使用MD5/HMAC加密 - String source = paramNameValue.toString(); - byte[] bytes = signEncipher.encrypt(source, secret); - - // 第四步:把二进制转化为大写的十六进制 - return byte2hex(bytes).toUpperCase(); - } -} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/SignEncipherHMAC_MD5.java b/sop-index/src/main/java/com/gitee/sop/index/service/validate/SignEncipherHMAC_MD5.java deleted file mode 100644 index 7c5a027f..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/SignEncipherHMAC_MD5.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.gitee.sop.index.service.validate; - -import com.gitee.sop.gatewaycommon.bean.SopConstants; -import com.gitee.sop.gatewaycommon.message.ErrorEnum; -import lombok.extern.slf4j.Slf4j; - -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -/** - * HMAC_MD5加密 - * @author tanghc - */ -@Slf4j -public class SignEncipherHMAC_MD5 implements SignEncipher { - - public static final String HMAC_MD5 = "HmacMD5"; - - @Override - public byte[] encrypt(String input, String secret) { - try { - SecretKey secretKey = new SecretKeySpec(secret.getBytes(SopConstants.CHARSET_UTF8), HMAC_MD5); - Mac mac = Mac.getInstance(secretKey.getAlgorithm()); - mac.init(secretKey); - return mac.doFinal(input.getBytes(SopConstants.CHARSET_UTF8)); - } catch (NoSuchAlgorithmException e) { - log.error("HMAC_MD5加密加密失败NoSuchAlgorithmException", e); - throw ErrorEnum.ISV_INVALID_SIGNATURE.getErrorMeta().getException(); - } catch (InvalidKeyException e) { - log.error("HMAC_MD5加密加密失败InvalidKeyException", e); - throw ErrorEnum.ISV_INVALID_SIGNATURE.getErrorMeta().getException(); - } - } -} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySigner.java b/sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySigner.java deleted file mode 100644 index 64fe7ccc..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/alipay/AlipaySigner.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.gitee.sop.index.service.validate.alipay; - - -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; -import com.gitee.sop.index.controller.param.ApiRequest; -import com.gitee.sop.index.message.ErrorEnum; -import com.gitee.sop.index.service.validate.Signer; - -/** - * 支付宝签名验证实现。 - * - * @author tanghc - * @see 支付宝签名 - */ -public class AlipaySigner implements Signer { - - @Override - public boolean checkSign(ApiRequest apiParam, String secret) { - // 服务端存的是公钥 - String publicKey = secret; - String charset = apiParam.getCharset(); - String signType = apiParam.getSign_type(); - if (signType == null) { - throw ErrorEnum.ISV_DECRYPTION_ERROR_MISSING_ENCRYPT_TYPE.getErrorMeta().getException(); - } - if (charset == null) { - throw ErrorEnum.ISV_INVALID_CHARSET.getErrorMeta().getException(); - } - String json = JSON.toJSONString(apiParam); - JSONObject params = JSON.parseObject(json); - return AlipaySignature.rsaCheckV2(params, publicKey, charset, signType); - } - -} diff --git a/sop-index/src/main/java/com/gitee/sop/index/service/validate/taobao/TaobaoSigner.java b/sop-index/src/main/java/com/gitee/sop/index/service/validate/taobao/TaobaoSigner.java deleted file mode 100644 index 2de3536e..00000000 --- a/sop-index/src/main/java/com/gitee/sop/index/service/validate/taobao/TaobaoSigner.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.gitee.sop.index.service.validate.taobao; - - -import com.gitee.sop.gatewaycommon.bean.SopConstants; -import com.gitee.sop.gatewaycommon.message.ErrorEnum; -import com.gitee.sop.gatewaycommon.param.ApiParam; -import com.gitee.sop.gatewaycommon.validate.AbstractSigner; -import com.gitee.sop.gatewaycommon.validate.SignConfig; -import com.gitee.sop.gatewaycommon.validate.SignEncipher; -import com.gitee.sop.gatewaycommon.validate.SignEncipherHMAC_MD5; -import com.gitee.sop.gatewaycommon.validate.SignEncipherMD5; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * 淘宝开放平台签名验证实现,http://open.taobao.com/doc.htm?docId=101617&docType=1 - * - * @author tanghc - */ -public class TaobaoSigner extends AbstractSigner { - - private Map signEncipherMap = new HashMap<>(); - - public TaobaoSigner() { - signEncipherMap.put("md5", new SignEncipherMD5()); - signEncipherMap.put("hmac", new SignEncipherHMAC_MD5()); - } - - - @Override - public String buildServerSign(ApiParam param, String secret) { - String signMethod = param.fetchSignMethod(); - if (signMethod == null) { - signMethod = SopConstants.DEFAULT_SIGN_METHOD; - } - SignEncipher signEncipher = signEncipherMap.get(signMethod); - if (signEncipher == null) { - throw ErrorEnum.ISV_INVALID_SIGNATURE_TYPE.getErrorMeta().getException(signMethod); - } - - // 第一步:参数排序 - Set keySet = param.keySet(); - List paramNames = new ArrayList<>(keySet); - Collections.sort(paramNames); - - // 第二步:把所有参数名和参数值串在一起 - StringBuilder paramNameValue = new StringBuilder(); - for (String paramName : paramNames) { - String val = SignConfig.wrapVal(param.get(paramName)); - paramNameValue.append(paramName).append(val); - } - - // 第三步:使用MD5/HMAC加密 - String source = paramNameValue.toString(); - byte[] bytes = signEncipher.encrypt(source, secret); - - // 第四步:把二进制转化为大写的十六进制 - return byte2hex(bytes).toUpperCase(); - } -} diff --git a/sop-index/src/main/resources/application.properties b/sop-index/src/main/resources/application.properties deleted file mode 100644 index 8284e9f4..00000000 --- a/sop-index/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=sop-index diff --git a/sop-spring-boot-starter/pom.xml b/sop-spring-boot-starter/pom.xml new file mode 100644 index 00000000..3dab4fa5 --- /dev/null +++ b/sop-spring-boot-starter/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + com.gitee.sop + sop-spring-boot-starter + 5.0.0-SNAPSHOT + + + 1.8 + 8 + 8 + UTF-8 + + + + + com.gitee.sop + sop-index-api + 5.0.0-SNAPSHOT + + + + javax.validation + validation-api + 2.0.1.Final + + + + org.springframework.boot + spring-boot-starter + 2.6.15 + true + + + org.apache.dubbo + dubbo + 3.2.6 + true + + + org.projectlombok + lombok + 1.18.34 + true + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + ${java.version} + ${java.version} + + -parameters + + + + + + diff --git a/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/annotation/Open.java b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/annotation/Open.java new file mode 100644 index 00000000..23f8c508 --- /dev/null +++ b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/annotation/Open.java @@ -0,0 +1,47 @@ +package com.gitee.sop.springboot.starter.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author tanghc + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Open { + + /** + * 接口名,如:member.user.get + */ + String value(); + + /** + * 版本号,默认版本号是"1.0" + */ + String version() default "1.0"; + + /** + * 忽略验证,业务参数除外 + */ + boolean ignoreValidate() default false; + + /** + * 告诉网关是否对结果进行合并,默认合并。设置为false,客户端将直接收到微服务端的结果。 + */ + boolean mergeResult() default true; + + /** + * 指定接口是否需要授权才能访问,可在admin中进行修改 + */ + boolean permission() default false; + + /** + * 是否需要appAuthToken,设置为true,网关端会校验token是否存在 + */ + boolean needToken() default false; + +} diff --git a/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/annotation/OpenParam.java b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/annotation/OpenParam.java new file mode 100644 index 00000000..32a42a86 --- /dev/null +++ b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/annotation/OpenParam.java @@ -0,0 +1,16 @@ +package com.gitee.sop.springboot.starter.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author 六如 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface OpenParam { +} diff --git a/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/config/SopAutoConfiguration.java b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/config/SopAutoConfiguration.java new file mode 100644 index 00000000..ff76c965 --- /dev/null +++ b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/config/SopAutoConfiguration.java @@ -0,0 +1,112 @@ +package com.gitee.sop.springboot.starter.config; + +import com.gitee.sop.index.api.ApiRegisterService; +import com.gitee.sop.index.api.RegisterDTO; +import com.gitee.sop.springboot.starter.annotation.Open; +import com.gitee.sop.springboot.starter.annotation.OpenParam; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.env.Environment; +import org.springframework.util.ObjectUtils; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + + +/** + * @author 六如 + */ +@Configuration +@Slf4j +public class SopAutoConfiguration implements InitializingBean { + + @Autowired + private Environment environment; + + @Autowired + private ApplicationContext applicationContext; + + @DubboReference + private ApiRegisterService apiRegisterService; + + @Override + public void afterPropertiesSet() throws Exception { + String appName = environment.getProperty("spring.application.name"); + Map beanMap = applicationContext.getBeansWithAnnotation(DubboService.class); + for (Object serviceObj : beanMap.values()) { + Class objClass = serviceObj.getClass(); + ReflectionUtils.doWithMethods(objClass, method -> { + regApi(appName, objClass, method); + }); + } + } + + private void regApi(String appName, Class clazz, Method method) { + Open open = AnnotationUtils.getAnnotation(method, Open.class); + if (open == null) { + return; + } + Parameter[] parameters = method.getParameters(); + Optional paramOpt = filterParameter(parameters); + String paramName = paramOpt.map(Parameter::getName).orElse(""); + String paramTypeName = paramOpt.map(Parameter::getType).map(Class::getName).orElse(""); + RegisterDTO registerDTO = new RegisterDTO(); + registerDTO.setApplication(appName); + registerDTO.setApiName(open.value()); + registerDTO.setApiVersion(open.version()); + Class[] interfaces = clazz.getInterfaces(); + if (interfaces.length == 0) { + throw new RuntimeException("Dubbo接口必须要实现接口, class=" + clazz.getName()); + } + Optional> interfaceClassOpt = filterInterfaceClass(method, interfaces); + if (!interfaceClassOpt.isPresent()) { + throw new RuntimeException("找不到dubbo接口, clazz=" + clazz.getName()); + } + registerDTO.setInterfaceClassName(interfaceClassOpt.get().getName()); + registerDTO.setMethodName(method.getName()); + registerDTO.setParamName(paramName); + registerDTO.setParamTypeName(paramTypeName); + registerDTO.setIsIgnoreValidate(parseBoolean(open.ignoreValidate())); + registerDTO.setIsPermission(parseBoolean(open.permission())); + registerDTO.setIsNeedToken(parseBoolean(open.needToken())); + log.info("注册开放接口, apiInfo={}", registerDTO); + apiRegisterService.register(registerDTO); + } + + private Optional filterParameter(Parameter[] parameters) { + if (ObjectUtils.isEmpty(parameters)) { + return Optional.empty(); + } + Optional first = Stream.of(parameters) + .filter(parameter -> AnnotationUtils.getAnnotation(parameter, OpenParam.class) != null) + .findFirst(); + return first.isPresent() ? first : Optional.of(parameters[0]); + } + + private Optional> filterInterfaceClass(Method method, Class[] interfaces) { + return Stream.of(interfaces) + .filter(inter -> { + for (Method interMethod : inter.getMethods()) { + if (interMethod.getName().equals(method.getName())) { + return true; + } + } + return false; + }) + .findFirst(); + } + + private int parseBoolean(boolean b) { + return b ? 1 : 0; + } +} diff --git a/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/IntId.java b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/IntId.java new file mode 100644 index 00000000..20021246 --- /dev/null +++ b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/IntId.java @@ -0,0 +1,14 @@ +package com.gitee.sop.springboot.starter.request; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author 六如 + */ +@Data +public class IntId { + @NotNull(message = "id不能为空") + private Integer id; +} diff --git a/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/LongId.java b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/LongId.java new file mode 100644 index 00000000..5e9ea80d --- /dev/null +++ b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/LongId.java @@ -0,0 +1,13 @@ +package com.gitee.sop.springboot.starter.request; + +import lombok.Data; + +/** + * @author 六如 + */ +@Data +public class LongId { + + private Long id; + +} diff --git a/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/OpenRequest.java b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/OpenRequest.java new file mode 100644 index 00000000..cb77ba2d --- /dev/null +++ b/sop-spring-boot-starter/src/main/java/com/gitee/sop/springboot/starter/request/OpenRequest.java @@ -0,0 +1,102 @@ +package com.gitee.sop.springboot.starter.request; + +import com.alibaba.fastjson2.JSON; +import lombok.Data; +import org.springframework.core.GenericTypeResolver; + +import java.io.Serializable; + +/** + * @author 六如 + */ +@Data +public class OpenRequest implements Serializable { + private static final long serialVersionUID = -6703437435180048422L; + + private Class clazz; + + public OpenRequest() { + clazz = (Class) GenericTypeResolver.resolveTypeArgument(getClass(), OpenRequest.class); + } + + /** + * 分配给开发者的应用ID + * + * @mock 2014072300007148 + */ + private String app_id; + + /** + * 接口名称 + * + * @mock alipay.trade.fastpay.refund.query + */ + private String method; + + /** + * 仅支持JSON + * + * @mock json + */ + private String format; + + /** + * 请求使用的编码格式,如utf-8,gbk,gb2312等 + * + * @mock utf-8 + */ + private String charset; + + /** + * 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2 + * + * @mock RSA2 + */ + private String sign_type; + + /** + * 商户请求参数的签名串,详见签名 + */ + private String sign; + + /** + * 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss" + * + * @mock 2014-07-24 03:07:50 + */ + private String timestamp; + + /** + * 调用的接口版本,固定为:1.0 + * + * @mock 1.0 + */ + private String version; + + /** + * 支付宝服务器主动通知商户服务器里指定的页面http/https路径 + * + * @mock http://ww.xx.com/callback + */ + private String notify_url; + + /** + * 授权token,详见应用授权概述 + */ + private String app_auth_token; + + /** + * 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档 + */ + private String biz_content; + + /** + * 将biz_content转成对象 + * + * @return 返回对象 + */ + public T toJavaObject() { + return JSON.parseObject(biz_content, clazz); + } + +} diff --git a/sop-spring-boot-starter/src/main/resources/META-INF/spring.factories b/sop-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..90bb5b32 --- /dev/null +++ b/sop-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configure +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.gitee.sop.springboot.starter.config.SopAutoConfiguration diff --git a/sop-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sop-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..13c1a04f --- /dev/null +++ b/sop-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.gitee.sop.springboot.starter.config.SopAutoConfiguration diff --git a/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java b/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java index 1ab624b0..52e75089 100644 --- a/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java +++ b/sop-test/src/test/java/com/gitee/sop/test/AlipayClientPostTest.java @@ -14,7 +14,7 @@ import java.util.Map; */ public class AlipayClientPostTest extends TestBase { - String url = "http://localhost:8081"; + String url = "http://localhost:8081/api"; String appId = "2019032617262200001"; // 平台提供的私钥 String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ="; @@ -64,7 +64,42 @@ public class AlipayClientPostTest extends TestBase { System.out.println("URL参数:" + buildUrlQuery(params)); System.out.println("----------- 返回结果 -----------"); - String responseData = get(url, params);// 发送请求 + String responseData = postJson(url, params);// 发送请求 + System.out.println(responseData); + } + + @Test + public void testSave() throws Exception { + + // 公共请求参数 + Map params = new HashMap(); + params.put("app_id", appId); + params.put("method", "story.save"); + params.put("format", "json"); + params.put("charset", "utf-8"); + params.put("sign_type", "RSA2"); + params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + params.put("version", "1.0"); + + // 业务参数 + Map bizContent = new HashMap<>(); + bizContent.put("storyName", "小猫钓鱼"); + bizContent.put("addTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + + params.put("biz_content", JSON.toJSONString(bizContent)); + String content = AlipaySignature.getSignContent(params); + String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8"); + params.put("sign", sign); + + System.out.println("----------- 请求信息 -----------"); + System.out.println("请求参数:" + buildParamQuery(params)); + System.out.println("商户秘钥:" + privateKey); + System.out.println("待签名内容:" + content); + System.out.println("签名(sign):" + sign); + System.out.println("URL参数:" + buildUrlQuery(params)); + + System.out.println("----------- 返回结果 -----------"); + String responseData = postJson(url, params);// 发送请求 System.out.println(responseData); } diff --git a/sop.sql b/sop.sql index 3f7ef0e3..cffc83d2 100644 --- a/sop.sql +++ b/sop.sql @@ -2,7 +2,25 @@ CREATE DATABASE IF NOT EXISTS `sop` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; USE `sop`; +-- 5.0 +CREATE TABLE `api_info` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `application` varchar(64) NOT NULL DEFAULT '' COMMENT '应用名称', + `api_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口名称', + `api_version` varchar(16) NOT NULL DEFAULT '1.0' COMMENT '版本号', + `interface_class_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口class', + `method_name` varchar(128) NOT NULL DEFAULT '' COMMENT '方法名称', + `param_class_name` varchar(128) NOT NULL DEFAULT '' COMMENT '参数class', + is_ignore_validate tinyint(4) NOT NULL DEFAULT '0' COMMENT '忽略验证', + is_permission tinyint(4) NOT NULL DEFAULT '0' COMMENT '接口是否需要授权访问', + is_need_Token tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否需要appAuthToken', + status tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态,1-启用,0-禁用', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_apiname_version` (`api_name`, api_version) USING BTREE +) ENGINE=InnoDB COMMENT='接口信息表'; DROP TABLE IF EXISTS `user_info`;