首先要查看项目中pom文件里面有没有swagger和knife4j的依赖,如果有的话删除,加入以下依赖
<!-- swagger --> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-spring-boot-starter</artifactId> <version>${knife4j.version}</version> <exclusions> <exclusion> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-webmvc-core</artifactId> </exclusion> <exclusion> <groupId>io.springfox</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>${springdoc.version}</version> </dependency> </dependencies>
然后在下面文件中加入配置初始化语句:
编辑
#################### æ¥å£ææ¡£é ç½® #################### springdoc.api-docs.enabled= true springdoc.api-docs.path= /v3/api-docs springdoc.swagger-ui.enabled= true springdoc.swagger-ui.path= /swagger-ui springdoc.default-flat-param-object= true knife4j.enable= false knife4j.setting.language= zh_cn
新建swagger的config类,内容如下:
编辑
SwaggerProperties
package com.todod.config.swagger; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import javax.validation.constraints.NotEmpty; /** * Swagger 配置属性 * * @author admin */ @ConfigurationProperties("base.swagger") @Data public class SwaggerProperties { /** * 标题 */ @NotEmpty(message = "标题不能为空") private String title; /** * 描述 */ @NotEmpty(message = "描述不能为空") private String description; /** * 作者 */ @NotEmpty(message = "作者不能为空") private String author; /** * 版本 */ @NotEmpty(message = "版本不能为空") private String version; /** * url */ @NotEmpty(message = "扫描的 package 不能为空") private String url; /** * email */ @NotEmpty(message = "扫描的 email 不能为空") private String email; /** * license */ @NotEmpty(message = "扫描的 license 不能为空") private String license; /** * license-url */ @NotEmpty(message = "扫描的 license-url 不能为空") private String licenseUrl; }
BaseSwaggerAutoConfiguration
package com.todod.config.swagger; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import io.swagger.v3.oas.models.media.IntegerSchema; import io.swagger.v3.oas.models.media.StringSchema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import org.springdoc.core.*; import org.springdoc.core.customizers.OpenApiBuilderCustomizer; import org.springdoc.core.customizers.ServerBaseUrlCustomizer; import org.springdoc.core.providers.JavadocProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.HttpHeaders; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; /** * Swagger 自动配置类,基于 OpenAPI + Springdoc 实现。 * * 友情提示: * 1. Springdoc 文档地址:<a href="https://github.com/springdoc/springdoc-openapi">仓库</a> * 2. Swagger 规范,于 2015 更名为 OpenAPI 规范,本质是一个东西 * * @author admin */ @Configuration @ConditionalOnClass({OpenAPI.class}) @EnableConfigurationProperties(SwaggerProperties.class) @ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true) // 设置为 false 时,禁用 public class BaseSwaggerAutoConfiguration { public static final String HEADER_TENANT_ID = "tenant-id"; // ========== 全局 OpenAPI 配置 ========== @Bean public OpenAPI createApi(SwaggerProperties properties) { Map<String, SecurityScheme> securitySchemas = buildSecuritySchemes(); OpenAPI openAPI = new OpenAPI() // 接口信息 .info(buildInfo(properties)) // 接口安全配置 .components(new Components().securitySchemes(securitySchemas)) .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION)); securitySchemas.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key))); return openAPI; } /** * API 摘要信息 */ private Info buildInfo(SwaggerProperties properties) { return new Info() .title(properties.getTitle()) .description(properties.getDescription()) .version(properties.getVersion()) .contact(new Contact().name(properties.getAuthor()).url(properties.getUrl()).email(properties.getEmail())) .license(new License().name(properties.getLicense()).url(properties.getLicenseUrl())); } /** * 安全模式,这里配置通过请求头 Authorization 传递 token 参数 */ private Map<String, SecurityScheme> buildSecuritySchemes() { Map<String, SecurityScheme> securitySchemes = new HashMap<>(); SecurityScheme securityScheme = new SecurityScheme() .type(SecurityScheme.Type.APIKEY) // 类型 .name(HttpHeaders.AUTHORIZATION) // 请求头的 name .in(SecurityScheme.In.HEADER); // token 所在位置 securitySchemes.put(HttpHeaders.AUTHORIZATION, securityScheme); return securitySchemes; } /** * 自定义 OpenAPI 处理器 */ @Bean @Primary // 目的:以我们创建的 OpenAPIService Bean 为主,避免一键改包后,启动报错! public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI, SecurityService securityParser, SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils, Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers, Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers, Optional<JavadocProvider> javadocProvider) { return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider); } // ========== 分组 OpenAPI 配置 ========== /** * 所有模块的 API 分组 */ @Bean public GroupedOpenApi allGroupedOpenApi() { return buildGroupedOpenApi("all", ""); } public static GroupedOpenApi buildGroupedOpenApi(String group) { return buildGroupedOpenApi(group, group); } public static GroupedOpenApi buildGroupedOpenApi(String group, String path) { return GroupedOpenApi.builder() .group(group) .pathsToMatch("/admin-api/" + path + "/**", "/" + path + "/**") .addOperationCustomizer((operation, handlerMethod) -> operation .addParametersItem(buildTenantHeaderParameter()) .addParametersItem(buildSecurityHeaderParameter())) .build(); } /** * 构建 Tenant 租户编号请求头参数 * * @return 多租户参数 */ private static Parameter buildTenantHeaderParameter() { return new Parameter() .name(HEADER_TENANT_ID) // header 名 .description("租户编号") // 描述 .in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header .schema(new IntegerSchema()._default(1L).name(HEADER_TENANT_ID).description("租户编号")); // 默认:使用租户编号为 1 } /** * 构建 Authorization 认证请求头参数 * * 解决 Knife4j <a href="https://gitee.com/xiaoym/knife4j/issues/I69QBU">Authorize 未生效,请求header里未包含参数</a> * * @return 认证参数 */ private static Parameter buildSecurityHeaderParameter() { return new Parameter() .name(HttpHeaders.AUTHORIZATION) // header 名 .description("认证 Token") // 描述 .in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header .schema(new StringSchema()._default("Bearer test1").name(HEADER_TENANT_ID).description("认证 Token")); // 默认:使用用户编号为 1 } }
新建WebAppConfig类来控制./doc.html可以访问
编辑
代码如下:
package com.todod.config; import com.todod.interceptor.LoginInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.http.CacheControl; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.concurrent.TimeUnit; @Configuration public class WebAppConfig implements WebMvcConfigurer { @Value("${file.upload.path}") private String uploadPath; // 文件路径 @Value("${file.upload.mapping}") private String showPath; // 映射路径 @Autowired private LoginInterceptor loginInterceptor; /** * interceptor配置 */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) // 添加需要验证登录用户操作权限的请求 .addPathPatterns("/**") // 排除不需要验证登录用户操作权限的请求 .excludePathPatterns("/user/login/**", "/user/logout/**","/apiDemo/doGet/**","/ltcloud/user/getAllUser","/ltcloud/frequency/getFrequencyById","/empower/**"); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String a = showPath + "**"; String b = "file:" + uploadPath; registry.addResourceHandler(a) .addResourceLocations(b). setCacheControl(CacheControl.maxAge(2, TimeUnit.DAYS)); registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } }
前端:
<template> <div> <i-frame v-if="!loading" :src="url" /> </div> </template> <script> import iFrame from "@/components/iFrame/index"; import { getConfigKey } from "@/api/infra/config"; export default { name: "InfraSwagger", components: { iFrame }, data() { return { url: process.env.VUE_APP_BASE_API + "doc.html", // Knife4j UI loading: true }; }, created() { this.url =process.env.VUE_APP_BASE_API + "doc.html" this.loading = false; } }; </script>
到此配置完毕,范围localhost:后端端口/doc.html
注:
1.BaseSwaggerAutoConfiguration类中的buildGroupedOpenApi方法可以控制显示哪些controller里的接口:
public static GroupedOpenApi buildGroupedOpenApi(String group, String path) { return GroupedOpenApi.builder() .group(group) .pathsToMatch("/admin-api/" + path + "/**", "/" + path + "/**") .addOperationCustomizer((operation, handlerMethod) -> operation .addParametersItem(buildTenantHeaderParameter()) .addParametersItem(buildSecurityHeaderParameter())) .build(); }
编辑
2.在controller上面加tag注解可以给controller接口起名字,改变英文显示
编辑
operation则会改变接口的名字
编辑