支持swagger排序

pull/3/head
tanghc 4 years ago
parent 57c8f34c3b
commit 199cb67fa3
  1. 6
      pom.xml
  2. 2
      sop-common/sop-service-common/pom.xml
  3. 20
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/CustomModelToSwaggerMapper.java
  4. 127
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/CustomSwaggerParameterBuilder.java
  5. 8
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/DocumentationPluginsManagerExt.java
  6. 16
      sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/swagger/SwaggerSupport.java
  7. 4
      sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/Example1001_BaseController.java
  8. 5
      sop-example/sop-story/src/main/java/com/gitee/sop/storyweb/controller/param/StoryParam.java
  9. 4
      sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocItem.java
  10. 3
      sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java
  11. 1947
      sop-website/src/main/resources/api.json

@ -65,6 +65,7 @@
<guava.version>27.1-jre</guava.version> <guava.version>27.1-jre</guava.version>
<swagger.version>1.5.21</swagger.version> <swagger.version>1.5.21</swagger.version>
<springfox-spring-web.version>2.9.2</springfox-spring-web.version> <springfox-spring-web.version>2.9.2</springfox-spring-web.version>
<springfox-swagger2.version>2.9.2</springfox-swagger2.version>
<easyopen.version>1.16.9</easyopen.version> <easyopen.version>1.16.9</easyopen.version>
</properties> </properties>
@ -121,6 +122,11 @@
<artifactId>swagger-annotations</artifactId> <artifactId>swagger-annotations</artifactId>
<version>${swagger.version}</version> <version>${swagger.version}</version>
</dependency> </dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger2.version}</version>
</dependency>
<dependency> <dependency>
<groupId>net.oschina.durcframework</groupId> <groupId>net.oschina.durcframework</groupId>

@ -60,7 +60,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId> <artifactId>springfox-swagger2</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>

@ -0,0 +1,20 @@
package com.gitee.sop.servercommon.swagger;
import io.swagger.models.parameters.Parameter;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2MapperImpl;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class CustomModelToSwaggerMapper extends ServiceModelToSwagger2MapperImpl {
@Override
protected List<Parameter> parameterListToParameterList(List<springfox.documentation.service.Parameter> list) {
// list需要根据order|postion排序
list = list.stream()
.sorted(Comparator.comparingInt(springfox.documentation.service.Parameter::getOrder))
.collect(Collectors.toList());
return super.parameterListToParameterList(list);
}
}

@ -0,0 +1,127 @@
package com.gitee.sop.servercommon.swagger;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiParam;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.service.AllowableListValues;
import springfox.documentation.service.AllowableValues;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.EnumTypeDeterminer;
import springfox.documentation.spi.service.ExpandedParameterBuilderPlugin;
import springfox.documentation.spi.service.contexts.ParameterExpansionContext;
import springfox.documentation.spring.web.DescriptionResolver;
import springfox.documentation.swagger.common.SwaggerPluginSupport;
import springfox.documentation.swagger.readers.parameter.Examples;
import springfox.documentation.swagger.schema.ApiModelProperties;
import java.util.Arrays;
import java.util.List;
import static springfox.documentation.swagger.common.SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER;
/**
* Created by wujie on 2019/2/16.
* 自定义ExpandedParameterBuilderPlugin主要是修正源码query传入请求参数postion无效
* 这里将postion赋值给order
*
* https://blog.csdn.net/qq_38316721/article/details/103908793
*/
public class CustomSwaggerParameterBuilder implements ExpandedParameterBuilderPlugin {
private final DescriptionResolver descriptions;
private final EnumTypeDeterminer enumTypeDeterminer;
public CustomSwaggerParameterBuilder(
DescriptionResolver descriptions,
EnumTypeDeterminer enumTypeDeterminer) {
this.descriptions = descriptions;
this.enumTypeDeterminer = enumTypeDeterminer;
}
@Override
public void apply(ParameterExpansionContext context) {
Optional<ApiModelProperty> apiModelPropertyOptional = context.findAnnotation(ApiModelProperty.class);
if (apiModelPropertyOptional.isPresent()) {
fromApiModelProperty(context, apiModelPropertyOptional.get());
}
Optional<ApiParam> apiParamOptional = context.findAnnotation(ApiParam.class);
if (apiParamOptional.isPresent()) {
fromApiParam(context, apiParamOptional.get());
}
}
@Override
public boolean supports(DocumentationType delimiter) {
return SwaggerPluginSupport.pluginDoesApply(delimiter);
}
private void fromApiParam(ParameterExpansionContext context, ApiParam apiParam) {
String allowableProperty = Strings.emptyToNull(apiParam.allowableValues());
AllowableValues allowable = allowableValues(
Optional.fromNullable(allowableProperty),
context.getFieldType().getErasedType());
maybeSetParameterName(context, apiParam.name())
.description(descriptions.resolve(apiParam.value()))
.defaultValue(apiParam.defaultValue())
.required(apiParam.required())
.allowMultiple(apiParam.allowMultiple())
.allowableValues(allowable)
.parameterAccess(apiParam.access())
.hidden(apiParam.hidden())
.scalarExample(apiParam.example())
.complexExamples(Examples.examples(apiParam.examples()))
.order(SWAGGER_PLUGIN_ORDER)
.build();
}
private void fromApiModelProperty(ParameterExpansionContext context, ApiModelProperty apiModelProperty) {
String allowableProperty = Strings.emptyToNull(apiModelProperty.allowableValues());
AllowableValues allowable = allowableValues(
Optional.fromNullable(allowableProperty),
context.getFieldType().getErasedType());
maybeSetParameterName(context, apiModelProperty.name())
.description(descriptions.resolve(apiModelProperty.value()))
.required(apiModelProperty.required())
.allowableValues(allowable)
.parameterAccess(apiModelProperty.access())
.hidden(apiModelProperty.hidden())
.scalarExample(apiModelProperty.example())
//源码这里是: SWAGGER_PLUGIN_ORDER,需要修正
.order(apiModelProperty.position())
.build();
}
private ParameterBuilder maybeSetParameterName(ParameterExpansionContext context, String parameterName) {
if (!Strings.isNullOrEmpty(parameterName)) {
context.getParameterBuilder().name(parameterName);
}
return context.getParameterBuilder();
}
private AllowableValues allowableValues(final Optional<String> optionalAllowable, Class<?> fieldType) {
AllowableValues allowable = null;
if (enumTypeDeterminer.isEnum(fieldType)) {
allowable = new AllowableListValues(getEnumValues(fieldType), "LIST");
} else if (optionalAllowable.isPresent()) {
allowable = ApiModelProperties.allowableValueFromString(optionalAllowable.get());
}
return allowable;
}
private List<String> getEnumValues(final Class<?> subject) {
return Lists.transform(Arrays.asList(subject.getEnumConstants()), new Function<Object, String>() {
@Override
public String apply(final Object input) {
return input.toString();
}
});
}
}

@ -4,6 +4,7 @@ import com.gitee.sop.servercommon.annotation.Open;
import com.gitee.sop.servercommon.bean.ServiceConfig; import com.gitee.sop.servercommon.bean.ServiceConfig;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import springfox.documentation.service.Operation; import springfox.documentation.service.Operation;
import springfox.documentation.service.StringVendorExtension; import springfox.documentation.service.StringVendorExtension;
@ -21,6 +22,7 @@ public class DocumentationPluginsManagerExt extends DocumentationPluginsManager
private static final String SOP_NAME = "sop_name"; private static final String SOP_NAME = "sop_name";
private static final String SOP_VERSION = "sop_version"; private static final String SOP_VERSION = "sop_version";
private static final String MODULE_ORDER = "module_order"; private static final String MODULE_ORDER = "module_order";
private static final String API_ORDER = "api_order";
@Override @Override
public Operation operation(OperationContext operationContext) { public Operation operation(OperationContext operationContext) {
@ -50,6 +52,12 @@ public class DocumentationPluginsManagerExt extends DocumentationPluginsManager
} }
} }
vendorExtensions.add(new StringVendorExtension(MODULE_ORDER, String.valueOf(order))); vendorExtensions.add(new StringVendorExtension(MODULE_ORDER, String.valueOf(order)));
Optional<ApiOperation> apiOperationOptional = operationContext.findAnnotation(ApiOperation.class);
int methodOrder = 0;
if (apiOperationOptional.isPresent()) {
methodOrder = apiOperationOptional.get().position();
}
vendorExtensions.add(new StringVendorExtension(API_ORDER, String.valueOf(methodOrder)));
} }
private String buildVersion(String version) { private String buildVersion(String version) {

@ -8,6 +8,8 @@ import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo; import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.EnumTypeDeterminer;
import springfox.documentation.spring.web.DescriptionResolver;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
/** /**
@ -27,6 +29,20 @@ public abstract class SwaggerSupport {
return new DocumentationPluginsManagerExt(); return new DocumentationPluginsManagerExt();
} }
@Bean
@Primary
public CustomModelToSwaggerMapper customModelToSwaggerMapper() {
return new CustomModelToSwaggerMapper();
}
@Bean
@Primary
public CustomSwaggerParameterBuilder customSwaggerParameterBuilder(
DescriptionResolver descriptions,
EnumTypeDeterminer enumTypeDeterminer) {
return new CustomSwaggerParameterBuilder(descriptions, enumTypeDeterminer);
}
@Bean @Bean
public Docket createRestApi() { public Docket createRestApi() {
return getDocket(); return getDocket();

@ -41,7 +41,7 @@ public class Example1001_BaseController {
} }
// 基础用法 // 基础用法
@ApiOperation(value = "获取故事信息", notes = "获取故事信息的详细信息") @ApiOperation(value = "获取故事信息(首位)", notes = "获取故事信息的详细信息", position = -100/* position默认0,值越小越靠前 */)
@Open("story.get") @Open("story.get")
@RequestMapping("/get/v1") @RequestMapping("/get/v1")
public StoryResult get_v1(StoryParam param) { public StoryResult get_v1(StoryParam param) {
@ -81,7 +81,7 @@ public class Example1001_BaseController {
} }
// 返回数组结果 // 返回数组结果
@ApiOperation(value = "返回数组结果", notes = "返回数组结果") @ApiOperation(value = "返回数组结果(第二)", notes = "返回数组结果", position = -99)
@Open("story.list") @Open("story.list")
@RequestMapping("/list/v1") @RequestMapping("/list/v1")
public List<StoryResult> getStory3(StoryParam story) { public List<StoryResult> getStory3(StoryParam story) {

@ -13,6 +13,9 @@ public class StoryParam {
@NotBlank(message = "name不能为空") @NotBlank(message = "name不能为空")
@Length(max = 20, message = "name长度不能超过20") @Length(max = 20, message = "name长度不能超过20")
@ApiModelProperty(value = "故事名称", required = true, example = "白雪公主") @ApiModelProperty(value = "故事名称", required = true, example = "白雪公主", position = 3)
private String name; private String name;
@ApiModelProperty(value = "备注 (第二)", example = "xx", position = 2)
private String remark;
} }

@ -22,8 +22,12 @@ public class DocItem {
private Collection<String> produces; private Collection<String> produces;
/** 模块顺序 */
private int moduleOrder; private int moduleOrder;
/** 文档顺序 */
private int apiOrder;
List<DocParameter> requestParameters; List<DocParameter> requestParameters;
List<DocParameter> responseParameters; List<DocParameter> responseParameters;

@ -61,7 +61,7 @@ public class SwaggerDocParser implements DocParser {
} }
} }
docItems.sort(Comparator.comparing(DocItem::getNameVersion)); docItems.sort(Comparator.comparing(DocItem::getApiOrder).thenComparing(DocItem::getNameVersion));
List<DocModule> docModuleList = docItems.stream() List<DocModule> docModuleList = docItems.stream()
.collect(Collectors.groupingBy(DocItem::getModule)) .collect(Collectors.groupingBy(DocItem::getModule))
@ -122,6 +122,7 @@ public class SwaggerDocParser implements DocParser {
docItem.setMultiple(docInfo.getString("multiple") != null); docItem.setMultiple(docInfo.getString("multiple") != null);
docItem.setProduces(docInfo.getJSONArray("produces").toJavaList(String.class)); docItem.setProduces(docInfo.getJSONArray("produces").toJavaList(String.class));
docItem.setModuleOrder(NumberUtils.toInt(docInfo.getString("module_order"), 0)); docItem.setModuleOrder(NumberUtils.toInt(docInfo.getString("module_order"), 0));
docItem.setApiOrder(NumberUtils.toInt(docInfo.getString("api_order"), 0));
String moduleName = this.buildModuleName(docInfo, docRoot); String moduleName = this.buildModuleName(docInfo, docRoot);
docItem.setModule(moduleName); docItem.setModule(moduleName);
List<DocParameter> docParameterList = this.buildRequestParameterList(docInfo, docRoot); List<DocParameter> docParameterList = this.buildRequestParameterList(docInfo, docRoot);

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save