Spring Boot集成SpringFox 3.0与Pageable参数处理方法
作者:工程师小A
Springfox 3.0有多个模块,提供了spring boot starter,与Spring Boot集成时仅需引入springfox-boot-starter,如下:
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency>
如果您以前使用了Springfox 2.x,需要修改一下Swagger配置:
删除@EnableSwagger2注解,改为@EnableOpenApi
将Docket中的参数DocumentationType.SWAGGER_2改为DocumentationType.OAS_30
Springfox 3.0删除了一些第三方模块,如有引用需要替换
修改后的配置如下:
package com.ys.config; import com.fasterxml.classmate.TypeResolver; import org.itrunner.heroes.exception.ErrorMessage; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.ResponseEntity; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.oas.annotations.EnableOpenApi; import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; import java.time.LocalDate; import java.util.List; import static java.util.List.of; @EnableOpenApi @Configuration public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.OAS_30) .select() .apis(RequestHandlerSelectors.basePackage("com.ys.controller")) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()) .pathMapping("/") .directModelSubstitute(LocalDate.class, String.class) .genericModelSubstitutes(ResponseEntity.class) .additionalModels(new TypeResolver().resolve(ErrorMessage.class)) .useDefaultResponseMessages(false) .securitySchemes(of(authenticationScheme())) .securityContexts(of(securityContext())) .enableUrlTemplating(false); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Api Documentation") .description("Api Documentation") .contact(new Contact("xx", "http://xxxxxx", "xxxxx@163.com")) .version("1.0.0") .build(); } private HttpAuthenticationScheme authenticationScheme() { return HttpAuthenticationScheme.JWT_BEARER_BUILDER.name("BearerToken").build(); } private SecurityContext securityContext() { return SecurityContext.builder() .securityReferences(defaultAuth()) .operationSelector(operationContext -> operationContext.requestMappingPattern().startsWith("/api/") ) .build(); } private List<SecurityReference> defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; return of(new SecurityReference("BearerToken", authorizationScopes)); } }
上面我们使用了HttpAuthenticationScheme构建Bearer Token Authentication,在Swagger UI界面点击Authorize时直接输出token值即可。
Springfox 3.0的Swagger UI地址,从http://host/context-path/swagger-ui.html 改成了 http://host/context-path/swagger-ui/ ,OAS 3.0的api docs地址默认为/v3/api-docs,因此Security中的ignore path要进行相应修改。
Pageable参数
当REST API的方法含有org.springframework.data.domain.Pageable参数时,Springfox根据接口生成pageNumber、pageSize、offset、paged、unpaged、sort.sorted、sort.unsorted等参数,这与Spring Boot实际使用的参数是不一致的,因此需要针对Pageable参数进行特殊处理。
我们使用OperationBuilderPlugin处理Pageable参数,如下:
package com.ys.config; import com.fasterxml.classmate.ResolvedType; import com.fasterxml.classmate.TypeResolver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; import springfox.documentation.builders.RequestParameterBuilder; import springfox.documentation.schema.ScalarType; import springfox.documentation.service.ParameterType; import springfox.documentation.service.RequestParameter; import springfox.documentation.service.ResolvedMethodParameter; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.OperationBuilderPlugin; import springfox.documentation.spi.service.contexts.OperationContext; import java.util.ArrayList; import java.util.List; @Component @Order public class PageableParameterReader implements OperationBuilderPlugin { private final TypeResolver resolver; @Autowired public PageableParameterReader(TypeResolver resolver) { this.resolver = resolver; } @Override public void apply(OperationContext context) { List<ResolvedMethodParameter> methodParameters = context.getParameters(); ResolvedType pageableType = resolver.resolve(Pageable.class); List<RequestParameter> parameters = new ArrayList<>(); for (ResolvedMethodParameter methodParameter : methodParameters) { ResolvedType resolvedType = methodParameter.getParameterType(); if (pageableType.equals(resolvedType)) { parameters.add(new RequestParameterBuilder() .in(ParameterType.QUERY) .name("page") .query(q -> q.model(m -> m.scalarModel(ScalarType.INTEGER))) .description("Results page you want to retrieve (0..N)").build()); parameters.add(new RequestParameterBuilder() .in(ParameterType.QUERY) .name("size") .query(q -> q.model(m -> m.scalarModel(ScalarType.INTEGER))) .description("Number of records per page").build()); parameters.add(new RequestParameterBuilder() .in(ParameterType.QUERY) .name("sort") .query(q -> q.model(m -> m.collectionModel(c -> c.model(cm -> cm.scalarModel(ScalarType.STRING))))) .description("Sorting criteria in the format: property(,asc|desc). " + "Default sort order is ascending. " + "Multiple sort criteria are supported.") .build()); context.operationBuilder().requestParameters(parameters); } } } @Override public boolean supports(DocumentationType delimiter) { return true; } }
方案一:在Controller分页方法的Pageable参数前添加@ApiIgnore,忽略默认的参数解析:
public ResponseEntity<List<DeviceDTO>> getAllDevices(@ApiIgnore @PageableDefault(sort = {"id"}, direction = Sort.Direction.DESC) Pageable pageable, @RequestParam(required = false) @ApiParam(value = "关键字(序列号,地址,归属单位)") String keyword,
方案二:全局配置,在SwaggerConfig类的createRestApi方法中添加:.ignoredParameterTypes(Pageable.class)
@EnableOpenApi @Configuration public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.OAS_30) .select() .apis(RequestHandlerSelectors.basePackage("com.ys.controller")) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()) .ignoredParameterTypes(Pageable.class) .pathMapping("/") .directModelSubstitute(LocalDate.class, String.class) .genericModelSubstitutes(ResponseEntity.class) .additionalModels(new TypeResolver().resolve(ErrorMessage.class)) .useDefaultResponseMessages(false) .securitySchemes(of(authenticationScheme())) .securityContexts(of(securityContext())) .enableUrlTemplating(false); }
修改后Swagger UI中显示的Pageable参数如下:
到此这篇关于Spring Boot集成SpringFox 3.0与Pageable参数处理的文章就介绍到这了,更多相关Spring Boot集成SpringFox 3.0内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!