springboot api文档,springboot apidoc

  springboot api文档,springboot apidoc

  00-1010前言SpringDoc使用集成简介从SpringFox结合SpringSecurity使用测试通用配置迁移概述参考资料

  

目录

 

  此前SpringFox提供的Swagger库已经在SpringBoot项目中使用。上了官网后发现已经近两年没有新版本了!前几天升级了SpringBoot 2.6.x的版本,发现这个库的兼容性越来越差。一些常用的注释属性被放弃了,但是它们甚至没有提供替换!无意中发现了另一个招摇的库SpringDoc,试出来很不错。我推荐给大家!

  SpringBoot实用电子商务项目商城(50k star)地址:https://github.com/macrozheng/mall

  

前言

SpringDoc是一个API文档生成工具,可以和SpringBoot结合使用。它基于OpenAPI 3,目前在Github上有1.7K Star。更新发布还是挺勤快的,是比较好用的Swagger库!值得一提的是,SpringDoc不仅支持Spring WebMvc项目,还支持Spring WebFlux项目,甚至支持Spring Rest和Spring Native项目。总之很厉害。这是SpringDoc的架构图。

 

  00-1010接下来介绍一下SpringDoc的使用方法,这是之前集成SpringFox的mall-tiny-swagger项目。我将把它转换成使用SpringDoc。

  00-1010首先我们要集成SpringDoc,只需在pom.xml中添加它的依赖项,开箱即用,无需任何配置。

  !-spring doc官方首发-依赖groupIdorg.springdoc/groupId神器spring doc-open API-UI/神器ID版本1.6.6/version/dependency

  00-1010我们先来看看常用的Swagger注释,看看SpringFox的和SpringDoc的有什么区别。毕竟,通过对比已经学过的技术,更能快速掌握新技术;springfoxpspringdoc @ Api @ Tag @ Api ignore @ Parameter(Hidden=true)或@Operation(hidden=true)或@ Hidden @ apiiimplicitparam @ Parameter @ ApiModel @ Schema @ ApiModelProperty @ Schema @ Api Operation(value= foo ,notes= bar )@ Operation(summary= foo ,description= bar )@ Api param @ param @ Parameter @ Api Response(code=404,Message= foo) API响应(响应代码= 404 ,description= foo )接下来在@Api注释中被废弃很久且没有替代的description属性终于被支持了!

  /* * *品牌管理控制器*由宏创建于2019年4月19日。*/@ tag(name= pmbrandcontroller ,Description=商品品牌管理)@ controller @ request mapping(/brand )公共类pmbrandcontroller { @ autowired private pmbrandservice brandservice;private static final Logger Logger=Logger factory . get Logger(pmbrandcontroller . 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. */@Configurationpublic 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. */@Configurationpublic 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

 

  

 

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

  

 

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

  

 

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

  

 

  看一眼请求参数的文档说明,还是熟悉的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有点卡手的朋友可以迁移到它试试!

 

  如果你想了解更多SpringBoot实战技巧的话,可以试试这个带全套教程的实战项目(50K+Star):github.com/macrozheng/…

  

 

  

参考资料

项目地址:github.com/springdoc/s…官方文档:springdoc.org/项目源码地址 :https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-springdoc

 

  更多关于SpringBoot API文档工具SpringDoc的资料请关注盛行IT其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: