Swagger 新体验

462 阅读3分钟

依赖

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.6.13</version>
</dependency>

application.yml

springdoc:
  api-docs:
    enabled: true
    path: /v3/api-docs
    groups:
      enabled: false
    resolve-schema-properties: false
    version: openapi_3_0
  swagger-ui:
    enabled: true
    path: /swagger-ui.html
    #config-url: /v3/api-docs/swagger-config
    #layout: BaseLayout
    validator-url: validator.swagger.io/validator
    try-it-out-enabled: false
    filter: false
    operations-sorter: alpha
    tags-sorter: alpha
    oauth2-redirect-url: /swagger-ui/oauth2-redirect.html
    display-operation-id: false
    display-request-duration: false
    deep-linking: false
    default-models-expand-depth: 1
    default-model-expand-depth: 1
    default-model-rendering:
    doc-expansion:
    max-displayed-tags:
    show-extensions: false
    url:
    show-common-extensions: false
    supported-submit-methods: get, put, post, delete, options, head, patch, trace
    query-config-enabled: false
    #oauth:
      #additional-query-string-params:
      #client-id:
      #realm:
      #app-name:
      #scope-separator:
      #use-basic-authentication-with-access-code-grant: false
      #use-pkce-with-authorization-code-grant: false
    disable-swagger-default-url: false
    urls:
    urls-primary-name:
    csrf:
      enabled: false
      use-local-storage: false
      use-session-storage: false
      cookie-name: XSRF-TOKEN
      header-name: X-XSRF-TOKEN
    syntax-highlight:
      activated: true
      theme: agate
    persist-authorization: false
    use-root-path: false
  #packages-to-scan:
  packages-to-exclude: com.example.swagger.test
  #paths-to-match:
  paths-to-exclude: /test/**
  #produces-to-match:
  #headers-to-match:
  #consumes-to-match:
  default-consumes-media-type: application/json
  default-produces-media-type: '*/*'
  cache:
    disabled: false
  show-actuator: false
  auto-tag-classes: true
  model-and-view-allowed: false
  override-with-generic-response: true
  group-configs:
  webjars:
    prefix: /webjars
  remove-broken-reference-definitions: true
  writer-with-default-pretty-printer: false
  model-converters:
    deprecating-converter:
      enabled: true
    polymorphic-converter:
      enabled: true
    pageable-converter:
      enabled: true
  use-fqn: false
  show-login-endpoint: false
  pre-loading-enabled: false
  writer-with-order-by-keys: false
  use-management-port: false
  disable-i18n: false
  show-spring-cloud-functions: true
  default-flat-param-object: false
  default-support-form-data: false

配置

import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.annotations.security.SecuritySchemes;
import io.swagger.v3.oas.models.*;
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 io.swagger.v3.oas.models.media.DateTimeSchema;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.oas.models.servers.ServerVariable;
import io.swagger.v3.oas.models.servers.ServerVariables;
import io.swagger.v3.oas.models.tags.Tag;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.Collections;

/**
 * https://petstore.swagger.io/v2/swagger.json
 */
@Configuration
@SecuritySchemes({
        @SecurityScheme(name = "Authorization", scheme = "bearer", type = SecuritySchemeType.HTTP, in = SecuritySchemeIn.HEADER),
})
public class OpenApiConfig {

    //@Bean
    public GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
                .group("public")
                .pathsToMatch("/public/**")
                .build();
    }
    //@Bean
    public GroupedOpenApi groupedOpenApi(){
        return GroupedOpenApi.builder()
                .group("admin")
                .pathsToMatch("/user/**")
                .addOpenApiMethodFilter(method -> method.isAnnotationPresent(RestController.class))
                .build();
    }

    @Bean
    public OpenAPI openAPI() {
        OpenAPI openAPI = new OpenAPI();
        Info info = new Info()
                .title("User Manage System")
                .description("A system for user manage")
                .termsOfService("https://www.ums.com")
                .contact(new Contact()
                        .name("CompanyName")
                        .url("https://www.xxx.com")
                        .email("xxx@gmail.com")
                )
                .license(new License()
                        .name("MIT")
                        .url("https://opensource.org/licenses/MIT")
                        .identifier("0000000000000000")
                )
                .version("v1.0")
                .summary("Welcome");

        ServerVariable serverVariable = new ServerVariable();
        serverVariable.setDefault("2");
        serverVariable.setDescription("A server variable");
        serverVariable.setEnum(Arrays.asList("1", "2", "3"));

        openAPI
                .info(info)
                .externalDocs(new ExternalDocumentation()
                        .url("https://www.doc.com")
                        .description("See another docs")
                )
                .servers(Arrays.asList(
                        new Server()
                            .url("http://localhost:8080")
                            .description("Ums server url")
                            .variables(new ServerVariables()
                                    .addServerVariable("v1", serverVariable)
                            ),
                        new Server()
                            .url("https://localhost:443")
                            .description("Ums server url")
                            .variables(new ServerVariables()
                                    .addServerVariable("v1", serverVariable)
                            )
                ))
                .security(Collections.singletonList(new SecurityRequirement()
                        .addList("key", "value")
                ))
                .tags(Collections.singletonList(new Tag()
                        .name("tagA")
                        .description("tag a description")
                        .externalDocs(new ExternalDocumentation()
                                .url("https://www.tag.com")
                        )
                ))
                .paths(new Paths()
                        .addPathItem("path", new PathItem()
                                .get(new Operation())
                        )
                )
                .components(new Components())
                .jsonSchemaDialect("json schema dialect")
                .specVersion(SpecVersion.V30)
                .webhooks(Collections.singletonMap("", new PathItem()))
                .schema("schema", new DateTimeSchema())
        ;
        return openAPI;
    }

}

controller

import com.example.swagger.entity.UserEntity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * Swagger 迁移:
 *
 * @Api@Tag
 *
 * @ApiIgnore@Parameter(hidden = true) or @Operation(hidden = true) or @Hidden
 *
 * @ApiImplicitParam@Parameter
 *
 * @ApiImplicitParams@Parameters
 *
 * @ApiModel@Schema
 *
 * @ApiModelProperty(hidden = true) → @Schema(accessMode = READ_ONLY)
 *
 * @ApiModelProperty@Schema
 *
 * @ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar")
 *
 * @ApiParam@Parameter
 *
 * @ApiResponse(code = 404, message = "foo") → @ApiResponse(responseCode = "404", description = "foo")
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户管理接口") // 之前是@Api
public class UserController {

    @GetMapping("/get/{id}")
    @Operation(summary = "通过id获取用户") // 之前是@ApiOperation
    // 之前是@ApiImplicitParams
    @Parameters(
            @Parameter(name = "id", required = true, example = "1") // 之前是@ApiImplicitParam
    )
    @SecurityRequirement(name = "Authorization")
    public ResponseEntity<UserEntity> get(@PathVariable("id") @Parameter Long id){ // 之前是@ApiParam
        UserEntity userEntity = new UserEntity();
        userEntity.setId(id);
        userEntity.setName("张三");

        return ResponseEntity.ok(userEntity);
    }

    @GetMapping("/get/current")
    // 之前是@ApiIgnore
    @Parameter(hidden = true)
    //或@Operation(hidden = true)
    //或@Hidden
    public ResponseEntity<UserEntity> getCurrent(HttpServletRequest request){
        UserEntity userEntity = new UserEntity();
        userEntity.setId(1L);
        userEntity.setName("张三");

        return ResponseEntity.ok(userEntity);
    }

    @GetMapping("/notFound")
    @ApiResponse(responseCode = "404", description = "foo") // 之前是@ApiResponse(code = 404, message = "foo")
    public ResponseEntity<?> notFound(){
        return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
    }

    @GetMapping("/index")
    @Operation(deprecated = true)
    public ResponseEntity<Boolean> index(){
        return ResponseEntity.ok(true);
    }

}

entity

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY;

/**
 * 类
 *
 * @author wanglunhui
 * @since 2022-11-23 20:46:04
 */
@Getter
@Setter
@Schema(name = "用户", description = "用户实体类") // 之前是@ApiModel
public class UserEntity implements Serializable {

    @Schema(accessMode = READ_ONLY) // 之前是@ApiModelProperty(hidden = true)
    private static final long serialVersionUID = -1L;

    @Schema(description = "id", required = true, example = "1") // 之前是@ApiModelProperty
    private Long id;

    @Schema(description = "姓名", required = true, example = "张三")
    private String name;

}

效果

Swagger UI.png