新增文档

1.x
tanghc 6 years ago
parent bb96c47860
commit e28fd3b2ec
  1. 1
      pom.xml
  2. 11
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/param/ZuulParamBuilder.java
  3. 18
      sop-common/sop-service-common/pom.xml
  4. 2
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/annotation/ApiMapping.java
  5. 27
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/bean/EnvironmentContext.java
  6. 36
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/BaseServiceConfiguration.java
  7. 4
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/EasyopenServiceConfiguration.java
  8. 84
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/SpringMvcServiceConfiguration.java
  9. 18
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/DefaultRequestMappingEvent.java
  10. 4
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/manager/RequestMappingEvent.java
  11. 18
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/ApiMappingHandlerMapping.java
  12. 20
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/mapping/MappingUtil.java
  13. 16
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/ApiListingScannerExt.java
  14. 60
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/DocumentationPluginsManagerExt.java
  15. 44
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSupport.java
  16. 15
      sop-example/sop-springmvc/src/main/java/com/gitee/app/config/OpenServiceConfig.java
  17. 24
      sop-example/sop-story/sop-story-web/pom.xml
  18. 24
      sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/bookweb/config/OpenServiceConfig.java
  19. 9
      sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/bookweb/controller/AlipayController.java
  20. 3
      sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/bookweb/controller/Story2Controller.java
  21. 18
      sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/bookweb/controller/param/StoryParam.java
  22. 17
      sop-test/src/test/java/com/gitee/sop/PermissionDemoPostTest.java

@ -19,5 +19,6 @@
<module>sop-gateway</module> <module>sop-gateway</module>
<module>sop-test</module> <module>sop-test</module>
<module>sop-sdk</module> <module>sop-sdk</module>
<module>sop-website</module>
</modules> </modules>
</project> </project>

@ -1,7 +1,6 @@
package com.gitee.sop.gatewaycommon.zuul.param; package com.gitee.sop.gatewaycommon.zuul.param;
import com.alibaba.fastjson.JSON; import com.gitee.sop.gatewaycommon.message.ErrorEnum;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.param.ApiParam; import com.gitee.sop.gatewaycommon.param.ApiParam;
import com.gitee.sop.gatewaycommon.param.ApiParamFactory; import com.gitee.sop.gatewaycommon.param.ApiParamFactory;
import com.gitee.sop.gatewaycommon.param.ApiUploadContext; import com.gitee.sop.gatewaycommon.param.ApiUploadContext;
@ -64,13 +63,7 @@ public class ZuulParamBuilder implements ParamBuilder<RequestContext> {
// json或者纯文本形式 // json或者纯文本形式
if (contentType.contains(CONTENT_TYPE_JSON) || contentType.contains(CONTENT_TYPE_TEXT)) { if (contentType.contains(CONTENT_TYPE_JSON) || contentType.contains(CONTENT_TYPE_TEXT)) {
String txt = SopConstants.EMPTY_JSON; throw ErrorEnum.ISV_INVALID_CONTENT_TYPE.getErrorMeta().getException();
try {
txt = RequestUtil.getText(request);
} catch (Exception e) {
log.error("获取纯文本内容失败", e);
}
params = JSON.parseObject(txt);
} else { } else {
params = RequestUtil.convertRequestParamsToMap(request); params = RequestUtil.convertRequestParamsToMap(request);
} }

@ -33,6 +33,24 @@
<version>1.16.1</version> <version>1.16.1</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>2.9.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<optional>true</optional>
</dependency>
</dependencies> </dependencies>

@ -59,7 +59,7 @@ public @interface ApiMapping {
@AliasFor(annotation = RequestMapping.class) @AliasFor(annotation = RequestMapping.class)
RequestMethod[] method() default {}; RequestMethod[] method() default {RequestMethod.GET, RequestMethod.POST};
/** /**
* Alias for {@link RequestMapping#params}. * Alias for {@link RequestMapping#params}.

@ -0,0 +1,27 @@
package com.gitee.sop.servercommon.bean;
import org.springframework.core.env.Environment;
/**
* @author thc
*/
public class EnvironmentContext {
private static Environment environment;
public static Environment getEnvironment() {
return environment;
}
public static void setEnvironment(Environment environment) {
EnvironmentContext.environment = environment;
}
public static String getProfile(Environment env) {
return env.getProperty("spring.profiles.active", "default");
}
public static String getProfile() {
return getProfile(environment);
}
}

@ -8,7 +8,10 @@ import com.gitee.sop.servercommon.manager.RequestMappingEvent;
import com.gitee.sop.servercommon.manager.ServiceZookeeperApiMetaManager; import com.gitee.sop.servercommon.manager.ServiceZookeeperApiMetaManager;
import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping; import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping;
import com.gitee.sop.servercommon.message.ServiceErrorFactory; import com.gitee.sop.servercommon.message.ServiceErrorFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@ -20,7 +23,9 @@ import javax.annotation.PostConstruct;
/** /**
* @author tanghc * @author tanghc
*/ */
public class BaseServiceConfiguration extends WebMvcConfigurationSupport { @Slf4j
public class BaseServiceConfiguration extends WebMvcConfigurationSupport
implements ApplicationRunner {
public BaseServiceConfiguration() { public BaseServiceConfiguration() {
ServiceConfig.getInstance().getI18nModules().add("i18n/isp/bizerror"); ServiceConfig.getInstance().getI18nModules().add("i18n/isp/bizerror");
@ -29,6 +34,9 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport {
@Autowired @Autowired
private Environment environment; private Environment environment;
private ApiMappingHandlerMapping apiMappingHandlerMapping = new ApiMappingHandlerMapping();
@Override @Override
protected void addInterceptors(InterceptorRegistry registry) { protected void addInterceptors(InterceptorRegistry registry) {
// 添加拦截器 // 添加拦截器
@ -42,9 +50,7 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport {
*/ */
@Override @Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() { protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
ApiMetaManager apiMetaManager = getApiMetaManager(environment); return apiMappingHandlerMapping;
RequestMappingEvent requestMappingEvent = getRequestMappingEvent(apiMetaManager, environment);
return new ApiMappingHandlerMapping(requestMappingEvent);
} }
protected RequestMappingEvent getRequestMappingEvent(ApiMetaManager apiMetaManager, Environment environment) { protected RequestMappingEvent getRequestMappingEvent(ApiMetaManager apiMetaManager, Environment environment) {
@ -62,14 +68,36 @@ public class BaseServiceConfiguration extends WebMvcConfigurationSupport {
@PostConstruct @PostConstruct
public final void after() { public final void after() {
log.info("-----spring容器加载完毕-----");
initMessage(); initMessage();
doAfter(); doAfter();
} }
// springboot启动完成后执行
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("-----服务器启动完毕-----");
ApiMetaManager apiMetaManager = getApiMetaManager(environment);
RequestMappingEvent requestMappingEvent = getRequestMappingEvent(apiMetaManager, environment);
requestMappingEvent.onRegisterSuccess(apiMappingHandlerMapping);
this.onStartup(args);
}
/**
* spring容器加载完毕后执行
*/
protected void doAfter() { protected void doAfter() {
} }
/**
* 启动完毕后执行
* @param args
*/
protected void onStartup(ApplicationArguments args) {
}
protected void initMessage() { protected void initMessage() {
ServiceErrorFactory.initMessageSource(ServiceConfig.getInstance().getI18nModules()); ServiceErrorFactory.initMessageSource(ServiceConfig.getInstance().getI18nModules());
} }

@ -7,12 +7,12 @@ import com.gitee.sop.servercommon.bean.ServiceApiInfo;
import com.gitee.sop.servercommon.manager.ApiMetaManager; import com.gitee.sop.servercommon.manager.ApiMetaManager;
import com.gitee.sop.servercommon.manager.DefaultRequestMappingEvent; import com.gitee.sop.servercommon.manager.DefaultRequestMappingEvent;
import com.gitee.sop.servercommon.manager.RequestMappingEvent; import com.gitee.sop.servercommon.manager.RequestMappingEvent;
import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
@ -49,7 +49,7 @@ public class EasyopenServiceConfiguration extends BaseServiceConfiguration {
} }
@Override @Override
protected List<ServiceApiInfo.ApiMeta> buildApiMetaList(ApiMappingHandlerMapping apiMappingHandlerMapping) { protected List<ServiceApiInfo.ApiMeta> buildApiMetaList(RequestMappingHandlerMapping requestMappingHandlerMapping) {
ApplicationContext ctx = getApplicationContext(); ApplicationContext ctx = getApplicationContext();
String[] apiServiceNames = ReflectionUtil.findApiServiceNames(ctx); String[] apiServiceNames = ReflectionUtil.findApiServiceNames(ctx);
List<ServiceApiInfo.ApiMeta> apiMetaList = new ArrayList<>(); List<ServiceApiInfo.ApiMeta> apiMetaList = new ArrayList<>();

@ -0,0 +1,84 @@
package com.gitee.sop.servercommon.configuration;
import com.gitee.sop.servercommon.bean.EnvironmentContext;
import com.gitee.sop.servercommon.bean.ServiceConfig;
import com.gitee.sop.servercommon.manager.ApiMetaManager;
import com.gitee.sop.servercommon.manager.DefaultRequestMappingEvent;
import com.gitee.sop.servercommon.manager.RequestMappingEvent;
import com.gitee.sop.servercommon.manager.ServiceZookeeperApiMetaManager;
import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping;
import com.gitee.sop.servercommon.message.ServiceErrorFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.annotation.PostConstruct;
import java.util.concurrent.Executors;
/**
* 提供给springmvc工程
* @author tanghc
*/
@Slf4j
public class SpringMvcServiceConfiguration {
public SpringMvcServiceConfiguration() {
ServiceConfig.getInstance().getI18nModules().add("i18n/isp/bizerror");
}
private ApiMappingHandlerMapping apiMappingHandlerMapping = new ApiMappingHandlerMapping();
@Autowired
private Environment environment;
/**
* 自定义Mapping详见@ApiMapping
*
* @return 返回RequestMappingHandlerMapping
*/
@Bean
@Primary
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return apiMappingHandlerMapping;
}
@Bean
GlobalExceptionHandler globalExceptionHandler() {
return ServiceConfig.getInstance().getGlobalExceptionHandler();
}
@PostConstruct
public final void after() {
log.info("-----spring容器加载完毕-----");
EnvironmentContext.setEnvironment(environment);
Executors.newSingleThreadExecutor().execute(()->{
uploadRouteToZookeeper();
});
initMessage();
doAfter();
}
private void uploadRouteToZookeeper() {
ApiMetaManager apiMetaManager = new ServiceZookeeperApiMetaManager(environment);
RequestMappingEvent requestMappingEvent = new DefaultRequestMappingEvent(apiMetaManager, environment);
requestMappingEvent.onRegisterSuccess(apiMappingHandlerMapping);
}
/**
* spring容器加载完毕后执行
*/
protected void doAfter() {
}
protected void initMessage() {
ServiceErrorFactory.initMessageSource(ServiceConfig.getInstance().getI18nModules());
}
}

@ -1,19 +1,18 @@
package com.gitee.sop.servercommon.manager; package com.gitee.sop.servercommon.manager;
import com.gitee.sop.servercommon.bean.ServiceApiInfo; import com.gitee.sop.servercommon.bean.ServiceApiInfo;
import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping;
import com.gitee.sop.servercommon.mapping.ApiMappingInfo; import com.gitee.sop.servercommon.mapping.ApiMappingInfo;
import com.gitee.sop.servercommon.mapping.ApiMappingRequestCondition; import com.gitee.sop.servercommon.mapping.ApiMappingRequestCondition;
import com.gitee.sop.servercommon.mapping.MappingUtil;
import lombok.Getter; import lombok.Getter;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.RequestCondition; import org.springframework.web.servlet.mvc.condition.RequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -34,12 +33,12 @@ public class DefaultRequestMappingEvent implements RequestMappingEvent {
} }
@Override @Override
public void onRegisterSuccess(ApiMappingHandlerMapping apiMappingHandlerMapping) { public void onRegisterSuccess(RequestMappingHandlerMapping requestMappingHandlerMapping) {
String serviceId = environment.getProperty("spring.application.name"); String serviceId = environment.getProperty("spring.application.name");
if (serviceId == null) { if (serviceId == null) {
throw new IllegalArgumentException("请在application.properties中指定spring.application.name属性"); throw new IllegalArgumentException("请在application.properties中指定spring.application.name属性");
} }
List<ServiceApiInfo.ApiMeta> apis = this.buildApiMetaList(apiMappingHandlerMapping); List<ServiceApiInfo.ApiMeta> apis = this.buildApiMetaList(requestMappingHandlerMapping);
// 排序 // 排序
apis.sort(Comparator.comparing(ServiceApiInfo.ApiMeta::fetchNameVersion)); apis.sort(Comparator.comparing(ServiceApiInfo.ApiMeta::fetchNameVersion));
@ -50,8 +49,8 @@ public class DefaultRequestMappingEvent implements RequestMappingEvent {
apiMetaManager.uploadApi(serviceApiInfo); apiMetaManager.uploadApi(serviceApiInfo);
} }
protected List<ServiceApiInfo.ApiMeta> buildApiMetaList(ApiMappingHandlerMapping apiMappingHandlerMapping) { protected List<ServiceApiInfo.ApiMeta> buildApiMetaList(RequestMappingHandlerMapping requestMappingHandlerMapping) {
Map<RequestMappingInfo, HandlerMethod> handlerMethods = apiMappingHandlerMapping.getHandlerMethods(); Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
Set<RequestMappingInfo> requestMappingInfos = handlerMethods.keySet(); Set<RequestMappingInfo> requestMappingInfos = handlerMethods.keySet();
List<String> store = new ArrayList<>(); List<String> store = new ArrayList<>();
List<ServiceApiInfo.ApiMeta> apis = new ArrayList<>(requestMappingInfos.size()); List<ServiceApiInfo.ApiMeta> apis = new ArrayList<>(requestMappingInfos.size());
@ -96,10 +95,7 @@ public class DefaultRequestMappingEvent implements RequestMappingEvent {
} }
protected String buildName(String path) { protected String buildName(String path) {
path = StringUtils.trimLeadingCharacter(path, '/'); return MappingUtil.buildApiName(path);
path = StringUtils.trimTrailingCharacter(path, '/');
path = path.replace("/", ".");
return path;
} }
} }

@ -1,6 +1,6 @@
package com.gitee.sop.servercommon.manager; package com.gitee.sop.servercommon.manager;
import com.gitee.sop.servercommon.mapping.ApiMappingHandlerMapping; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
/** /**
* @author tanghc * @author tanghc
@ -10,5 +10,5 @@ public interface RequestMappingEvent {
* 注册成功后回调 * 注册成功后回调
* @param apiMappingHandlerMapping * @param apiMappingHandlerMapping
*/ */
void onRegisterSuccess(ApiMappingHandlerMapping apiMappingHandlerMapping); void onRegisterSuccess(RequestMappingHandlerMapping apiMappingHandlerMapping);
} }

@ -1,10 +1,8 @@
package com.gitee.sop.servercommon.mapping; package com.gitee.sop.servercommon.mapping;
import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.servercommon.annotation.ApiAbility; import com.gitee.sop.servercommon.annotation.ApiAbility;
import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.servercommon.bean.ServiceConfig; import com.gitee.sop.servercommon.bean.ServiceConfig;
import com.gitee.sop.servercommon.bean.ServiceContext;
import com.gitee.sop.servercommon.manager.RequestMappingEvent;
import org.springframework.core.PriorityOrdered; import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.StringValueResolver; import org.springframework.util.StringValueResolver;
@ -21,12 +19,6 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple
private static StringValueResolver stringValueResolver = new ApiMappingStringValueResolver(); private static StringValueResolver stringValueResolver = new ApiMappingStringValueResolver();
private RequestMappingEvent requestMappingEvent;
public ApiMappingHandlerMapping(RequestMappingEvent requestMappingEvent) {
this.requestMappingEvent = requestMappingEvent;
}
@Override @Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
ApiMapping apiMapping = method.getAnnotation(ApiMapping.class); ApiMapping apiMapping = method.getAnnotation(ApiMapping.class);
@ -83,7 +75,7 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple
apiMappingInfo.setIgnoreValidate(ignoreValidate); apiMappingInfo.setIgnoreValidate(ignoreValidate);
apiMappingInfo.setMergeResult(mergeResult); apiMappingInfo.setMergeResult(mergeResult);
apiMappingInfo.setPermission(permission); apiMappingInfo.setPermission(permission);
logger.info("注册接口,method:" + method + ", version:" + version); logger.info("注册接口,name:" + method + ", version:" + version);
return new ApiMappingRequestCondition(apiMappingInfo); return new ApiMappingRequestCondition(apiMappingInfo);
} }
@ -95,10 +87,4 @@ public class ApiMappingHandlerMapping extends RequestMappingHandlerMapping imple
} }
return apiAbility; return apiAbility;
} }
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
this.requestMappingEvent.onRegisterSuccess(this);
}
} }

@ -0,0 +1,20 @@
package com.gitee.sop.servercommon.mapping;
import org.springframework.util.StringUtils;
/**
* @author tanghc
*/
public class MappingUtil {
/**
* 将springmvc接口路径转换成SOP方法名
* @param path springmvc路径/a/b,/goods/listGoods
* @return
*/
public static String buildApiName(String path) {
path = StringUtils.trimLeadingCharacter(path, '/');
path = StringUtils.trimTrailingCharacter(path, '/');
path = path.replace("/", ".");
return path;
}
}

@ -0,0 +1,16 @@
package com.gitee.sop.servercommon.swagger;
import springfox.documentation.spring.web.plugins.DocumentationPluginsManager;
import springfox.documentation.spring.web.scanners.ApiDescriptionReader;
import springfox.documentation.spring.web.scanners.ApiListingScanner;
import springfox.documentation.spring.web.scanners.ApiModelReader;
/**
* @author tanghc
*/
public class ApiListingScannerExt extends ApiListingScanner {
public ApiListingScannerExt(ApiDescriptionReader apiDescriptionReader, ApiModelReader apiModelReader, DocumentationPluginsManager pluginsManager) {
super(apiDescriptionReader, apiModelReader, pluginsManager);
}
}

@ -0,0 +1,60 @@
package com.gitee.sop.servercommon.swagger;
import com.gitee.sop.servercommon.annotation.ApiAbility;
import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.servercommon.bean.ServiceConfig;
import com.gitee.sop.servercommon.mapping.MappingUtil;
import com.google.common.base.Optional;
import springfox.documentation.service.Operation;
import springfox.documentation.service.StringVendorExtension;
import springfox.documentation.service.VendorExtension;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spring.web.plugins.DocumentationPluginsManager;
import java.util.List;
/**
* @author tanghc
*/
public class DocumentationPluginsManagerExt extends DocumentationPluginsManager {
public static final String SOP_NAME = "sop_name";
public static final String SOP_VERSION = "sop_version";
@Override
public Operation operation(OperationContext operationContext) {
Operation operation = super.operation(operationContext);
this.setVendorExtension(operation, operationContext);
return operation;
}
private void setVendorExtension(Operation operation, OperationContext operationContext) {
List<VendorExtension> vendorExtensions = operation.getVendorExtensions();
Optional<ApiMapping> mappingOptional = operationContext.findAnnotation(ApiMapping.class);
if (mappingOptional.isPresent()) {
ApiMapping apiMapping = mappingOptional.get();
String name = apiMapping.value()[0];
String version = buildVersion(apiMapping.version());
vendorExtensions.add(new StringVendorExtension(SOP_NAME, name));
vendorExtensions.add(new StringVendorExtension(SOP_VERSION, version));
} else {
Optional<ApiAbility> abilityOptional = operationContext.findAnnotation(ApiAbility.class);
if (abilityOptional.isPresent()) {
ApiAbility apiAbility = abilityOptional.get();
String mappingPattern = operationContext.requestMappingPattern();
String name = MappingUtil.buildApiName(mappingPattern);
String version = buildVersion(apiAbility.version());
vendorExtensions.add(new StringVendorExtension(SOP_NAME, name));
vendorExtensions.add(new StringVendorExtension(SOP_VERSION, version));
}
}
}
private String buildVersion(String version) {
if ("".equals(version)) {
return ServiceConfig.getInstance().getDefaultVersion();
} else {
return version;
}
}
}

@ -0,0 +1,44 @@
package com.gitee.sop.servercommon.swagger;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
public abstract class SwaggerSupport {
protected abstract String getDocTitle();
@Bean
@Primary
public DocumentationPluginsManagerExt documentationPluginsManagerExt() {
return new DocumentationPluginsManagerExt();
}
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
protected ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(getDocTitle())
.description("文档描述")
.termsOfServiceUrl("文档")
.version("1.0")
.build();
}
}

@ -1,20 +1,15 @@
package com.gitee.app.config; package com.gitee.app.config;
import com.gitee.sop.servercommon.configuration.AlipayServiceConfiguration; import com.gitee.sop.servercommon.bean.ServiceConfig;
import org.springframework.context.annotation.Bean; import com.gitee.sop.servercommon.configuration.SpringMvcServiceConfiguration;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
/** /**
* 使用支付宝开放平台功能 * 使用支付宝开放平台功能
* *
* @author tanghc * @author tanghc
*/ */
public class OpenServiceConfig extends AlipayServiceConfiguration { public class OpenServiceConfig extends SpringMvcServiceConfiguration {
static {
@Bean ServiceConfig.getInstance().setDefaultVersion("1.0");
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return super.requestMappingHandlerMapping();
} }
} }

@ -17,6 +17,7 @@
<properties> <properties>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version> <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<swagger.version>2.9.2</swagger.version>
</properties> </properties>
<dependencies> <dependencies>
@ -39,6 +40,29 @@
<artifactId>spring-cloud-starter-openfeign</artifactId> <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency> </dependency>
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>

@ -2,10 +2,10 @@ package com.gitee.sop.bookweb.config;
import com.gitee.sop.servercommon.bean.ServiceConfig; import com.gitee.sop.servercommon.bean.ServiceConfig;
import com.gitee.sop.servercommon.configuration.AlipayServiceConfiguration; import com.gitee.sop.servercommon.configuration.AlipayServiceConfiguration;
import com.gitee.sop.servercommon.configuration.TaobaoServiceConfiguration; import com.gitee.sop.servercommon.swagger.SwaggerSupport;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import javax.annotation.PostConstruct; import springfox.documentation.swagger2.annotations.EnableSwagger2;
/** /**
* 使用支付宝开放平台功能 * 使用支付宝开放平台功能
@ -19,6 +19,24 @@ public class OpenServiceConfig extends AlipayServiceConfiguration {
ServiceConfig.getInstance().getI18nModules().add("i18n/isp/goods_error"); ServiceConfig.getInstance().getI18nModules().add("i18n/isp/goods_error");
} }
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
// 开启文档
@Configuration
@EnableSwagger2
public static class Swagger2 extends SwaggerSupport {
@Override
protected String getDocTitle() {
return "故事API";
}
}
} }
/** /**

@ -1,7 +1,10 @@
package com.gitee.sop.bookweb.controller; package com.gitee.sop.bookweb.controller;
import com.gitee.sop.bookweb.controller.param.StoryParam;
import com.gitee.sop.servercommon.annotation.ApiMapping; import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.story.api.domain.Story; import com.gitee.sop.story.api.domain.Story;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data; import lombok.Data;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -23,8 +26,9 @@ public class AlipayController {
return story; return story;
} }
@ApiOperation(value="获取故事信息", notes = "说明接口的详细信息,介绍,用途,注意事项等。")
@ApiMapping(value = "alipay.story.find") @ApiMapping(value = "alipay.story.find")
public StoryVO getStory2(Story story) { public StoryVO getStory2(StoryParam story) {
StoryVO storyVO = new StoryVO(); StoryVO storyVO = new StoryVO();
storyVO.id = 1L; storyVO.id = 1L;
storyVO.name = "白雪公主"; storyVO.name = "白雪公主";
@ -39,8 +43,11 @@ public class AlipayController {
@Data @Data
public static class StoryVO { public static class StoryVO {
@ApiModelProperty(value = "故事ID", example = "1")
private Long id; private Long id;
@ApiModelProperty(value = "故事名称", example = "海底小纵队")
private String name; private String name;
@ApiModelProperty(value = "创建时间", example = "2019-04-14 19:02:12")
private Date gmt_create; private Date gmt_create;
} }
} }

@ -3,7 +3,7 @@ package com.gitee.sop.bookweb.controller;
import com.gitee.sop.servercommon.annotation.ApiAbility; import com.gitee.sop.servercommon.annotation.ApiAbility;
import com.gitee.sop.servercommon.annotation.ApiMapping; import com.gitee.sop.servercommon.annotation.ApiMapping;
import com.gitee.sop.story.api.domain.Story; import com.gitee.sop.story.api.domain.Story;
import com.gitee.sop.story.api.service.StoryService; import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -24,6 +24,7 @@ public class Story2Controller{
} }
// 优先使用方法上@ApiAbility // 优先使用方法上@ApiAbility
@ApiOperation(value="获取故事信息2", notes = "获取故事信息2的详细信息")
@ApiAbility(version = "1.4") @ApiAbility(version = "1.4")
@RequestMapping("getStory4") @RequestMapping("getStory4")
public Story storyget() { public Story storyget() {

@ -0,0 +1,18 @@
package com.gitee.sop.bookweb.controller.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
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 = "白雪公主")
private String name;
}

@ -10,7 +10,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* 模仿支付宝客户端请求接口 * 测试是否有权限访问可在sop-admin中设置权限
*/ */
public class PermissionDemoPostTest extends TestBase { public class PermissionDemoPostTest extends TestBase {
@ -19,21 +19,6 @@ public class PermissionDemoPostTest extends TestBase {
// 支付宝私钥 // 支付宝私钥
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ="; 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=";
/**
* 参数 类型 是否必填 最大长度 描述 示例值
* app_id String 32 支付宝分配给开发者的应用ID 2014072300007148
* method String 128 接口名称 alipay.trade.fastpay.refund.query
* format String 40 仅支持JSON JSON
* charset String 10 请求使用的编码格式如utf-8,gbk,gb2312等 utf-8
* sign_type String 10 商户生成签名字符串所使用的签名算法类型目前支持RSA2和RSA推荐使用RSA2 RSA2
* sign String 344 商户请求参数的签名串详见签名 详见示例
* timestamp String 19 发送请求的时间格式"yyyy-MM-dd HH:mm:ss" 2014-07-24 03:07:50
* version String 3 调用的接口版本固定为1.0 1.0
* app_auth_token String 40 详见应用授权概述
* biz_content String 请求参数的集合最大长度不限除公共参数外所有请求参数都必须放在这个参数中传递具体参照各产品快速接入文档
*/
// 这个请求会路由到story服务
@Test @Test
public void testPost() throws Exception { public void testPost() throws Exception {

Loading…
Cancel
Save