这里介绍如何配置Swagger 3.0和Knife4j 3.0版本,强烈建议大家使用Knife4j,因为它的前身是swagger-bootstrap-ui,是在Swagger的基础上进行了界面的优化,使用起来比Swagger舒服了太多
使用 swagger3 注解代替 swagger2 的(可选)
这一步是可选的,因为改动太大,故 springfox对旧版的 swagger做了兼容处理。
但不知道未来会不会不兼容,这里列出如何用 swagger 3 的注解(已经在上面引入)代替 swagger 2 的
(注意修改 swagger 3 注解的包路径为io.swagger.v3.oas.annotations.)
对应关系为:
swagger2 | OpenAPI 3 | 注解位置 |
---|---|---|
@Api |
@Tag(name = “接口类描述”) | Controller 类上 |
@ApiOperation |
@Operation(summary =“接口方法描述”) | Controller 方法上 |
@ApiImplicitParams |
@Parameters | Controller 方法上 |
@ApiImplicitParam |
@Parameter(description=“参数描述”) | Controller 方法上 @Parameters 里 |
@ApiParam |
@Parameter(description=“参数描述”) | Controller 方法的参数上 |
@ApiIgnore |
@Parameter(hidden = true) 或 @Operation(hidden = true) 或 @Hidden | - |
@ApiModel |
@Schema | DTO类上 |
@ApiModelProperty |
@Schema | DTO属性上 |
io.springfox
springfox-boot-starter
3.0.0
com.github.xiaoymin
knife4j-spring-boot-starter
3.0.3
org.springframework.boot
spring-boot-configuration-processor
true
代码如下:
package com.liu.news.config;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.RequestParameterBuilder;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.schema.ScalarType;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
@Slf4j
@Configuration
@EnableAutoConfiguration
@EnableOpenApi//开启swagger,当前版本为3 所以注解和2@EnableSwagger2的版本不同
//或者直接省略prefix,那么直接写为swagger.enabled,当配置中存在swagger.enabled生效,matchIfMissing = true默认生效
@ConditionalOnProperty(prefix = "swagger",name = "enabled", matchIfMissing = true)
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerAutoConfig {
//默认的排除路径,排除Spring Boot默认的错误处理路径和端点(在解析的url规则之上) /*/error,由于服务通常加前缀,所以前面/*忽略前缀
private static final List DEFAULT_EXCLUDE_PATH = Arrays.asList("/error","/actuator/**","/*/error");
//swagger会解析的url规则
private static final String BASE_PATH = "/**";
@Autowired
private SwaggerProperties swaggerProperties;
@Bean
public Docket createRestApi() {
// base-path处理
if (swaggerProperties.getBasePath().isEmpty()) {
swaggerProperties.getBasePath().add(BASE_PATH);
}
// exclude-path处理
if (swaggerProperties.getExcludePath().isEmpty()) {
swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH);
}
//需要排除的url
List> excludePath = new ArrayList<>();
swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
// 版本请求头处理
List pars = new ArrayList<>();
RequestParameterBuilder versionPar = new RequestParameterBuilder().description("灰度路由版本信息")
.in(ParameterType.HEADER).name("VERSION").required(false)
.query(param -> param.model(model -> model.scalarModel(ScalarType.STRING)));
pars.add(versionPar.build());
ApiSelectorBuilder builder = new Docket(DocumentationType.OAS_30)
.host(swaggerProperties.getHost())
.apiInfo(apiInfo()).globalRequestParameters(pars)
.select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()));
swaggerProperties.getBasePath().forEach(p -> builder.paths(PathSelectors.ant(p)));
swaggerProperties.getExcludePath().forEach(p -> builder.paths(PathSelectors.ant(p).negate()));
return builder.build().securitySchemes(Collections.singletonList(securitySchema()))
.securityContexts(Collections.singletonList(securityContext())).pathMapping("/");
}
/**
* 配置默认的全局鉴权策略的开关,通过正则表达式进行匹配;默认匹配所有URL
* @return
*/
private SecurityContext securityContext() {
return SecurityContext.builder().securityReferences(defaultAuth()).build();
}
/**
* 默认的全局鉴权策略
* @return
*/
private List defaultAuth() {
ArrayList authorizationScopeList = new ArrayList<>();
swaggerProperties.getAuthorization().getAuthorizationScopeList()
.forEach(authorizationScope -> authorizationScopeList.add(
new AuthorizationScope(authorizationScope.getScope(), authorizationScope.getDescription())));
AuthorizationScope[] authorizationScopes = new AuthorizationScope[authorizationScopeList.size()];
return Collections
.singletonList(SecurityReference.builder().reference(swaggerProperties.getAuthorization().getName())
.scopes(authorizationScopeList.toArray(authorizationScopes)).build());
}
private OAuth securitySchema() {
ArrayList authorizationScopeList = new ArrayList<>();
swaggerProperties.getAuthorization().getAuthorizationScopeList()
.forEach(authorizationScope -> authorizationScopeList.add(
new AuthorizationScope(authorizationScope.getScope(), authorizationScope.getDescription())));
ArrayList grantTypes = new ArrayList<>();
swaggerProperties.getAuthorization().getTokenUrlList()
.forEach(tokenUrl -> grantTypes.add(new ResourceOwnerPasswordCredentialsGrant(tokenUrl)));
return new OAuth(swaggerProperties.getAuthorization().getName(), authorizationScopeList, grantTypes);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(swaggerProperties.getTitle())
.description(swaggerProperties.getDescription())
.version(swaggerProperties.getVersion())
.license(swaggerProperties.getLicense())
.licenseUrl(swaggerProperties.getLicenseUrl())
.termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
.contact(new Contact(
swaggerProperties.getContact().getName(),
swaggerProperties.getContact().getUrl(),
swaggerProperties.getContact().getEmail()
))
.build();
}
}
package com.liu.news.config;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @description: 映射配置文件Swagger基本属性
*/
@Data
@Configuration
@Component
@ConfigurationProperties("swagger")
public class SwaggerProperties {
/**
* 是否开启swagger
*/
private Boolean enabled;
/**
* swagger会解析的包路径
**/
private String basePackage = "";
/**
* swagger会解析的url规则
**/
private List basePath = new ArrayList<>();
/**
* 在basePath基础上需要排除的url规则
**/
private List excludePath = new ArrayList<>();
/**
* 需要排除的服务
*/
private List ignoreProviders = new ArrayList<>();
/**
* 标题
**/
private String title = "";
/**
* 描述
**/
private String description = "";
/**
* 版本
**/
private String version = "";
/**
* 许可证
**/
private String license = "";
/**
* 许可证URL
**/
private String licenseUrl = "";
/**
* 服务条款URL
**/
private String termsOfServiceUrl = "";
/**
* host信息
**/
private String host = "";
/**
* 联系人信息
*/
private Contact contact = new Contact();
/**
* 全局统一鉴权配置
**/
private Authorization authorization = new Authorization();
@Data
@NoArgsConstructor
public static class Contact {
/**
* 联系人
**/
private String name = "";
/**
* 联系人url
**/
private String url = "";
/**
* 联系人email
**/
private String email = "";
}
@Data
@NoArgsConstructor
public static class Authorization {
/**
* 鉴权策略ID,需要和SecurityReferences ID保持一致
*/
private String name = "";
/**
* 需要开启鉴权URL的正则
*/
private String authRegex = "^.*$";
/**
* 鉴权作用域列表
*/
private List authorizationScopeList = new ArrayList<>();
private List tokenUrlList = new ArrayList<>();
}
@Data
@NoArgsConstructor
public static class AuthorizationScope {
/**
* 作用域名称
*/
private String scope = "";
/**
* 作用域描述
*/
private String description = "";
}
}
swagger:
title: artical-api
description: "文章服务"
version: 1.0
license: "www"
licenseUrl: http://baidu.com
terms-of-service-url: http://baidu.com
contact:
name: liu
email: 11111
url: http://baidu.com
authorization:
name: OAuth
auth-regex: ^.*$
authorization-scope-list:
- scope: server
description: server all
token-url-list:
- http://${GATEWAY_HOST:localhost}:${GATEWAY-PORT:5000}/auth/oauth/token
pom中已经引入了jar包
配置文件中加入swagger配置就可以
代码如下
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动包
url: jdbc:mysql://localhost:3307/artical?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
username: root
password: root
mybatis-plus:
global-config:
db-config:
field-strategy: not_empty
#驼峰下划线转换
column-underline: true
#逻辑删除配置
logic-delete-value: 0
logic-not-delete-value: 1
db-type: mysql
refresh: false
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
management:
server:
port: 9003
security:
enabled: false
user: user-prompt-info.yml
swagger:
title: artical-api
description: "文章服务"
version: 1.0
license: "www"
licenseUrl: http://baidu.com
terms-of-service-url: http://baidu.com
contact:
name: liu
email: 11111
url: http://baidu.com
swagger:
title: artical-api
description: "文章服务"
version: 1.0
license: "www"
licenseUrl: http://baidu.com
terms-of-service-url: http://baidu.com
contact:
name: liu
email: 11111
url: http://baidu.com
authorization:
name: OAuth
auth-regex: ^.*$
authorization-scope-list:
- scope: server
description: server all
token-url-list:
- http://${GATEWAY_HOST:localhost}:${GATEWAY-PORT:5000}/auth/oauth/token
访问网址
http://localhost:9070/swagger-ui/index.html
knife4j 访问 http://localhost:9070/doc.html