1.移除pom.xml 里面的springdoc-openapi-starter-webmvc-ui
移除ruoyi-admin下pom.xml
<!-- spring-doc -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
移除主目录下pom.xml
<swagger.version>3.0.0</swagger.version>
<springdoc.version>2.6.0</springdoc.version>
<!-- spring-doc -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>
2.添加knife4j-openapi3-jakarta-spring-boot-starter依赖
主pom.xml里面添加
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<knife4j.version>4.4.0</knife4j.version>
ruoyi-common模块下pom.xml添加
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
3.修改application.yml 配置文件,替换原来的Springdoc配置
# Springdoc配置
springdoc:
# 配置Swagger UI的访问路径和排序方式
swagger-ui:
path: /swagger-ui.html # Swagger UI的访问路径
tags-sorter: alpha # 按字母顺序排序标签
operations-sorter: alpha # 按字母顺序排序操作
# 配置API文档的访问路径
api-docs:
path: /v3/api-docs # API文档的访问路径
# 配置API分组,用于组织和管理API
group-configs:
- group: '基础模块' # API分组名称
paths-to-match: '/**' # 匹配所有路径
packages-to-scan: com.ruoyi.web.controller.common
- group: '系统模块'
paths-to-match: '/**'
packages-to-scan: com.ruoyi.web.controller.system
- group: '系统监控'
paths-to-match: '/**'
packages-to-scan: com.ruoyi.web.controller.monitor
- group: '工具模块'
paths-to-match: '/**'
packages-to-scan: com.ruoyi.web.controller.tool
# knife4j的增强配置,不需要增强可以不配
knife4j:
enable: true
setting:
language: zh_cn
4.在SecurityConfig文件里面放行/doc.html/**, /webjars/**
@Bean
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
{
return httpSecurity
// CSRF禁用,因为不使用session
.csrf(csrf -> csrf.disable())
// 禁用HTTP响应标头
.headers((headersCustomizer) -> {
headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
})
// 认证失败处理类
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
// 基于token,所以不需要session
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// 注解标记允许匿名访问的url
.authorizeHttpRequests((requests) -> {
permitAllUrl.getUrls().forEach(url -> requests.requestMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
requests.requestMatchers("/login", "/register", "/captchaImage").permitAll()
// 静态资源,可匿名访问
.requestMatchers(HttpMethod.GET, "/", "/*.html", "/**.html", "/**.css", "/**.js", "/profile/**").permitAll()
.requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/druid/**","/doc.html/**", "/webjars/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated();
})
// 添加Logout filter
.logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler))
// 添加JWT filter
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
// 添加CORS filter
.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
.addFilterBefore(corsFilter, LogoutFilter.class)
.build();
}
5.删除原来的SwaggerConfig配置,添加Knife4jConfig
package com.ruoyi.web.core.config;
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 org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Knife4j整合Swagger3 Api接口文档配置类
*
* @author whh
*/
@Configuration
public class Knife4jConfig {
/**
* 创建了一个api接口的分组
* 除了配置文件方式创建分组,也可以通过注册bean创建分组
*/
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
// 分组名称
.group("工具模块")
// 接口请求路径规则
.pathsToMatch("/**")
.packagesToScan("com.ruoyi.web.tool")
.build();
}
/**
* 配置基本信息
*/
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info()
// 标题
.title("Knife4j整合Swagger3 Api接口文档")
// 描述Api接口文档的基本信息
.description("Knife4j后端接口服务...")
// 版本
.version("v1.0.0")
// 设置OpenAPI文档的联系信息,姓名,邮箱。
.contact(new Contact().name("Hva").email("Hva@163.com"))
// 设置OpenAPI文档的许可证信息,包括许可证名称为"Apache 2.0",许可证URL为"http://springdoc.org"。
.license(new License().name("Apache 2.0").url("http://springdoc.org"))
);
}
}
6.修改com.ruoyi.framework.config下ResourcesConfig配置
package com.ruoyi.framework.config;
import java.util.concurrent.TimeUnit;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
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 com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
/**
* 通用配置
*
* @author ruoyi
*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
@Resource
private RepeatSubmitInterceptor repeatSubmitInterceptor;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/** 本地文件上传路径 */
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
.addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
// /** swagger配置 */
// registry.addResourceHandler("/swagger-ui/**")
// .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
// .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());
//
//配置 knife4j 的静态资源请求映射地址
registry.addResourceHandler("/doc.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
/**
* 自定义拦截规则
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
}
/**
* 跨域配置
*/
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 设置访问源地址
config.addAllowedOriginPattern("*");
// 设置访问源请求头
config.addAllowedHeader("*");
// 设置访问源请求方法
config.addAllowedMethod("*");
// 有效期 1800秒
config.setMaxAge(1800L);
// 添加映射路径,拦截一切请求
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
// 返回新的CorsFilter
return new CorsFilter(source);
}
}
7.访问http://localhost:8080/doc.html
注意:添加新模块的文档有两种方式
1.是通过在配置文件application.yml里面继续添加 group-configs 就行了
2.是通过在Knife4jConfig文件里面添加新的GroupedOpenApi的bean就行,一个GroupedOpenApi就是一个模块的文档配置。
3.但是千万要注意,两种配置方式不能冲突,不然会启动报错的。
8.给文档设置全局token
1.首先你需要拿到token,如果你的登录相关的接口也在文档中,可以直接通过文档获取,如果没有可以使用postman,apifox等接口工具获取token
2.在knife4j的文档管理里面有一个全局参数设置,在里面添加一个全局的请求头就行了,添加后点击测试接口,如果还没有权限就点击一下这个接口的重置按钮,或者关闭这个接口重新打开,如果还是不行,就需要检查一下你这个这个请求头的名字和你系统的是否对得上,以及你的token是否正确并且有效。
注意:这个全局参数是只在这个模块生效,切换模块或者系统重启后这个全局参数都需要重新设置。还有这个token一般都是 Bearer + 空格 + 实际的token 组成的。
9.踩坑
当前最新knife4j-openapi3-jakarta-spring-boot-starter版本是4.5.0,它依赖于springboot的3.3.x版本,如果你把spring-boot-dependencies升级到3.4.x或者3.5.x,在访问页面knife4j页面的时候会报错。