swagger相关依赖:
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
<!-- swaggwe增强ui -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
swagger相关配置类:
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import io.swagger.annotations.Api;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfiguration {
/**
* 配置api接口生成插件swagger
* 测试环境在线文档地址:....../doc.html
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("xx系统")
.apiInfo(apiInfo())
.useDefaultResponseMessages(false) // 不生成默认的响应码
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("xx系统接口说明")
.version("1.0")
.build();
}
}
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.google.common.base.Optional;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin;
import springfox.documentation.spi.schema.contexts.ModelPropertyContext;
import springfox.documentation.swagger.common.SwaggerPluginSupport;
import java.lang.reflect.Field;
import static springfox.documentation.schema.Annotations.findPropertyAnnotation;
import static springfox.documentation.swagger.schema.ApiModelProperties.findApiModePropertyAnnotation;
/**
* @ApiModelProperty注解 默认按照字段定义顺序排序
*/
@Slf4j
@Component
public class CustomApiModelPropertyPositionBuilder implements ModelPropertyBuilderPlugin {
@Override
public void apply(ModelPropertyContext context) {
Optional<BeanPropertyDefinition> beanPropertyDefinitionOpt = context.getBeanPropertyDefinition();
if (!beanPropertyDefinitionOpt.isPresent()) {
return;
}
// 获取注解信息
Optional<ApiModelProperty> annotation = getAnnotation(context);
if (!annotation.isPresent() || annotation.get().position() != 0) {
return;
}
// 获取字段和类信息
AnnotatedField currentField = beanPropertyDefinitionOpt.get().getField();
Field[] declaredFields = currentField.getDeclaringClass().getDeclaredFields();
// 获取字段的定义顺序
int index = indexOf(declaredFields, currentField);
if (index != -1) {
// 设置position属性 context.getSpecificationBuilder().position(indexOf)
context.getBuilder().position(index);
}
}
@Override
public boolean supports(DocumentationType delimiter) {
return SwaggerPluginSupport.pluginDoesApply(delimiter);
}
/**
* 获取注解信息
*/
private Optional<ApiModelProperty> getAnnotation(ModelPropertyContext context) {
if (context.getAnnotatedElement().isPresent()) {
return findApiModePropertyAnnotation(context.getAnnotatedElement().get());
}
if (context.getBeanPropertyDefinition().isPresent()) {
return findPropertyAnnotation(context.getBeanPropertyDefinition().get(), ApiModelProperty.class);
}
return Optional.absent();
}
/**
* 获取字段的序号
*/
private int indexOf(Field[] declaredFields, AnnotatedField field) {
for (int i = 0; i < declaredFields.length; i++) {
if (declaredFields[i].getName().equals(field.getName())) {
return i;
}
}
return -1;
}