成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

淺談springfox-swagger原理解析與使用過(guò)程中遇到的坑

swagger簡(jiǎn)介

創(chuàng)新互聯(lián)是專業(yè)的浉河網(wǎng)站建設(shè)公司,浉河接單;提供網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行浉河網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

swagger確實(shí)是個(gè)好東西,可以跟據(jù)業(yè)務(wù)代碼自動(dòng)生成相關(guān)的api接口文檔,尤其用于restful風(fēng)格中的項(xiàng)目,開(kāi)發(fā)人員幾乎可以不用專門(mén)去維護(hù)rest api,這個(gè)框架可以自動(dòng)為你的業(yè)務(wù)代碼生成restfut風(fēng)格的api,而且還提供相應(yīng)的測(cè)試界面,自動(dòng)顯示json格式的響應(yīng)。大大方便了后臺(tái)開(kāi)發(fā)人員與前端的溝通與聯(lián)調(diào)成本。

springfox-swagger簡(jiǎn)介

簽于swagger的強(qiáng)大功能,java開(kāi)源界大牛spring框架迅速跟上,它充分利用自已的優(yōu)勢(shì),把swagger集成到自己的項(xiàng)目里,整了一個(gè)spring-swagger,后來(lái)便演變成springfox。springfox本身只是利用自身的aop的特點(diǎn),通過(guò)plug的方式把swagger集成了進(jìn)來(lái),它本身對(duì)業(yè)務(wù)api的生成,還是依靠swagger來(lái)實(shí)現(xiàn)。

關(guān)于這個(gè)框架的文檔,網(wǎng)上的資料比較少,大部分是入門(mén)級(jí)的簡(jiǎn)單使用。本人在集成這個(gè)框架到自己項(xiàng)目的過(guò)程中,遇到了不少坑,為了解決這些坑,我不得不扒開(kāi)它的源碼來(lái)看個(gè)究竟。此文,就是記述本人在使用springfox過(guò)程中對(duì)springfox的一些理解以及需要注意的地方。

springfox大致原理

springfox的大致原理就是,在項(xiàng)目啟動(dòng)的過(guò)種中,spring上下文在初始化的過(guò)程,框架自動(dòng)跟據(jù)配置加載一些swagger相關(guān)的bean到當(dāng)前的上下文中,并自動(dòng)掃描系統(tǒng)中可能需要生成api文檔那些類,并生成相應(yīng)的信息緩存起來(lái)。如果項(xiàng)目MVC控制層用的是springMvc那么會(huì)自動(dòng)掃描所有Controller類,跟據(jù)這些Controller類中的方法生成相應(yīng)的api文檔。

因本人的項(xiàng)目就是SpringMvc,所以此文就以Srping mvc集成springfox為例來(lái)討論springfox的使用與原理。

SpringMvc集成springfox的步驟

首先,項(xiàng)目需要加入以下三個(gè)依賴:

<!-- sring mvc依賴 -->

   <dependency>

     <groupId>org.springframework</groupId>

     <artifactId>spring-webmvc</artifactId>

     <version>4.2.8.RELEASE</version>

   </dependency>

<!-- swagger2核心依賴 -->

   <dependency>

     <groupId>io.springfox</groupId>

     <artifactId>springfox-swagger2</artifactId>

     <version>2.6.1</version>

   </dependency>

   <!-- swagger-ui為項(xiàng)目提供api展示及測(cè)試的界面 -->

   <dependency>

     <groupId>io.springfox</groupId>

     <artifactId>springfox-swagger-ui</artifactId>

     <version>2.6.1</version>

   </dependency>

上面三個(gè)依賴是項(xiàng)目集成springmvc及springfox最基本的依賴,其它的依賴這里省略。其中第一個(gè)是springmvc的基本依賴,第二個(gè)是swagger依賴,第三個(gè)是界面相關(guān)的依賴,這個(gè)不是必須的,如果你不想用springfox自帶的api界面的話,也可以不用這個(gè),而另外自己寫(xiě)一套適合自己項(xiàng)目的界面。加入這幾個(gè)依賴后,系統(tǒng)后會(huì)自動(dòng)加入一些跟springfox及swagger相關(guān)jar包,我粗略看了一下,主要有以下這么幾個(gè):

springfox-swagger2-2.6.1.jar

swagger-annotations-1.5.10.jar

swagger-models-1.5.10.jar

springfox-spi-2.6.1.jar

springfox-core-2.6.1.jar

springfox-schema-2.6.1.jar

springfox-swagger-common-2.6.1.jar

springfox-spring-web-2.6.1.jar

guava-17.0.jar

spring-plugin-core-1.2.0.RELEASE.jar

spring-plug-metadata-1.2.0.RELEASE.jar

spring-swagger-ui-2.6.1.jar

jackson-databind-2.2.3.jar

jackson-annotations-2.2.3.jar

上面是我通過(guò)目測(cè)覺(jué)得springfox可能需要的jar,可能沒(méi)有完全例出springfox所需的所有jar。從上面 jar可以看出pringfox除了依賴swagger之外,它還需要guava、spring-plug、jackson等依賴包(注意jackson是用于生成json必須的jar包,如果項(xiàng)目里本身沒(méi)有加入這個(gè)依賴,為了集成swagger的話必須額外再加入這個(gè)依賴)。

springfox的簡(jiǎn)單使用

如果只用springfox的默認(rèn)的配置的話,與springmvc集成起來(lái)非常簡(jiǎn)單,只要寫(xiě)一個(gè)類似于以下代碼的類放到你的項(xiàng)目里就行了,代碼如下:

@Configuration

@EnableWebMvc

@EnableSwagger2

publicclass ApiConfig {}

注意到,上面是一個(gè)空的java類文件,類名可以隨意指定,但必須加入上述類中標(biāo)出的@Configuration、@EnableWebMvc、@EnableSwagger2三個(gè)注解,這樣就完成了springmvc與springfox的基本集成,有了三個(gè)注解,項(xiàng)目啟動(dòng)后就可以直接用類似于以下的地址來(lái)查看api列表了:http://127.0.0.1:8080/jadDemo/swagger-ui.html

這確實(shí)是一個(gè)很神奇的效果,簡(jiǎn)單的三個(gè)注解,系統(tǒng)就自動(dòng)顯示出項(xiàng)目里所有Controller類的所有api了。現(xiàn)在,我們就這個(gè)配置類入手,簡(jiǎn)單分析它的原理。這個(gè)類中沒(méi)有任何代碼,很顯然,三個(gè)注解起了至關(guān)重要的作用。其中@Configuration注解是spring框架中本身就有的,它是一個(gè)被@Component元注解標(biāo)識(shí)的注解,所以有了這個(gè)注解后,spring會(huì)自動(dòng)把這個(gè)類實(shí)例化成一個(gè)bean注冊(cè)到spring上下文中。第二個(gè)注解@EnableWebMvc故名思義,就是啟用srpingmvc了,在Eclipse中點(diǎn)到這個(gè)注解里面簡(jiǎn)單看一下,它就是通過(guò)元注解@Import(DelegatingWebMvcConfiguration.class)往spring context中塞入了一個(gè)DelegatingWebMvcConfiguration類型的bean。我想,這個(gè)類的目的應(yīng)該就是為swagger提供了一些springmvc方面的配置吧。第三個(gè)注解:@EnableSwagger2,看名字應(yīng)該可以想到,是用來(lái)集成swagger 2的,他通過(guò)元注解:@Import({Swagger2DocumentationConfiguration.class}),又引入了一個(gè)Swagger2DocumentationConfiguration類型的配置bean,而這個(gè)就是Swagger的核心配置了。它里面的代碼如下:

@Configuration
@Import({ SpringfoxWebMvcConfiguration.class, SwaggerCommonConfiguration.class })
@ComponentScan(basePackages = {
 "springfox.documentation.swagger2.readers.parameter",
  "springfox.documentation.swagger2.web",
  "springfox.documentation.swagger2.mappers"
})

publicclassSwagger2DocumentationConfiguration {
 @Bean
 public JacksonModuleRegistrar swagger2Module() {
  returnnewSwagger2JacksonModule();
 }
}

這個(gè)類頭部通過(guò)一些注解,再引入SpringfoxWebMvcConfiguration類和SwaggerCommonConfiguration類,并通過(guò)ComponentScan注解,自動(dòng)掃描springfox .swagger2相關(guān)的的bean到spring context中。這里,我最感興趣的是SpringfoxWebMvcConfiguration這個(gè)類,這個(gè)類我猜應(yīng)該就是springfox集成mvc比較核心的配置了,點(diǎn)進(jìn)去,看到以下代碼:

@Configuration
@Import({ModelsConfiguration.class })
@ComponentScan(basePackages = {
  "springfox.documentation.spring.web.scanners",
"springfox.documentation.spring.web.readers.operation","springfox.documentation.spring.web.readers.parameter","springfox.documentation.spring.web.plugins","springfox.documentation.spring.web.paths"
})

@EnablePluginRegistries({ DocumentationPlugin.class,
  ApiListingBuilderPlugin.class,
  OperationBuilderPlugin.class,
  ParameterBuilderPlugin.class,
  ExpandedParameterBuilderPlugin.class,
  ResourceGroupingStrategy.class,
  OperationModelsProviderPlugin.class,
  DefaultsProviderPlugin.class,
  PathDecorator.class
})
publicclassSpringfoxWebMvcConfiguration {}

這個(gè)類中下面的代碼,無(wú)非就是通過(guò)@Bean注解再加入一些新的Bean,我對(duì)它的興趣不是很大,我最感興趣的是頭部通過(guò)@EnablePluginRegistries加入的那些東西。springfox是基于spring-plug的機(jī)制整合swagger的,spring-plug具體是怎么實(shí)現(xiàn)的,我暫時(shí)還沒(méi)有時(shí)間去研究spring-plug的原理。但在下文會(huì)提到自己寫(xiě)一個(gè)plug插件來(lái)擴(kuò)展swagger的功能。上面通過(guò)@EnablePluginRegistries加入的plug中,還沒(méi)有時(shí)間去看它全部的代碼,目前我看過(guò)的代碼主要有ApiListingBuilderPlugin.class, OperationBuilderPlugin.class,ParameterBuilderPlugin.class, ExpandedParameterBuilderPlugin.class,

第一個(gè)ApiListingBuilderPlugin,它有兩個(gè)實(shí)現(xiàn)類,分別是ApiListingReader和SwaggerApiListingReader。其中ApiListingReader會(huì)自動(dòng)跟據(jù)Controller類型生成api列表,而SwaggerApiListingReader會(huì)跟據(jù)有@Api注解標(biāo)識(shí)的類生成api列表。OperationBuilderPlugin插件就是用來(lái)生成具體api文檔的,這個(gè)類型的插件,有很多很多實(shí)現(xiàn)類,他們各自分工,各做各的事情,具體我沒(méi)有仔細(xì)去看,只關(guān)注了其中一個(gè)實(shí)現(xiàn)類:OperationParameterReader,這個(gè)類是用于讀取api參數(shù)的Plugin。它依賴于ModelAttributeParameterExpander工具類,可以將Controller中接口方法參數(shù)中非簡(jiǎn)單類型的命令對(duì)像自動(dòng)解析它內(nèi)部的屬性得出包含所有屬性的參數(shù)列表(這里存在一個(gè)可能會(huì)出現(xiàn)無(wú)限遞歸的坑,下文有介紹)。而ExpandedParameterBuilderPlugin插件,主要是用于擴(kuò)展接口參數(shù)的一些功能,比如判斷這個(gè)參數(shù)的數(shù)據(jù)類型以及是否為這個(gè)接口的必須參數(shù)等等。總體上說(shuō),整個(gè)springfox-swagger內(nèi)部其實(shí)是由這一系列的plug轉(zhuǎn)運(yùn)起來(lái)的。他們?cè)谙到y(tǒng)啟動(dòng)時(shí),就被調(diào)起來(lái),有些用來(lái)掃描出接口列表,有些用來(lái)讀取接口參數(shù)等等。他們共同的目地就是把系統(tǒng)中所有api接口都掃描出來(lái),并緩存起來(lái)供用戶查看。那么,這一系列表plug到底是如何被調(diào)起來(lái)的,它們的執(zhí)行入口倒底在哪?

   我們把注意點(diǎn)放到上文SpringfoxWebMvcConfiguration這個(gè)類代碼頭部的ComponentScan注解內(nèi)容上來(lái),這一段注解中掃描了一個(gè)叫springfox.documentation.spring.web.plugins的package,這個(gè)package在springfox-spring-web-2.6.1.jar中可以找到。這個(gè)package下,我們發(fā)現(xiàn)有兩個(gè)非常核心的類,那就是DocumentationPluginsManager和DocumentationPluginsBootstrapper。對(duì)于第一個(gè)DocumentationPluginsManager,它是一個(gè)沒(méi)有實(shí)現(xiàn)任何接口的bean,但它內(nèi)部有諸多PluginRegistry類型的屬性,而且都是通過(guò)@Autowired注解把屬性值注入進(jìn)來(lái)的。接合它的類名來(lái)看,很容易想到,這個(gè)就是管理所有plug的一個(gè)管理器了。很好理解,因?yàn)镃omponentScan注解的配置,所有的plug實(shí)例都會(huì)被spring實(shí)例化成一個(gè)bean,然后被注入到這個(gè)DocumentationPluginsManager實(shí)例中被統(tǒng)一管理起來(lái)。在這個(gè)package中的另一個(gè)重要的類DocumentationPluginsBootstrapper,看名字就可以猜到,他可能就是plug的啟動(dòng)類了。點(diǎn)進(jìn)去看具體時(shí)就可以發(fā)現(xiàn),他果然是一個(gè)被@Component標(biāo)識(shí)了的組件,而且它的構(gòu)造方法中注入了剛剛描述的DocumentationPluginsManager實(shí)例,而且最關(guān)鍵的,它還實(shí)現(xiàn)了SmartLifecycle接口。對(duì)spring bean生命周期有所了解的人的都知道,這個(gè)組件在被實(shí)例化為一個(gè)bean納入srping context中被管理起來(lái)的時(shí)候,會(huì)自動(dòng)調(diào)用它的start()方法。點(diǎn)到start()中看代碼時(shí)就會(huì)發(fā)現(xiàn),它有一行代碼scanDocumentation(buildContext(each));就是用來(lái)掃描api文檔的。進(jìn)一步跟蹤這個(gè)方法的代碼,就可以發(fā)現(xiàn),這個(gè)方法最終會(huì)通過(guò)它的DocumentationPluginsManager屬性把所有plug調(diào)起一起掃描整個(gè)系統(tǒng)并生成api文檔。掃描的結(jié)果,緩存在DocumentationCache這個(gè)類的一個(gè)map屬性中。

   以上就是,srpingMvc整合springfox的大致原理。它主要是通過(guò)EnableSwagger2注解,向srping context注入了一系列bean,并在系統(tǒng)啟動(dòng)的時(shí)候自動(dòng)掃描系統(tǒng)的Controller類,生成相應(yīng)的api信息并緩存起來(lái)。此外,它還注入了一些被@Controller注解標(biāo)識(shí)的Controller類,作為ui模塊訪問(wèn)api列表的入口。比如springfox-swagger2-2.6.1.jar包中的Swagger2Controller類。這個(gè)Controller就是ui模塊中用來(lái)訪問(wèn)api列表的界面地址。在訪問(wèn)http://127.0.0.1:8080/jadDemo/swagger-ui.html這個(gè)地址查看api列表時(shí),通過(guò)瀏覽器抓包就可以看到,它是通過(guò)類似于http://127.0.0.1:8080/jadDemo/v2/api-docs?group=sysGroup這樣的地址異步獲得api信息(Json格式)并顯示到界面上,這個(gè)地址后臺(tái)對(duì)應(yīng)的Controller入口就是上文的Swagger2Controller類,這個(gè)類收到請(qǐng)求后,直接從事先初始化好的緩存中的取出api信息生成json字符串返回。

了解了springfox的原理,下面來(lái)看看springfox使用過(guò)程中,我遇到的哪些坑。

springfox第一大坑:配置類生成的bean必須與spring mvc共用同一個(gè)上下文。

前文描述了,在springmvc項(xiàng)目中,集成springfox是只要在項(xiàng)目寫(xiě)一個(gè)如下的沒(méi)有任何業(yè)務(wù)代碼的簡(jiǎn)單配置類就可以了。

@Configuration
@EnableWebMvc
@EnableSwagger2
publicclass ApiConfig {
}

因?yàn)锧Configuration注解的作用,spring會(huì)自動(dòng)把它實(shí)例化成一個(gè)bean注入到上下文。但切記要注意的一個(gè)坑就是:這個(gè)bean所在的上下文必須跟spring mvc為同一個(gè)上下文。怎么解理呢?因?yàn)樵趯?shí)際的spring mvc項(xiàng)目中,通常有兩個(gè)上下文,一個(gè)是跟上下文,另一個(gè)是spring mvc(它是跟上下文的子上下文)。其中跟上下文是就是web.xml文件中跟spring相關(guān)的那個(gè)org.springframework.web.context.request.RequestContextListener監(jiān)聽(tīng)器,加載起來(lái)的上下文,通常我們會(huì)寫(xiě)一個(gè)叫spring-contet.xml的配置文件,這里面的bean最終會(huì)初始化到跟上下文中,它主要包括系統(tǒng)里面的service,dao等bean,也包括數(shù)據(jù)源、事物等等。而另一個(gè)上下文是就是spring mvc了,它通過(guò)web.xml中跟spring mvc相關(guān)的那個(gè)org.springframework.web.servlet.DispatcherServlet加載起來(lái),他通常有一個(gè)配置文件叫spring-mvc.xml。我們?cè)趯?xiě)ApiConfig這個(gè)類時(shí),如果決定用@Configuration注解來(lái)加載,那么就必須保證這個(gè)類所在的路徑剛好在springmvc的component-scan的配置的base-package范圍內(nèi)。因?yàn)樵贏piConfig在被spring加載時(shí),會(huì)注入一列系列的bean,而這些bean中,為了能自動(dòng)掃描出所有Controller類,有些bean需要依賴于SpringMvc中的一些bean,如果項(xiàng)目把Srpingmvc的上下文與跟上下文分開(kāi)來(lái),作為跟上下文的子上下文的話。如果不小心讓這個(gè)ApiConfig類型的bean被跟上文加載到,因?yàn)閞oot context中沒(méi)有spring mvc的context中的那些配置類時(shí)就會(huì)報(bào)錯(cuò)。

實(shí)事上,我并不贊成通過(guò)@Configuration注解來(lái)配置Swagger,因?yàn)槲艺J(rèn)為,Swagger的api功能對(duì)于生產(chǎn)項(xiàng)目來(lái)說(shuō)是可有可無(wú)的。我們Swagger往往是用于測(cè)試環(huán)境供項(xiàng)目前端團(tuán)隊(duì)開(kāi)發(fā)或供別的系統(tǒng)作接口集成使上。系統(tǒng)上線后,很可能在生產(chǎn)系統(tǒng)上隱藏這些api列表。 但如果配置是通過(guò)@Configuration注解寫(xiě)死在java代碼里的話,那么上線的時(shí)候想去掉這個(gè)功能的時(shí)候,那就尷尬了,不得不修改java代碼重新編譯。基于此,我推薦的一個(gè)方法,通過(guò)spring最傳統(tǒng)的xml文件配置方式。具體做法就是去掉@Configuration注解,然后它寫(xiě)一個(gè)類似于<bean class="com.jad.web.mvc.swagger.conf.ApiConfig"/>這樣的bean配置到spring的xml配置文件中。在root context與mvc的context分開(kāi)的項(xiàng)目中,直接配置到spring-mvc.xml中,這樣就保證了它跟springmvc 的context一定處于同一個(gè)context中。

springfox第二大坑:Controller類的參數(shù),注意防止出現(xiàn)無(wú)限遞歸的情況。

Spring mvc有強(qiáng)大的參數(shù)綁定機(jī)制,可以自動(dòng)把請(qǐng)求參數(shù)綁定為一個(gè)自定義的命令對(duì)像。所以,很多開(kāi)發(fā)人員在寫(xiě)Controller時(shí),為了偷懶,直接把一個(gè)實(shí)體對(duì)像作為Controller方法的一個(gè)參數(shù)。比如下面這個(gè)示例代碼:

@RequestMapping(value = "update")
public String update(MenuVomenuVo, Model model){
}

這是大部分程序員喜歡在Controller中寫(xiě)的修改某個(gè)實(shí)體的代碼。在跟swagger集成的時(shí)候,這里有一個(gè)大坑。如果MenuVo這個(gè)類中所有的屬性都是基本類型,那還好,不會(huì)出什么問(wèn)題。但如果這個(gè)類里面有一些其它的自定義類型的屬性,而且這個(gè)屬性又直接或間接的存在它自身類型的屬性,那就會(huì)出問(wèn)題。例如:假如MenuVo這個(gè)類是菜單類,在這個(gè)類時(shí)又含有MenuVo類型的一個(gè)屬性parent代表它的父級(jí)菜單。這樣的話,系統(tǒng)啟動(dòng)時(shí)swagger模塊就因無(wú)法加載這個(gè)api而直接報(bào)錯(cuò)。報(bào)錯(cuò)的原因就是,在加載這個(gè)方法的過(guò)程中會(huì)解析這個(gè)update方法的參數(shù),發(fā)現(xiàn)參數(shù)MenuVo不是簡(jiǎn)單類型,則會(huì)自動(dòng)以遞歸的方式解釋它所有的類屬性。這樣就很容易陷入無(wú)限遞歸的死循環(huán)。

為了解決這個(gè)問(wèn)題,我目前只是自己寫(xiě)了一個(gè)OperationParameterReader插件實(shí)現(xiàn)類以及它依賴的ModelAttributeParameterExpander工具類,通過(guò)配置的方式替換掉到srpingfox原來(lái)的那兩個(gè)類,偷梁換柱般的把參數(shù)解析這個(gè)邏輯替換掉,并避開(kāi)無(wú)限遞歸。當(dāng)然,這相當(dāng)于是一種修改源碼級(jí)別的方式。我目前還沒(méi)有找到解決這個(gè)問(wèn)題的更完美的方法,所以,只能建議大家在用spring-fox Swagger的時(shí)候盡量避免這種無(wú)限遞歸的情況。畢竟,這不符合springmvc命令對(duì)像的規(guī)范,springmvc參數(shù)的命令對(duì)像中最好只含有簡(jiǎn)單的基本類型屬性。

springfox第三大坑:api分組相關(guān),Docket實(shí)例不能延遲加載

springfox默認(rèn)會(huì)把所有api分成一組,這樣通過(guò)類似于http://127.0.0.1:8080/jadDemo/swagger-ui.html這樣的地址訪問(wèn)時(shí),會(huì)在同一個(gè)頁(yè)面里加載所有api列表。這樣,如果系統(tǒng)稍大一點(diǎn),api稍微多一點(diǎn),頁(yè)面就會(huì)出現(xiàn)假死的情況,所以很有必要對(duì)api進(jìn)行分組。api分組,是通過(guò)在ApiConf這個(gè)配置文件中,通過(guò)@Bean注解定義一些Docket實(shí)例,網(wǎng)上常見(jiàn)的配置如下:

@EnableWebMvc
@EnableSwagger2
publicclass ApiConfig {
@Bean
 public Docket customDocket() {
    return newDocket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
  }
}

上述代碼中通過(guò)@Bean注入一個(gè)Docket,這個(gè)配置并不是必須的,如果沒(méi)有這個(gè)配置,框架會(huì)自己生成一個(gè)默認(rèn)的Docket實(shí)例。這個(gè)Docket實(shí)例的作用就是指定所有它能管理的api的公共信息,比如api版本、作者等等基本信息,以及指定只列出哪些api(通過(guò)api地址或注解過(guò)濾)。

Docket實(shí)例可以有多個(gè),比如如下代碼:

@EnableWebMvc
@EnableSwagger2
publicclass ApiConfig {
@Bean
 public Docket customDocket1() {
    return newDocket(DocumentationType.SWAGGER_2)
.groupName("apiGroup1").apiInfo(apiInfo()).select()

.paths(PathSelectors.ant("/sys/**"));

  }

@Bean
 public Docket customDocket2() {
    return newDocket(DocumentationType.SWAGGER_2)
.groupName("apiGroup2").apiInfo(apiInfo())
.select()
.paths(PathSelectors.ant("/shop/**"));
  }
}

當(dāng)在項(xiàng)目中配置了多個(gè)Docket實(shí)例時(shí),也就可以對(duì)api進(jìn)行分組了,比如上面代碼將api分為了兩組。在這種情況下,必須給每一組指定一個(gè)不同的名稱,比如上面代碼中的"apiGroup1"和"apiGroup2",每一組可以用paths通過(guò)ant風(fēng)格的地址表達(dá)式來(lái)指定哪一組管理哪些api。比如上面配置中,第一組管理地址為/sys/開(kāi)頭的api第二組管理/shop/開(kāi)頭的api。當(dāng)然,還有很多其它的過(guò)濾方式,比如跟據(jù)類注解、方法注解、地址正則表達(dá)式等等。分組后,在api 列表界面右上角的下拉選項(xiàng)中就可以選擇不同的api組。這樣就把項(xiàng)目的api列表分散到不同的頁(yè)面了。這樣,即方便管理,又不致于頁(yè)面因需要加載太多api而假死。

然而,同使用@Configuration一樣,我并不贊成使用@Bean來(lái)配置Docket實(shí)例給api分組。因?yàn)檫@樣,同樣會(huì)把代碼寫(xiě)死。所以,我推薦在xml文件中自己配置Docket實(shí)例實(shí)現(xiàn)這些類似的功能。當(dāng)然,考慮到Docket中的眾多屬性,直接配置bean比較麻煩,可以自己為Docket寫(xiě)一個(gè)FactoryBean,然后在xml文件中配置FactoryBean就行了。然而將Docket配置到xml中時(shí)。又會(huì)遇到一個(gè)大坑,就那是,spring對(duì)bean的加載方式默認(rèn)是延遲加載的,在xml中直接配置這些Docket實(shí)例Bean后。你會(huì)發(fā)現(xiàn),沒(méi)有一點(diǎn)效果,頁(yè)面左上角的下拉列表中跟本沒(méi)有你的分組項(xiàng)。

這個(gè)問(wèn)題曾困擾過(guò)我好幾個(gè)小時(shí),后來(lái)憑經(jīng)驗(yàn)推測(cè)出可能是因?yàn)閟ping bean默認(rèn)延遲加載,這個(gè)Docket實(shí)例還沒(méi)加載到spring context中。實(shí)事證明,我的猜測(cè)是對(duì)的。我不知道這算是springfox的一個(gè)bug,還是因?yàn)槲腋静辉摪褜?duì)Docket的配置從原來(lái)的java代碼中搬到xml配置文件中來(lái)。

springfox其它的坑:springfox還有些其它的坑,比如@ApiOperation注解中,如果不指定httpMethod屬性具體為某個(gè)get或post方法時(shí),api列表中,會(huì)它get,post,delete,put等所有方法都列出來(lái),搞到api列表重復(fù)的太多,很難看。另外,還有在測(cè)試時(shí),遇到登錄權(quán)限問(wèn)題,等等。這一堆堆的比較容易解決的小坑,因?yàn)槠邢?,我就不多說(shuō)了。還有比如@Api、@ApiOperation及@ApiParam等等注解的用法,網(wǎng)上很多這方面的文檔,我就不重復(fù)了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

分享名稱:淺談springfox-swagger原理解析與使用過(guò)程中遇到的坑
標(biāo)題網(wǎng)址:http://jinyejixie.com/article18/ggsdgp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、、標(biāo)簽優(yōu)化、微信公眾號(hào)、搜索引擎優(yōu)化網(wǎng)站導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
普定县| 平湖市| 永登县| 丹江口市| 潼关县| 阿巴嘎旗| 固安县| 宝鸡市| 新乡县| 新巴尔虎右旗| 拉萨市| 佛山市| 和龙市| 景洪市| 金乡县| 江孜县| 盘山县| 广州市| 石景山区| 江津市| 奈曼旗| 漳浦县| 中宁县| 波密县| 青河县| 乐亭县| 台安县| 汝州市| 全南县| 罗田县| 胶州市| 冷水江市| 刚察县| 皋兰县| 奉节县| 长沙县| 连云港市| 嘉善县| 澜沧| 普宁市| 宜兴市|