【问题标题】:Spring Boot Actuator / SwaggerSpring Boot 执行器/Swagger
【发布时间】:2016-02-13 21:15:51
【问题描述】:

我正在开发 Spring Boot 应用程序,我使用 Swagger 作为文档。

我在我的应用程序上添加了 Spring Boot Actuator,但现在我想在我的招摇文档中添加由执行器 (/health /metrics ..) 创建的新服务。

我没有找到如何配置 Actuator 和 Swagger。

【问题讨论】:

    标签: spring-boot swagger spring-boot-actuator


    【解决方案1】:

    替代方案:

    a) 在正则表达式中排除带有NOT的路径?

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.regex("^((?!/error).)*")) // exclude Basic Error Controller
                .build();
    }
    

    b) 或链并否定谓词

    PathSelectors.any()
      .and(PathSelectors.regex("/error").negate())
      .and(PathSelectors.regex("/manage.*").negate());
    

    【讨论】:

      【解决方案2】:

      您可以在 Swagger 中配置要添加到文档中的路径:

      @Bean
      public Docket appApi() {
          return new Docket(DocumentationType.SWAGGER_2)
                  .select()
                  .apis(RequestHandlerSelectors.any())
                  .paths(PathSelectors.any())
                  ...
      }
      

      将显示所有可用的端点。

      .paths(PathSelectors.any("/mypath/**")) 将仅限于在 mypath. 中公开的端点

      【讨论】:

        【解决方案3】:

        通过application.properties 文件将执行器端点移动到上下文路径中。

        management.context-path=/manage
        

        然后你可以从 swagger 中排除该路径

        @Bean
        public Docket api() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .select()
                    .apis(RequestHandlerSelectors.any())
                    .paths(Predicates.not(PathSelectors.regex("/manage.*")))
                    .build();
        }
        

        您可能也想排除错误控制器

        @Bean
        public Docket api() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .select()
                    .apis(RequestHandlerSelectors.any())
                    .paths(Predicates.not(PathSelectors.regex("(/manage.*|/error)")))
                    .build();
        }
        

        【讨论】:

        • 在我看来,这与 OP 的要求相反。 OP 想知道如何配置执行器端点以出现在 swagger 中,而不是从 swagger 中删除它们。看起来 /health 和 /info 不包含 swagger 元数据。
        • @axiopisty 我认为你是对的,我的错。我误解了,因为根据我的经验,默认情况下它们会大摇大摆地出现,我需要尝试删除它们。以上是最好的方法。
        【解决方案4】:
        ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2)
          .useDefaultResponseMessages(false)
          .apiInfo(apiInfo())
          .securitySchemes(securitySchemes())
          .select()
          .apis(RequestHandlerSelectors.any())
          .paths(Predicates.not(PathSelectors.regex("/actuator.*")))
          .build();
        

        您好,您可以排除正则表达式上的路径,然后将它们链接起来。

        【讨论】:

          【解决方案5】:

          更新:2017 年 4 月 26 日,更新了实施。感谢Andy Brown 提供小费。

          由于我们的编码约定,我们的端点没有特定的前缀,因此我一直在寻找一种解决方案来排除执行器端点,而不是包含我自己的路径。

          我想出了以下配置,仅排除执行器端点。 这样一来,我就不必在添加新端点后更新配置,也不必为自己的端点添加前缀以将它们与执行器端点区分开来。

          /**
           * This enables swagger. See http://localhost:8080/v2/api-docs for the swagger.json output!
           * @param actuatorEndpointHandlerMapping this endpoint handler mapping contains all the endpoints provided by the
           * spring actuator. We will iterate over all the endpoints and exclude them from the swagger documentation.
           * @return the docket.
           */
          @Autowired
          @Bean
          public Docket swaggerSpringMvcPlugin(final EndpointHandlerMapping actuatorEndpointHandlerMapping) {
              ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2)
                      .useDefaultResponseMessages(false)
                      .apiInfo(apiInfo())
                      .securitySchemes(securitySchemes())
                      .select();
          
              // Ignore the spring-boot-actuator endpoints:
              Set<MvcEndpoint> endpoints = actuatorEndpointHandlerMapping.getEndpoints();
              endpoints.forEach(endpoint -> {
                  String path = endpoint.getPath();
                  log.debug("excluded path for swagger {}", path);
                  builder.paths(Predicates.not(PathSelectors.regex(path + ".*")));
              });
          
              return builder.build();
          }
          

          【讨论】:

          • 这不是捕获执行器端点的非常可靠的方法。一方面,您的正则表达式捕获前缀而不是路径段。最好注入一个EndpointHandlerMapping bean 并使用getEndpoints() 来查找当前版本中可用的执行器端点。
          • 你是绝对正确的@AndyBrown,谢谢你的提示!我不知道我可以通过这种方式检索端点。我已经相应地更新了我的解决方案。现在用完整的方法来展示如何自动装配它。
          猜你喜欢
          • 2014-04-07
          • 2018-08-29
          • 2017-06-29
          • 2016-09-05
          • 2019-03-26
          • 2016-08-08
          • 1970-01-01
          • 2017-02-19
          • 1970-01-01
          相关资源
          最近更新 更多