神器 SpringDoc 横空出世,最适合 SpringBoot 的API文档工具来了

之前在SpringBoot项目中一直使用的是SpringFox提供的Swagger库,上了下官网发现已经有接近两年没出新版本了!前几天升级了SpringBoot 2.6.x 版本,发现这个库的兼容性也越来越不好了,有的常用注解属性被废弃了居然都没提供替代!无意中发现了另一款Swagger库SpringDoc,试用了一下非常不错,推荐给大家!

SpringDoc简介

SpringDoc是一款可以结合SpringBoot使用的API文档生成工具,基于OpenAPI 3,目前在Github上已有1.7K+Star,更新发版还是挺勤快的,是一款更好用的Swagger库!值得一提的是SpringDoc不仅支持Spring WebMvc项目,还可以支持Spring WebFlux项目,甚至Spring Rest和Spring Native项目,总之非常强大,下面是一张SpringDoc的架构图。

添加图片注释,不超过 140 字(可选)

使用

接下来我们介绍下SpringDoc的使用,使用的是之前集成SpringFox的mall-tiny-swagger项目,我将把它改造成使用SpringDoc。

集成

首先我们得集成SpringDoc,在pom.xml中添加它的依赖即可,开箱即用,无需任何配置。

 
 

<!--springdoc 官方Starter--> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>1.6.6</version> </dependency>

从SpringFox迁移

  • 我们先来看下经常使用的Swagger注解,看看SpringFox的和SpringDoc的有啥区别,毕竟对比已学过的技术能该快掌握新技术;

添加图片注释,不超过 140 字(可选)

  • 接下来我们对之前Controller中使用的注解进行改造,对照上表即可,之前在@Api注解中被废弃了好久又没有替代的description属性终于被支持了!

 
 

/** * 品牌管理Controller * Created by macro on 2019/4/19. */ @Tag(name = "PmsBrandController", description = "商品品牌管理") @Controller @RequestMapping("/brand") public class PmsBrandController { @Autowired private PmsBrandService brandService; private static final Logger LOGGER = LoggerFactory.getLogger(PmsBrandController.class); @Operation(summary = "获取所有品牌列表",description = "需要登录后访问") @RequestMapping(value = "listAll", method = RequestMethod.GET) @ResponseBody public CommonResult<List<PmsBrand>> getBrandList() { return CommonResult.success(brandService.listAllBrand()); } @Operation(summary = "添加品牌") @RequestMapping(value = "/create", method = RequestMethod.POST) @ResponseBody @PreAuthorize("hasRole('ADMIN')") public CommonResult createBrand(@RequestBody PmsBrand pmsBrand) { CommonResult commonResult; int count = brandService.createBrand(pmsBrand); if (count == 1) { commonResult = CommonResult.success(pmsBrand); LOGGER.debug("createBrand success:{}", pmsBrand); } else { commonResult = CommonResult.failed("操作失败"); LOGGER.debug("createBrand failed:{}", pmsBrand); } return commonResult; } @Operation(summary = "更新指定id品牌信息") @RequestMapping(value = "/update/{id}", method = RequestMethod.POST) @ResponseBody @PreAuthorize("hasRole('ADMIN')") public CommonResult updateBrand(@PathVariable("id") Long id, @RequestBody PmsBrand pmsBrandDto, BindingResult result) { CommonResult commonResult; int count = brandService.updateBrand(id, pmsBrandDto); if (count == 1) { commonResult = CommonResult.success(pmsBrandDto); LOGGER.debug("updateBrand success:{}", pmsBrandDto); } else { commonResult = CommonResult.failed("操作失败"); LOGGER.debug("updateBrand failed:{}", pmsBrandDto); } return commonResult; } @Operation(summary = "删除指定id的品牌") @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) @ResponseBody @PreAuthorize("hasRole('ADMIN')") public CommonResult deleteBrand(@PathVariable("id") Long id) { int count = brandService.deleteBrand(id); if (count == 1) { LOGGER.debug("deleteBrand success :id={}", id); return CommonResult.success(null); } else { LOGGER.debug("deleteBrand failed :id={}", id); return CommonResult.failed("操作失败"); } } @Operation(summary = "分页查询品牌列表") @RequestMapping(value = "/list", method = RequestMethod.GET) @ResponseBody @PreAuthorize("hasRole('ADMIN')") public CommonResult<CommonPage<PmsBrand>> listBrand(@RequestParam(value = "pageNum", defaultValue = "1") @Parameter(description = "页码") Integer pageNum, @RequestParam(value = "pageSize", defaultValue = "3") @Parameter(description = "每页数量") Integer pageSize) { List<PmsBrand> brandList = brandService.listBrand(pageNum, pageSize); return CommonResult.success(CommonPage.restPage(brandList)); } @Operation(summary = "获取指定id的品牌详情") @RequestMapping(value = "/{id}", method = RequestMethod.GET) @ResponseBody @PreAuthorize("hasRole('ADMIN')") public CommonResult<PmsBrand> brand(@PathVariable("id") Long id) { return CommonResult.success(brandService.getBrand(id)); } }

  • 接下来进行SpringDoc的配置,使用OpenAPI来配置基础的文档信息,通过GroupedOpenApi配置分组的API文档,SpringDoc支持直接使用接口路径进行配置。

 
 

/** * SpringDoc API文档相关配置 * Created by macro on 2022/3/4. */ @Configuration public class SpringDocConfig { @Bean public OpenAPI mallTinyOpenAPI() { return new OpenAPI() .info(new Info().title("Mall-Tiny API") .description("SpringDoc API 演示") .version("v1.0.0") .license(new License().name("Apache 2.0").url("https://github.com/macrozheng/mall-learning"))) .externalDocs(new ExternalDocumentation() .description("SpringBoot实战电商项目mall(50K+Star)全套文档") .url("http://www.macrozheng.com")); } @Bean public GroupedOpenApi publicApi() { return GroupedOpenApi.builder() .group("brand") .pathsToMatch("/brand/**") .build(); } @Bean public GroupedOpenApi adminApi() { return GroupedOpenApi.builder() .group("admin") .pathsToMatch("/admin/**") .build(); } }

结合SpringSecurity使用

  • 由于我们的项目集成了SpringSecurity,需要通过JWT认证头进行访问,我们还需配置好SpringDoc的白名单路径,主要是Swagger的资源路径;

 
 

/** * SpringSecurity的配置 * Created by macro on 2018/4/26. */ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.csrf()// 由于使用的是JWT,我们这里不需要csrf .disable() .sessionManagement()// 基于token,所以不需要session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers(HttpMethod.GET, // Swagger的资源路径需要允许访问 "/", "/swagger-ui.html", "/swagger-ui/", "/*.html", "/favicon.ico", "/**/*.html", "/**/*.css", "/**/*.js", "/swagger-resources/**", "/v3/api-docs/**" ) .permitAll() .antMatchers("/admin/login")// 对登录注册要允许匿名访问 .permitAll() .antMatchers(HttpMethod.OPTIONS)//跨域请求会先进行一次options请求 .permitAll() .anyRequest()// 除上面外的所有请求全部需要鉴权认证 .authenticated(); } }

  • 然后在OpenAPI对象中通过addSecurityItem方法和SecurityScheme对象,启用基于JWT的认证功能。

 
 

/** * SpringDoc API文档相关配置 * Created by macro on 2022/3/4. */ @Configuration public class SpringDocConfig { private static final String SECURITY_SCHEME_NAME = "BearerAuth"; @Bean public OpenAPI mallTinyOpenAPI() { return new OpenAPI() .info(new Info().title("Mall-Tiny API") .description("SpringDoc API 演示") .version("v1.0.0") .license(new License().name("Apache 2.0").url("https://github.com/macrozheng/mall-learning"))) .externalDocs(new ExternalDocumentation() .description("SpringBoot实战电商项目mall(50K+Star)全套文档") .url("http://www.macrozheng.com")) .addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME)) .components(new Components() .addSecuritySchemes(SECURITY_SCHEME_NAME, new SecurityScheme() .name(SECURITY_SCHEME_NAME) .type(SecurityScheme.Type.HTTP) .scheme("bearer") .bearerFormat("JWT"))); } }

测试

  • 接下来启动项目就可以访问Swagger界面了,访问地址:http://localhost:8088/swagger-ui.html

添加图片注释,不超过 140 字(可选)

  • 我们先通过登录接口进行登录,可以发现这个版本的Swagger返回结果是支持高亮显示的,版本明显比SpringFox来的新;

添加图片注释,不超过 140 字(可选)

  • 然后通过认证按钮输入获取到的认证头信息,注意这里不用加bearer前缀;

添加图片注释,不超过 140 字(可选)

  • 之后我们就可以愉快地访问需要登录认证的接口了;

添加图片注释,不超过 140 字(可选)

  • 看一眼请求参数的文档说明,还是熟悉的Swagger样式!

常用配置

SpringDoc还有一些常用的配置可以了解下,更多配置可以参考官方文档。

 
 

springdoc: swagger-ui: # 修改Swagger UI路径 path: /swagger-ui.html # 开启Swagger UI界面 enabled: true api-docs: # 修改api-docs路径 path: /v3/api-docs # 开启api-docs enabled: true # 配置需要生成接口文档的扫描包 packages-to-scan: com.macro.mall.tiny.controller # 配置需要生成接口文档的接口路径 paths-to-match: /brand/**,/admin/**

总结

在SpringFox的Swagger库好久不出新版的情况下,迁移到SpringDoc确实是一个更好的选择。今天体验了一把SpringDoc,确实很好用,和之前熟悉的用法差不多,学习成本极低。而且SpringDoc能支持WebFlux之类的项目,功能也更加强大,使用SpringFox有点卡手的朋友可以迁移到它试试!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 Spring基本特征 6 2 Spring的组成 6 2.1 Spring的jar包 6 2.2 Spring配置文件 7 2.3 Spring API 8 3 Spring基本功能详解 8 3.1 SpringIOC 8 3.2别名Alias 11 别名拓展: 11 3.3 Spring容器内部对象的创建 12 Spring容器内部对象创建拓展: 12 3.3.1使用类构造器实例化(默认无参数) 14 3.3.2使用静态工厂方法实例化(简单工厂模式) 14 3.3.3初始化(创建)bean时机 15 Lazy-init初始化bean的时机拓展: 15 3.4 Bean的作用域 16 Scope单例多例作用域拓展: 16 3.4.1 singleton(默认值) 16 3.4.2 prototype 17 3.4.3 Request 17 3.4.4 Session 18 3.4.5 Global session 18 3.4.6 指定Bean的初始化方法和销毁方法 18 Bean的初始化和销毁拓展: 18 Spring的IOC总结: 20 3.5 依赖注入(DI) 20 3.5.1 使用构造器注入 20 3.5.2 使用属性setting方法进行注入 21 3.5.3 装配list集合 22 3.5.4 装配set集合 22 3.5.5 装配map 22 3.5.6 装配Properties 23 3.6 注解注入 23 注解注入拓展: 23 3.6.1 @Autowired 26 3.6.2 @Qualifier 27 3.6.3 @Resource 27 3.6.4 @PostConstruct 28 3.6.5 @PreDestroy 28 注解注入拓展: 28 3.7扫描注入 30 注解扫描拓展: 32 Mvc用注解写: 34 Spring容器IOC和di的整个启动过程: 38 3.8 spring中的继承 38 拓展spring为类中的属性赋值: 40 小结: 47 面向接口编程: 47 4 面向切面编程 52 4.1 代理模式 52 代理模式拓展: 52 4.1.1 JDK动态代理 58 JDK动态代理拓展: 59 4.1.2 CGLIB做代理 66 CGLIB动态代理拓展: 68 4.1.3 Spring的动态代理 71 4.2 AOP编程 71 4.2.1概念: 71 SpringAOP概念拓展: 73 之前实现了目标方法的动态调用,现在来实现切面的动态调用。 74 4.2.2 AOP实现的两种模式 78 4.2.2.1 xml形式 78 XML形式拓展: 81 异常通知处理例子: 91 不用spring异常通知,另一种处理异常 96 4.2.2.2Aop注解形式(了解) 99 注解注入拓展: 103 5 Spring数据库 106 5.1 Spring+JDBC 106 5.1.1 Jdbc编程特点 106 5.1.2引入DataSource 106 5.1.3 核心类JdbcTemplate 106 5.1.4 使用JdbcTemplate 106 5.1.5 继承JdbcDaoSupport 107 5.1.6 使用properties文件 107 5.1.7 RowMapper的使用 107 拓展: 108 DataSource注入的三种方式: 108 5.1.8声明式事务管理 116 5.1.8.1Spring的事务管理器 117 5.1.8.2Spring事务的传播属性 117 5.1.8.3Spring事务的隔离级别 117 拓展: 118 5.1.8.4以XML配置的 形式 119 拓展: 120 5.1.8.5以注解方式配置 125 拓展: 127 5.1.9使用CGLIB以XML形式配置事务 130 5.2 Spring+Hibernate 131 5.2.1 HibernateTemplate模板 131 5.2.2 声明式事务 131 配置XML文件 131 拓展: 132 注解形式: 137 拓展: 138 6 Struts2+spring+hibernate 141 6.1 需要添加的jar包 141 6.2 Spring融合web服务器 141 6.3 struts.xml文件 143 6.4 OpenInSessionView 143 拓展: 144 实例: 146
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值