如何使用 Springfox 从 Swagger 文档中隐藏端点

Posted

技术标签:

【中文标题】如何使用 Springfox 从 Swagger 文档中隐藏端点【英文标题】:How to hide endpoints from Swagger documentation with Springfox 【发布时间】:2019-07-27 08:47:34 【问题描述】:

我有一个 Spring Boot 项目,下一个依赖是 Springfox:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

我有我的界面:

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

@RestController
@RequestMapping(value = "/cache")
@ApiIgnore
@Api(hidden = true)
public interface CacheController 

    @RequestMapping(
        value = "clear/",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE
    )
    @ApiOperation(value = "", hidden = true)
    ResponseEntity<String> clearToken();

注释@ApiIgnore@Api(hidden = true)(我已经单独测试过它们,它们也不起作用。)没有隐藏文档的效果。它仅在注释超过方法时才有效,但我想将它们全部隐藏,因为我还有其他要隐藏的端点。

一些想法?

编辑:

这是我的 Swagger 配置:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig 

    public static String API_KEY_NAME;

    @Bean
    public Docket apiDocumentation() 
        List<ResponseMessage> errorList = this.defineResponseMessages();

        return new Docket(DocumentationType.SWAGGER_2)  
          .select()       
          .apis(RequestHandlerSelectors.basePackage("my.package.rest"))              
          .paths(PathSelectors.any())                          
          .build()
          .useDefaultResponseMessages(true)
          .globalResponseMessage(RequestMethod.GET, errorList)
          .securitySchemes(Arrays.asList(this.apiKey()))
          .securityContexts(Arrays.asList(this.securityContext()))
          .apiInfo(this.apiInfo());                                          
    

    @Value("$server.security.apiKeyName")
    public void setApiKeyName(final String apiKeyName) 
        SwaggerConfig.API_KEY_NAME = apiKeyName;
    

    private ApiKey apiKey() 
        return new ApiKey("apiKey", API_KEY_NAME, "header");
    

    private SecurityContext securityContext() 
        return SecurityContext.builder()
            .securityReferences(defaultAuth())
            .forPaths(PathSelectors.any()).build();
    

    private List<SecurityReference> defaultAuth() 
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Arrays.asList(new SecurityReference("apiKey", authorizationScopes));
    

    private List<ResponseMessage> defineResponseMessages() 
        List<ResponseMessage> errorList = new ArrayList<ResponseMessage>();

        ResponseMessage responseMessage = new ResponseMessageBuilder()
            .code(HttpStatus.INTERNAL_SERVER_ERROR.value())
            .message(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase())
            .build();

        errorList.add(responseMessage);

        responseMessage = new ResponseMessageBuilder()
                .code(HttpStatus.UNAUTHORIZED.value())
                .message(HttpStatus.UNAUTHORIZED.getReasonPhrase())
                .build();

        errorList.add(responseMessage);

        responseMessage = new ResponseMessageBuilder()
                .code(HttpStatus.NOT_FOUND.value())
                .message(HttpStatus.NOT_FOUND.getReasonPhrase())
                .build();

        errorList.add(responseMessage);

        return errorList;
    

    private ApiInfo apiInfo() 
        ApiInfoBuilder apiInfoBuilder = new ApiInfoBuilder();
        return apiInfoBuilder
            .title("My API")
            .description("Description")
            .version("1.0.0 Beta")
            .build();
    

【问题讨论】:

您的 Swagger Docket 配置是什么样的? 我已编辑帖子以添加 Swagger 配置 【参考方案1】:

您已在接口上添加了@ApiIgnore 注释。看起来,当添加到界面上时,此注释不起作用。 (我真的不明白为什么@Api 可以在界面上工作而@ApiIgnore 不能。?)

将注释直接添加到您的控制器类。这应该可以解决您的问题。

@Api 注释上的 hidden 属性当前不起作用。 (请参阅this GitHub 问题。)

【讨论】:

【参考方案2】:

另一种方法是使用@ApiOperation(hidden = true) 这可以用于控制器/处理程序级别的方法。 例如

@RestController
public HomeController
@ApiOperation(value = "<Your Message>", hidden = true)
    public String getMessage(@RequestParam(value = "msg") final String msg)
        return msg;
    

【讨论】:

我也解决了隐藏操作。我的文档在一个界面中。推荐它。【参考方案3】:

对于 OpenAPI3SpringBoot: 我在控制器的方法上使用了@Hidden 注释。 它似乎在方法级别和控制器级别都有效。

@Hidden 注释是通过以下方式导入的:

import io.swagger.v3.oas.annotations;

【讨论】:

【参考方案4】:

我们只想从类中隐藏特定方法的场景。对于 swagger.v3,io.swagger.core.v3:swagger-annotations:2.0.10 jar 中有一个名为 Hidden 的注释。要隐藏的方法可以使用Hidden注解进行注解,如下所示。下面的方法显示了带有DELETE 操作的方法,需要从swagger 文档中隐藏。

@DELETE
@Hidden
public void deleteList(int id) 
//code goes here.

【讨论】:

【参考方案5】:

另一种不同的好方法是在 SpringFox 配置上定义可见路径

@Configuration
@EnableSwagger2
public class SpringFoxConfig 

    @Bean
    public Docket api() 
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(Predicates.or(PathSelectors.ant("/rtm/**"), PathSelectors.ant("/appview/**")))
                .build().apiInfo(apiEndPointsInfo());
    

通过这种方式,您可以集中定义可见路径,并避免在许多控制器上放置大张旗鼓的注释。

【讨论】:

【参考方案6】:

另一种选择是完全删除@Api,并且您的控制器及其方法不应被大摇大摆地拾取。

【讨论】:

以上是关于如何使用 Springfox 从 Swagger 文档中隐藏端点的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 springfox 在 Swagger UI 中绕过授权

springfox-swagger-ui3的基本使用

从 Springfox Swagger 2 迁移到 Springdoc Open API

如何更改 Springfox Swagger 2.0 的 basePath

使用springfox+swagger2书写API文档(十八)

如何复写 springfox swagger2controller