栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Small Tools(3) 集成Knife4j3.0.3接口文档

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Small Tools(3) 集成Knife4j3.0.3接口文档

文章目录
      • 一、前言
      • 二、swagger公共模块抽取
        • 1、引入依赖
        • 2、Knife4j配置类
        • 3、application-swagger.yml
      • 三、各微服务接口文档
        • 1、引入swagger公共模块
        • 2、服务模块`bootstrap.yml`
        • 3、公共基础配置`bootstrap.yaml`
      • 四、Gateway聚合接口文档
        • 1、引入依赖
        • 2、动态聚合各个服务的swagger接口
      • 五、swagger集成oauth2密码模式进行授权认证
      • 六、源码

一、前言

本文将集成knife4j-spring-boot-starter3.0.3接口文档 & gateway聚合各服务接口文档 & 集成oauth2的密码模式进行授权认证登录

2.6.7
2021.0.1
2021.0.1.0

这里将swagger文档单独抽取了一个公共模块统一管理

二、swagger公共模块抽取 1、引入依赖



    com.github.xiaoymin
    knife4j-spring-boot-starter
    3.0.3

2、Knife4j配置类

tips: 这里使用的是swagger2.0的api文档方式,因为在3里面集成oauth2认证发现没有表单认证登录了,不太友好,也没看见官方文档有说明,如果之后有发现,再更新到小编的demo源码中吧^_^

@Slf4j
@Configuration
@EnableSwagger2WebMvc
// 对JSR303提供支持
@Import(BeanValidatorPluginsConfiguration.class)
public class Knife4jConfig {

    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${small-tools.ip}")
    private String ip;

    @Value("${server.port}")
    private String port;

    @Value("${knife4j.passwordTokenUrl}")
    private String passwordTokenUrl;

    @Resource
    private OpenApiExtensionResolver openApiExtensionResolver;

    @Bean
    public Docket defaultApi() {
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(this.apiInfo())
                .groupName(this.applicationName)
                .select()
                // 添加@Api注解才显示
                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
//                .apis(RequestHandlerSelectors.basePackage("com.zhengqing"))
                .paths(PathSelectors.any())
                .build()
                // 插件扩展 -- ex:自定义md文档
                .extensions(this.openApiExtensionResolver.buildExtensions(this.applicationName))
                // 默认全局参数
                .globalRequestParameters(
                        Lists.newArrayList(
                                new RequestParameterBuilder()
                                        .name(SwaggerConstant.TENANT_ID)
                                        .description("租户ID")
                                        .in(ParameterType.HEADER)
                                        .required(true)
                                        .build()
                        )
                );

        // context
        List securityContexts = Lists.newArrayList(
                SecurityContext.builder()
                        .securityReferences(
                                CollectionUtil.newArrayList(
                                        new SecurityReference("oauth2",
                                                Lists.newArrayList(
                                                        new AuthorizationScope("read", "read  resources"),
                                                        new AuthorizationScope("write", "write resources"),
                                                        new AuthorizationScope("reads", "read all resources"),
                                                        new AuthorizationScope("writes", "write all resources")
                                                ).toArray(new AuthorizationScope[]{})
                                        )
                                )
                        )
                        .forPaths(PathSelectors.ant("
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("API文档")
                .description("API文档")
                .termsOfServiceUrl(String.format("%s:%s/", this.ip, this.port))
                .contact(
                        new Contact(
                                "zhengqingya",
                                "https://gitee.com/zhengqingya",
                                "960869719@qq.com"
                        )
                )
                .version("1.0.0")
                .build();
    }

    
    @Bean
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
                                                                         ServletEndpointsSupplier servletEndpointsSupplier,
                                                                         ControllerEndpointsSupplier controllerEndpointsSupplier,
                                                                         EndpointMediaTypes endpointMediaTypes,
                                                                         CorsEndpointProperties corsProperties,
                                                                         WebEndpointProperties webEndpointProperties,
                                                                         Environment environment) {
        List> allEndpoints = new ArrayList();
        Collection 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));
    }

}
3、application-swagger.yml
spring:
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MATCHER # 解决springboot高版本Knife4j报错问题

# https://doc.xiaominfo.com/knife4j
knife4j:
  # 开启增强配置
  enable: true
  # 是否开启生产环境屏蔽   true:关闭swagger,false:开启swagger
  production: false
  # 自定义文档
  documents:
    - group: demo
      name: 测试自定义标题分组
      # 某一个文件夹下所有的.md文件
      locations: classpath:markdown
    private static final String SWAGGER_URL = "/v2/api-docs?group=";

    
    @Resource
    private DiscoveryClient discoveryClient;

    
    @Value("${spring.application.name}")
    private String gatewayServiceName;

    @Override
    public List get() {
        // swagger下拉列表服务资源
        List resourceList = new ArrayList<>();
        // 动态获取nacos注册中心上的服务实例名
        List nacosServiceNameList = this.discoveryClient.getServices();
        for (String instance : nacosServiceNameList) {
            String instanceName = instance.toLowerCase();
            if (this.gatewayServiceName.equals(instanceName)) {
                continue;
            }
            // 拼接swagger访问url,样式为`/demo/v2/api-info?group=demo`,当网关调用这个接口时,会自动通过负载均衡寻找对应的主机
            String url = "/" + instanceName + SWAGGER_URL + instanceName;
            SwaggerResource swaggerResource = new SwaggerResource();
            swaggerResource.setUrl(url);
            swaggerResource.setName(instance);
            resourceList.add(swaggerResource);
        }
        return resourceList;
    }

}

swagger-ui.html需要访问的接口

@RestController
@RequiredArgsConstructor
@RequestMapping("/swagger-resources")
public class SwaggerHandler {

    private final MySwaggerResourcesProvider mySwaggerResourcesProvider;

    
    @GetMapping("/configuration/security")
    public ResponseEntity securityConfiguration() {
        return new ResponseEntity<>(SecurityConfigurationBuilder.builder().build(), HttpStatus.OK);
    }

    
    @GetMapping("/configuration/ui")
    public ResponseEntity uiConfiguration() {
        return new ResponseEntity<>(UiConfigurationBuilder.builder().build(), HttpStatus.OK);
    }

    
    @GetMapping("")
    public ResponseEntity swaggerResources() {
        return new ResponseEntity<>(mySwaggerResourcesProvider.get(), HttpStatus.OK);
    }

}

此方式会动态拉取我们nacos上面已注册的服务名进行拼接访问我们各微服务的接口文档
ex:/demo/v2/api-info?group=demo

五、swagger集成oauth2密码模式进行授权认证

在swagger公共模块中已经引入了oauth2的认证

一旦认证成功后,刷新页面会自动刷新Authorization的值方便我们去测试api

这里需要说明的是认证接口授权成功后Authorization取值问题
一般后端都会有统一响应体

{
  "code": 200,
  "data": [],
  "msg": "OK"
}

当我们有了统一响应体之后Authorization值便会出现undefined undefined的问题

我们可以打开浏览器查看前端UI缓存值发现取值tokenType &accessToken

再去Knife4j的前端UI源码中搜索相关值,可以看见取值逻辑为

$.post(url,params,function(data){
    if(data!=null&&data!=undefined) {
        that.cacheValue.accessToken=data.token_type+" "+data.access_token;
        that.cacheValue.tokenType=data.token_type;
        that.cacheValue.granted=true;
        window.localStorage.setItem(that.state,JSON.stringify(that.cacheValue))
        window.close();
    }
})


于是乎在我们的授权认证成功后修改返回所需字段

再次认证后Authorization取值恢复正常^_^

六、源码

tips: 最近项目在重构,最新代码放在dev分支上了

https://gitee.com/zhengqingya/small-tools


今日分享语句:
无论何时,不管怎样,我也绝不允许自己有一点点心丧气。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/999373.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号