springboot2.6.3整合knife4j 3.0.3

背景

最近由于项目使用的swaggerui存在查找接口不方便,ui不美观等问题,决定使用基于swagger的knife4j替换swagger ui,从swagger ui升级到knife4j极其简单,官方效果如下:
https://doc.xiaominfo.com/demo/doc.html
knife4j官方效果

目标

搭建knife4j在线接口文档,并且支持在线调试,下载接口文档到本地,直在dev环境引入knife4j依赖,其余环境不引入。

过程

  1. 通过maven profile特性在dev环境引入knife4j依赖
<profiles>
        <profile>
            <id>dev</id>
            <properties>
                <!-- 环境标识,需要与配置文件的名称相对应 -->
                <profiles.active>dev</profiles.active>
                <revision>1.0.0-SNAPSHOT</revision>
            </properties>
            <dependencies>
                <!--               dev才加入在线文档依赖 -->
                <dependency>
                    <groupId>com.github.xiaoymin</groupId>
                    <artifactId>knife4j-spring-boot-starter</artifactId>
                    <version>3.0.3</version>
                </dependency>
            </dependencies>
        </profile>
    </profiles>

maven打包需指定profile,如mvn clean package -Pdev -Dmaven.test.skip=true
2. dev 配置文件配置

spring:
# swagger问题修复
    mvc:
        pathmatch:
            matching-strategy: ant_path_matcher
# Swagger配置
swagger:
    # 是否开启swagger
    enabled: true
    # 请求前缀
    pathMapping: /dev-api
knife4j:
    enable: true
    setting:
        enableDebug: true
  1. idea指定profile为dev
    在这里插入图片描述
  2. 配置knife4j支持经由网关访问并且调试,网关地址映射/dev-api => /admin
    • 配置前:
      在这里插入图片描述
  • 配置代码
@Configuration
@ConditionalOnProperty(name = "swagger.enabled", havingValue = "true")
public class SwaggerConfig
{
    @Value("${server.servlet.context-path:}")
    private String contextPath;

    @Bean
    public Docket defaultApi(Environment evn) {
    	//接口地址前缀,如/api
        String pathMapping = evn.getProperty("swagger.pathMapping");

        Docket docket = new Docket(DocumentationType.OAS_30)
            .enable(true)
            .apiInfo(new ApiInfoBuilder()
                .title("在线swagger接口文档")
                .contact(new Contact("xxx", "", ""))
                .description("前端对接使用")
                .build())
            .select()
            //只收集带有swagger注解的
            .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
            .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
            //指定Controller扫描包路径
            .apis(RequestHandlerSelectors.basePackage("com.xx.xx.controller"))
            .paths(PathSelectors.any())
            .build()
            /* 设置安全模式,swagger可以设置访问token */
            .securitySchemes(securitySchemes())
            .securityContexts(securityContexts())
            .pathMapping(pathMapping)
            //用了网关地址重写,需要去除server.servlet.context-path设置的地址前缀,换成网关的/dev-api前缀
            .pathProvider(new CustomerPathProvider());

        return docket;
    }
    /**
     * 安全模式,这里指定token通过Authorization头请求头传递
     */
    private List<SecurityScheme> securitySchemes()
    {
        return List.of(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
    }

    /** 用了网关,去除server.servlet.context-path 地址前缀,使用pathMapping */
    private class CustomerPathProvider extends DefaultPathProvider {

        @Override
        public String getOperationPath(String operationPath) {
            String path = super.getOperationPath(operationPath);
            return path.replace(contextPath, "");
        }
    }
    
    /**
     * 安全上下文
     */
    private List<SecurityContext> securityContexts()
    {
        List<SecurityContext> securityContexts = new ArrayList<>();
        securityContexts.add(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
                        .build());
        return securityContexts;
    }

    /**
     * 默认的安全上引用
     */
    private List<SecurityReference> defaultAuth()
    {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        List<SecurityReference> securityReferences = new ArrayList<>();
        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
        return securityReferences;
    }
    /**
     * 解决Spring Boot 2.6.x 与Swagger 3.0.0 不兼容问题
     **/
    @Bean
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        String basePath = webEndpointProperties.getBasePath();
        EndpointMapping endpointMapping = new EndpointMapping(basePath);
        boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
    }
    private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
        return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
    }
}
  • 配置后:
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是整合步骤: 1. 引入依赖 在 `pom.xml` 中引入以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 配置安全属性 在 `application.properties` 文件中配置安全属性: ```properties # 配置登录页面 spring.security.login-page=/login # 配置登录请求 spring.security.login-processing-url=/doLogin # 配置退出请求 spring.security.logout-url=/logout # 配置退出成功后跳转页面 spring.security.logout-success-url=/ # 配置用户信息 spring.security.user.name=user spring.security.user.password=password spring.security.user.roles=USER ``` 3. 配置安全策略 在 `WebSecurityConfig` 中配置安全策略: ```java @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() // 允许访问首页和 home 页面 .anyRequest().authenticated() // 其他请求需要认证 .and() .formLogin() .loginPage("/login") // 配置登录页面 .loginProcessingUrl("/doLogin") // 配置登录请求 .defaultSuccessUrl("/hello") // 登录成功后跳转到 hello 页面 .permitAll() .and() .logout() .logoutUrl("/logout") // 配置退出请求 .logoutSuccessUrl("/") // 配置退出成功后跳转页面 .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") .password("{noop}password") // 密码加密方式为 plain text .roles("USER"); } } ``` 以上就是整合 Spring Security 的基本步骤,你可以根据需求进行更进一步的配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值