SpringBoot教程(十六) | SpringBoot集成swagger(全網(wǎng)最全)

      網(wǎng)友投稿 1111 2025-03-31

      一. 接口文檔概述

      swagger是當(dāng)下比較流行的實(shí)時(shí)接口文文檔生成工具。接口文檔是當(dāng)前前后端分離項(xiàng)目中必不可少的工具,在前后端開發(fā)之前,后端要先出接口文檔,前端根據(jù)接口文檔來進(jìn)行項(xiàng)目的開發(fā),雙方開發(fā)結(jié)束后在進(jìn)行聯(lián)調(diào)測試。

      所以接口文檔其實(shí)就是開發(fā)之前雙方之間的一種約定。通常接口文檔分為離線的和實(shí)時(shí)的。離線的接口文檔工具有: word(相當(dāng)于沒說), YAPI, 小幺雞等,這種文檔需要程序員在上面編寫,也一般具備接口測試功能。通常是由開發(fā)人員先在離線接口文檔上編寫信息,然后交給前端人員參照開發(fā)。最大的弊端是當(dāng)我們的接口程序發(fā)生變動(dòng)時(shí),需要回過頭來維護(hù)上面的內(nèi)容,很麻煩,是真的麻煩。

      實(shí)時(shí)接口文檔就是可以根據(jù)我們的代碼來自動(dòng)生成相應(yīng)的接口文檔,優(yōu)點(diǎn)就是我們的代碼發(fā)生變化時(shí),生成的接口文檔也會(huì)自動(dòng)更新,無需我們關(guān)注修改,主需要按時(shí)發(fā)布即可。但是由于是根據(jù)代碼自動(dòng)生成的,所以最大的弊端就是代碼侵入性強(qiáng),需要我們在項(xiàng)目代碼中集成生成接口文檔的相關(guān)代碼。實(shí)時(shí)接口文檔現(xiàn)在的方案有很多,但是swagger還是其中比較有影響力的一個(gè)。

      二. SpringBoot集成swagger2

      官網(wǎng)地址: swagger.io 當(dāng)然,官網(wǎng)都是英文的,看起來還是比較麻煩的。建議大家直接按照我的步驟來,還是很簡單的。

      同時(shí)在說一點(diǎn): swagger分為swagger2 和swagger3兩個(gè)常用版本。二者區(qū)別不是很大,主要對于依賴和注解進(jìn)行了優(yōu)化。swagger2需要引入2個(gè)jar包,swagger3只需要一個(gè),用起來沒有什么大的區(qū)別。下面以swagger2為例。

      2.1 引入依賴

      io.springfox springfox-swagger2 2.9.2 io.springfox springfox-swagger-ui 2.9.2

      2.2 引入配置

      首先需要添加一個(gè)注解 : @EnableSwagger2。 這個(gè)注解我們可以添加到SpringBoot的啟動(dòng)類上,也可以自定義一個(gè)配置類,放到上面。添加了這個(gè)注解以后,就代表我們已經(jīng)在項(xiàng)目中開啟了Swagger的功能。

      我們采用第二種方式,自己定義一個(gè)配置類,正好還可以添加一個(gè)Docket配置。 所謂Docket配置,就是一組(一個(gè)項(xiàng)目或一個(gè)版本)接口文檔的配置,比如設(shè)置名稱, 聯(lián)系人等等。

      我們在config文件夾下,添加一個(gè)SwaggerConfig類。

      @Configuration @EnableSwagger2 public class SwaggerConfig { /** * 設(shè)置多個(gè): * * @Bean * public Docket appApi() { * * List pars = new ArrayList<>(); * ParameterBuilder token = new ParameterBuilder(); * token.name("token").description("用戶令牌").modelRef(new ModelRef("string")).parameterType("header").required(false) * .build(); * pars.add(token.build()); * * return new Docket(DocumentationType.SWAGGER_2).select().paths(regex("/app/.*")).build() * .globalOperationParameters(pars).apiInfo(pdaApiInfo()).useDefaultResponseMessages(false) * .enable(enableSwagger) * .groupName("appApi"); * * } * * @Bean * public Docket adminApi() { * * List pars = new ArrayList<>(); * ParameterBuilder token = new ParameterBuilder(); * token.name("token").description("用戶令牌").modelRef(new ModelRef("string")).parameterType("header").required(false) * .build(); * pars.add(token.build()); * return new Docket(DocumentationType.SWAGGER_2).select().paths(regex("/admin/.*")).build() * .globalOperationParameters(pars).apiInfo(pdaApiInfo()).useDefaultResponseMessages(false) * .enable(enableSwagger) * .groupName("adminApi"); * * } * * * @return */ @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.basePackage("com.lsqingfeng.action.swagger.controller")).paths(PathSelectors.any()) .build().globalOperationParameters(setHeaderToken()); } private ApiInfo apiInfo() { return new ApiInfoBuilder().title("action-swagger").description("swagger實(shí)戰(zhàn)").termsOfServiceUrl("") .version("1.0").build(); } /** * @Description: 設(shè)置swagger文檔中全局參數(shù) * @param * @Date: 2020/9/11 10:15 * @return: java.util.List */ private List setHeaderToken() { List pars = new ArrayList<>(); ParameterBuilder userId = new ParameterBuilder(); userId.name("token").description("用戶TOKEN").modelRef(new ModelRef("string")).parameterType("header") .required(true).build(); pars.add(userId.build()); return pars; } }

      上面就是一個(gè)配置案例, 還設(shè)置了一個(gè)setToken方法,代表生成文檔的所有接口中,都要包含一個(gè)header類型的token參數(shù)。

      2.3 給Controller 添加注解

      我們接口文檔的直接描述主要就是在Controller這一層,比如這個(gè)接口的功能,參數(shù)的名稱,返回值的名稱等。這些值我們都需要在Controller上通過給方法上,請求參數(shù)和返回參數(shù)上添加對應(yīng)的注解,swagger才能幫我們生成相應(yīng)的接口文檔。這也就是我前面提到的對現(xiàn)有代碼的侵入性。

      我們來寫一個(gè)案例。

      首先先創(chuàng)建一個(gè)vo的包,里邊寫我們的請求和相應(yīng)參數(shù),使用JavaBean定義出請求和響應(yīng)的數(shù)據(jù)結(jié)構(gòu)。注意這里要添加相應(yīng)的注解:

      請求類:

      package com.lsqingfeng.springboot.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @className: SwaggerReqVO * @description: * @author: sh.Liu * @date: 2022-03-22 19:19 */ @Data @ApiModel("創(chuàng)建Swagger請求參數(shù)") public class SwaggerReqVO { @ApiModelProperty("id") private Integer id; @ApiModelProperty("姓名") private String name; @ApiModelProperty("性別") private Integer gender; }

      響應(yīng)類:

      package com.lsqingfeng.springboot.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @className: SwaggerResVO * @description: * @author: sh.Liu * @date: 2022-03-22 19:20 */ @Data @ApiModel("創(chuàng)建Swagger響應(yīng)結(jié)果") public class SwaggerResVO { @ApiModelProperty("id") private Integer id; @ApiModelProperty("姓名") private String name; @ApiModelProperty("性別") private Integer gender; @ApiModelProperty("啥啥") private String what; }

      這里分別使用了 @ApiModel注解和 @@ApiModelProperty 注解定義了實(shí)體的名稱和字段的名稱,方便生成接口文檔時(shí)展示。

      再來看Controller:

      package com.lsqingfeng.springboot.controller; import com.lsqingfeng.springboot.vo.SwaggerReqVO; import com.lsqingfeng.springboot.vo.SwaggerResVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; /** * @className: SwaggerController * @description: swagger 接口測試 * @author: sh.Liu * @date: 2022-03-22 19:18 */ @RestController @RequestMapping("/swagger") @Api(value = "用戶接口", tags = {"用戶接口"}) public class SwaggerController { @ApiOperation("新增用戶") @PostMapping("save") public String save(@RequestBody SwaggerReqVO req) { return "success"; } @GetMapping("getById") @ApiOperation("根據(jù)條件查詢用戶") public SwaggerResVO getById(@RequestBody SwaggerResVO req) { return new SwaggerResVO(); } }

      這里使用了@Api注解和 @ApiOperation注解分別標(biāo)注了接口組名和接口的名稱。現(xiàn)在我們啟動(dòng)項(xiàng)目。

      發(fā)現(xiàn)報(bào)了這個(gè)錯(cuò)誤。

      上網(wǎng)查詢原因說是SpringBoot2.6版本和Swagger2.9.2不兼容導(dǎo)致的。 也有人說是由于guava這個(gè)包的版本過低導(dǎo)致的。

      我都分別試了一下,替換了guava的高版本依賴問題還是存在。

      這個(gè)問題的主要原因確實(shí)是SpringBoot版本過高導(dǎo)致。如果你用的是SpringBoot2.5.x及之前版本是沒有問題的。

      Spring Boot 2.6.X使用PathPatternMatcher匹配路徑,Swagger引用的Springfox使用的路徑匹配是基于AntPathMatcher的。

      所以要想解決,添加配置,將springBoot MVC的路勁匹配模式修改一下即可。

      在springBoot配置文件中添加配置:

      spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER 復(fù)制代碼

      如果是yml格式的配置文件:

      再次啟動(dòng)問題解決。

      訪問地址: ip:端口號/swagger-ui.html

      正常情況就可以看到我們的界面了。一會(huì)再說非正常情況。由于我們只給用戶接口添加了注解,所有用戶接口是可以直接觀察中文文檔的。而剩下的兩個(gè)接口,由于沒添加注解,所以都是以默認(rèn)的形式展示的。

      點(diǎn)開接口,我們可以看到接口中的想詳細(xì)信息

      點(diǎn)擊model,可以看到字段的中文描述。點(diǎn)擊 Try it out,就可以直接調(diào)試接口。同時(shí)注意接口中都讓填一個(gè)token,這就是我們之前的設(shè)置成效了。

      截止到目前其實(shí)swagger的集成就已經(jīng)完畢了,主要就是根據(jù)我們的注解生成文檔,并且可以在線調(diào)用調(diào)試。開發(fā)的時(shí)候,我們只需要把Controller這一層的請求和響應(yīng),以及方法描述等內(nèi)容先開發(fā)完畢,就可以提供給前端讓他們參照開發(fā)了。

      2.4 [404]問題解決

      正常情況我們按照上面的步驟就可以出現(xiàn)頁面,但是有些時(shí)候可能是由于springBoot的版本過高導(dǎo)致的,我們輸入之前的地址,出現(xiàn)404的情況,這個(gè)主要是由于項(xiàng)目中無法讀取到swagger依賴包下的頁面導(dǎo)致的。如果出現(xiàn)了這個(gè)問題,我們可以添加一個(gè)配置類,讓他實(shí)現(xiàn)WebMvcConfigurer 接口,在添加一個(gè)方法:

      @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); }

      完整代碼如下:

      package com.lsqingfeng.springboot.config; import com.lsqingfeng.springboot.interceptor.TokenInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @className: WebMvcConfig * @description:webMvc配置 * @author: sh.Liu * @date: 2022-01-13 09:51 */ @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } }

      這個(gè)時(shí)候在啟動(dòng)就可以了!

      2.5 替換UI

      上面的整個(gè)過程已經(jīng)完成了,但是生成的接口文檔的頁面,其實(shí)很多人不太喜歡,覺得不太符合國人的使用習(xí)慣,所有又有一些大神,提供了其他的UI測試頁面。這個(gè)頁面的使用還是比較廣泛的。

      修改方式:只需引入一個(gè)依賴包:

      com.github.xiaoymin swagger-bootstrap-ui 1.9.6

      然后把剛才實(shí)現(xiàn)的那個(gè)的那個(gè)方法再添加一條:

      registry.addResourceHandler("doc.html") .addResourceLocations("classpath:/META-INF/resources/");

      完成代碼:

      package com.lsqingfeng.springboot.config; import com.lsqingfeng.springboot.interceptor.TokenInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @className: WebMvcConfig * @description:webMvc配置 * @author: sh.Liu * @date: 2022-01-13 09:51 */ @Configuration public class WebMvcConfig implements WebMvcConfigurer { // @Override // public void addInterceptors(InterceptorRegistry registry) { // //攔截 // registry.addInterceptor(new TokenInterceptor()) // .addPathPatterns("/**") // .excludePathPatterns("/login"); // } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); registry.addResourceHandler("doc.html") .addResourceLocations("classpath:/META-INF/resources/"); } }

      重新啟動(dòng)項(xiàng)目: 訪問路徑發(fā)生了變化:** ip:端口號/doc.html**

      頁面出現(xiàn)了。我們在看看我們的用戶接口:

      這個(gè)風(fēng)格確實(shí)更加的直觀,同時(shí)也是可以直接進(jìn)行調(diào)試的。大部分的swagger都用的這個(gè)風(fēng)格的文檔。

      三. SpringBoot集成swagger3

      上面已經(jīng)很詳細(xì)的講解了swagger2的集成方式,而swagger3的集成方式更加的簡潔一些。

      首先引入依賴:

      io.springfox springfox-boot-starter 3.0.0

      然后是替換注解: swagger2使用的開啟注解是: @EnableSwagger2

      而在swagger3中,這個(gè)注解要換成: @EnableOpenApi

      配置類:

      import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.oas.annotations.EnableOpenApi; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; @Configuration public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.OAS_30) // v2 不同 .select() .apis(RequestHandlerSelectors.basePackage("com.example.swaggerv3.controller")) // 設(shè)置掃描路徑 .build(); } }

      要注意,里邊的版本類型換成了 OAS_30, 就是swagger3的意思。

      OAS 是 OpenAPI Specification 的簡稱,翻譯成中文就是 OpenAPI 說明書。

      同時(shí)訪問地址:原始地址,也就是沒換UI的地址: localhost:8080/swagger-ui/index.html這個(gè)要和swagger2區(qū)分開。

      swagger3的原始UI風(fēng)格也發(fā)生了一些變化:

      同時(shí)swagger3也是可以更換UI的。方法和swagger2一樣。

      四. swaggerUI -和跨域沖突處理

      如果我們的項(xiàng)目中有關(guān)于跨域的處理,同時(shí)還有-,然后還要使用swagger,這種情況大家要注意了,有可能我們的-會(huì)將swagger中的頁面路徑攔截掉導(dǎo)致swagger頁面出不來,當(dāng)我們在-中把swagger的頁面排除掉的時(shí)候,也有可能會(huì)導(dǎo)致跨域配置的失效。

      詳細(xì)的解決方案可以看我之前寫過的一篇博客: lsqingfeng.blog.csdn.net/article/det…

      具體解決方案簡單提一下:

      -:

      /** * -配置 * * @author liuShuai */ @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Bean public TokenInterceptor tokenInterceptor() { return new TokenInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry .addInterceptor(tokenInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/user/login") .excludePathPatterns("/user/downloadExcel") .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } }

      SpringBoot教程(十六) | SpringBoot集成swagger(全網(wǎng)最全)

      跨域配置:

      import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /** * @className: CorsConfig * @description: * @author: sh.Liu * @date: 2020-12-02 10:16 */ @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); config.setAllowCredentials(true); config.addAllowedMethod("*"); config.addAllowedHeader("*"); UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**", config); return new CorsFilter(configSource); } }

      用這兩種方式去配置,就可以讓他們和平共處了。

      另: 配套項(xiàng)目代碼已托管中g(shù)itCode: gitcode.net/lsqingfeng/…

      分支: feautre/MybatisPlus

      所有文章也會(huì)在微信公眾號首發(fā)更新,歡迎關(guān)注: 一縷82年的清風(fēng)

      Spring Boot

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:怎樣手機(jī)wps中使用表格樣式(手機(jī)版wps表格怎么設(shè)置文本格式)
      下一篇:怎么把pdf文件以圖片形式放到word文檔里(如何將pdf作為圖片放在word里)
      相關(guān)文章
      亚洲校园春色另类激情| 亚洲国产精品成人AV在线| www.亚洲一区| 亚洲女女女同性video| 国产精品亚洲自在线播放页码 | 亚洲国产综合专区电影在线 | 精品日韩99亚洲的在线发布| 亚洲午夜久久久精品电影院| 亚洲午夜精品一区二区公牛电影院 | 久久久久亚洲Av片无码v| 久久精品国产亚洲av麻| 亚洲成人激情在线| 久久亚洲精品无码aⅴ大香| 亚洲精品美女在线观看| 亚洲人成片在线观看| 亚洲毛片基地4455ww| 亚洲七久久之综合七久久| 日韩欧美亚洲中文乱码| 日韩亚洲国产综合久久久| 亚洲第一永久AV网站久久精品男人的天堂AV | 色噜噜综合亚洲av中文无码| 78成人精品电影在线播放日韩精品电影一区亚洲 | 亚洲色中文字幕无码AV| 亚洲国产成人精品无码区在线观看| 亚洲国产成人精品无码区在线观看| 亚洲ⅴ国产v天堂a无码二区| 亚洲视频一区二区在线观看| 久久精品亚洲AV久久久无码| 亚洲第一综合天堂另类专| 亚洲А∨精品天堂在线| 在线观看亚洲av每日更新| 久久久久久亚洲精品| 亚洲天堂福利视频| 亚洲综合激情五月丁香六月| 日本亚洲高清乱码中文在线观看| 亚洲人成色77777在线观看大| 亚洲精品一品区二品区三品区| 亚洲AV无码久久| 亚洲日产2021三区在线| 亚洲熟女www一区二区三区| 亚洲成人国产精品|