范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

神器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的架构图。
  使用
  接下来我们介绍下SpringDoc的使用,使用的是之前集成SpringFox的  mall-tiny-swagger  项目,我将把它改造成使用SpringDoc。 集成
  首先我们得集成SpringDoc,在  pom.xml  中添加它的依赖即可,开箱即用,无需任何配置。       org.springdoc     springdoc-openapi-ui     1.6.6  从SpringFox迁移我们先来看下经常使用的Swagger注解,看看SpringFox的和SpringDoc的有啥区别,毕竟对比已学过的技术能该快掌握新技术;
  接下来我们对之前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> 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> listBrand(@RequestParam(value = "pageNum", defaultValue = "1")                                                         @Parameter(description = "页码") Integer pageNum,                                                         @RequestParam(value = "pageSize", defaultValue = "3")                                                         @Parameter(description = "每页数量") Integer pageSize) {         List 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 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
  我们先通过登录接口进行登录,可以发现这个版本的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有点卡手的朋友可以迁移到它试试! 参考资料项目地址:https://github.com/springdoc/springdoc-openapi 官方文档:https://springdoc.org/ 项目源码地址
  https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-springdoc
  来源:https://mp.weixin.qq.com/s/scityFhZp9BOJorZSdCG0w

宅家大跳刘畊宏毽子舞,用极米Z6XPro陪练更酣爽一首周董经典的本草纲目,洗脑了刘畊宏男孩女孩们一套活力满满的健身操,累趴了全网的小仙女健身狂热爱好者刘畊宏于社交平台中带领网友进行居家健身操,疾速火遍全网。在刘畊宏晒出自己使用极米小米MIXFOLD2惊艳外观亮相,小米12价格发烧惨遭疯抢据5月16日消息,今日微博博主数码聊天站据悉曾表示,小米MIXFOLD2二代折叠机整体非常轻薄,仅比一侧的充电口厚一点,并支持杜比视界视频。这就是为什么这款手机不支持无线充电的原因时代霸主微软总裁比尔盖茨全球个人电脑软件领导品牌微软公司的董事长兼CEO。比尔盖茨出生于1955年10月28日,和二位姐妹一同在西雅图成长。父亲是一位律师,已去世的母亲则是位集学校老师华盛顿大学董事长和U科技创新是未来进步的关键1科技创新的意义科学技术是第一生产力,这句话充分阐释了科学技术对一个国家和一个民族的重要性。中国历来都十分重视科技的发展与创新。创新是一个民族进步的灵魂,是国家文明发展的不竭动力,刚刚!国际大行突然翻多,大幅上调腾讯阿里美团等目标价,最高翻倍!更有旗舰基金10倍增持,释放什么信号?点蓝字关注,不迷路在3月大幅下调相关评级后,国际大行摩根大通突然全面翻多,上调大部分中资互联网公司评级。5月16日,据彭博社消息,摩根大通今日集体上调多家互联网公司评级,对腾讯控股知网涉嫌垄断被立案调查海康威视回应被美制裁传言AI周报马斯克收购Twitter的交易暂时搁置前小米VR负责人已加入字节跳动钉钉被曝组织优化,涉及自研SaaS硬件部门中芯国际2022年第一季度营收18。4亿美元,同比增长66。9苹果更依魅族在新系统上的这波操作,简直太骚了前阵子珠海小厂魅族做了一个所有国产手机厂商都没做过的骚操作,可以说是狠狠收割了一波煤油们的好评,甚至连我这个小米用户也羡慕了。事情的起因是这样的。最近这两年安卓旗舰芯片功耗表现不尽华为真有35岁生死线吗?没有强制性,我以前部门好几个都过40了,其中有管理层,有技术专家,也有普通开发人员(这也有好几个,非SE)。早几年,绩效拿过C继续待很多年的也有,不过连续拿C就不行。这两三年因为美58同城安居客数智化升级满足多元居住需求助力用户实现理想安居在租购并举大背景下,房产行业迎来了新的发展模式,一方面商品房市场将更好满足购房者的合理住房需求,另一方面住房租赁行业的发展也在提速。作为国内领先的房产信息及交易服务平台,58同城安5月15日上市公司发布最新事项公告精选二)1川能动力(000155)公司股票5月16日开市时起开始停牌,预计停牌时间不超过10个交易日。公司拟收购四川省能投风电开发有限公司少数股权四川省能投会东新能源开发有限公司少数股权四可追踪并分析动物行为瑞士研究团队开发出人工智能图像算法据瑞士资讯网站近日报道,来自瑞士的研究团队开发出了一种利用人工智能追踪并分析动物行为的新方法。这项技术目前正在苏黎世动物园接受测试。机器能否察觉动物的喜怒哀乐?研究动物行为的科学家
科技周报商汤科技港股上市冒充老干妈员工诈骗腾讯案主犯获刑12年编者按鞭牛士将以周报形式盘点一周内发生的重要事件,内容涵盖国际国内科技互联网,为科技行业从业者用户传递行业信息。国内动态1冒充老干妈员工诈骗腾讯案一审宣判,主犯获刑12年,两被告提视频译文谷歌揭晓2021年最热搜词汇我们的电脑和手机屏幕是一个窗口,从中能看到我们是怎样的人,而我们在这些设备上搜索的内容则透露了我们最多的信息。(被采访者说)你从未像在搜索引擎里表现的这么诚实,人们在社交媒体或其他高校校园,正在大变样智慧教室智慧教学智慧食堂智慧图书馆智慧服务平台这些年,很多高校都在推动学校的智慧化建设,高校校园正在大变样。无实体校园卡通过手机直接体会餐厅就餐超市消费医院就诊图书馆借阅等功能,还程序员面试金典面试题16。09。运算题目难度中等原题链接1今天继续更新程序员面试金典系列,大家在公众号算法精选里回复面试金典就能看到该系列当前连载的所有文章了,记得关注哦题目描述请实现整数数字的乘法减法和除法运算,运5个PyTorch中的处理张量的基本函数每个深度学习初学者都应该知道这5个Pytorch的基本函数。能够以准确有效的方式构建神经网络是招聘人员在深度学习工程师中最受追捧的技能之一。PyTorch是一个主要用于深度学习的P视频剪辑短片将被禁短视频发展痛点如何破解?来源工人日报本报记者徐潇近日,腾讯向法院申请变更诉讼请求,将斗罗大陆索赔金额从6160万元提高到8亿元。至此,腾讯半年来起诉抖音的标的总额已超过29。43亿元。12月15日,中国网去卖手机回收麒麟5G手机,买到就是赚到呀众所周知,麒麟5G芯片无法再生产,搭载麒麟芯片的手机也是越来越少,近日一批搭载华为自研5G芯片麒麟820的荣耀X10手机又上架开售了,之前错过的小伙伴这次可一定不能再错过呀。荣耀X红米Note12Pro真机照公布,5360mAh天玑7000!堪比旗舰机说到现在家喻户晓的千元机产品,很多人可能都会想到红米Note系列!在全球来看,RedmiNote系列也是销量最高的国产代表,也就是说,在国内和国外市场,RedmiNote都很出名。70亿美元到账,英特尔变卖中国工厂,韩国芯片巨头成为接盘侠文球子审核子扬校对知秋在2020年,SK海力士对英特尔闪存业务签署了收购协议,将接管位于我国大连地区的闪存工厂。这笔交易经过长时间的等待,终于迎来结果,在今年12月22日,我国监管中国科大多项成果入选2021年国内十大科技新闻中安在线中安新闻客户端讯12月26日,由科技日报社主办部分两院院士和媒体人士共同评选出的2021年国内国际十大科技新闻揭晓。中国科大潘建伟院士团队的祖冲之号九章二号量子计算原型机研有得等了!华为Mate50或6月才发布,首发鸿蒙3。0还有两大新科技2021年对于华为来说,无疑近几年来过得最艰难的一年。华为在2021年发布的新机屈指可数,仅有MateX2P50P50ProP50Pocketnova9nova9Pro等新机,而且