【實戰】記一次老專案的swagger整合

mu_阿成發表於2020-10-30

1.背景

這兩天接到一個整合swagger的任務,本以為很簡單,預計兩小時內完成,沒想到其中有太多的坑,整了兩天才完成。
首先專案是一個比較老的專案,之前用的servlet,目前在重構為springmvc。所以有一部分servlet,一部分springmvc。spring配置方面也有很多不規範的地方,這也為我後面踩坑埋下伏筆。

2.坑坑

2.1 spring版本

專案用的spring版本為4.3.1,在引入springfox-swagger2和springfox-swagger-ui後專案啟動報錯。原因是springfox-swagger2在整合的時候,已經引入了spring的相關jar,且與專案中的spring版本不一致,導致了衝突,需要排除掉swagger中的spring依賴

<dependency> 
            <groupId>io.springfox</groupId> 
            <artifactId>springfox-swagger2</artifactId> 
            <version>2.4.0</version> 
            <exclusions> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-core</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-beans</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-context</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-context-support</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-aop</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-tx</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-orm</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-jdbc</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-web</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-webmvc</artifactId> 
                </exclusion> 
                <exclusion> 
                    <groupId>org.springframework</groupId> 
                    <artifactId>spring-oxm</artifactId> 
                </exclusion> 
            </exclusions> 
        </dependency> 
        <dependency> 
            <groupId>io.springfox</groupId> 
            <artifactId>springfox-swagger-ui</artifactId> 
            <version>2.4.0</version> 
        </dependency> 

2.2 web.xml

加swagger依賴,加swagger配置,加swagger註解後。啟動,訪問http://xxxx:8080/platform_web/swagger-ui.html#/ ,頁面空白,F12...404了
說明請求沒有被轉發。去web.xml看一眼dispatcherservlet怎麼配的,發現url-pattern是.do。額,沒有匹配呀,那我自己寫吧。總不能把人家的改成/

<servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
        <!-- 為swagger配置額外的pattern-->
        <url-pattern>/v2/api-docs</url-pattern>
        <url-pattern>/v2/api-docs-ext</url-pattern>
        <url-pattern>/configuration/security</url-pattern>
        <url-pattern>/configuration/ui</url-pattern>
        <url-pattern>/swagger-resources</url-pattern>
        <url-pattern>/swagger-resources/configuration/security</url-pattern>
        <url-pattern>/swagger-resources/configuration/ui</url-pattern>
    </servlet-mapping>

2.3 spring配置,springmvc配置(配置不規範,重構兩行淚)

再啟動,文件描述出來了,但介面還沒有內容...F12看請求資源,全是200,所以不是資源請求的問題。但是我swagger請求中配置了掃描包,包裡的類也加上了swagger註釋了呀。.apis(RequestHandlerSelectors.basePackage("work")) //掃描的包。說明沒掃描到包或者說沒拿到包中的依賴。看一下spring配置檔案,確實配置了,spring容器肯定有這些bean。springmvc配置檔案中並沒有包掃描的配置。嚴格的說controller應該註冊在springmvc容器中,但在spring容器中也不是不可以呀,spirng和springmvc是父子容器的關係,springmvc應該能正常的拿到spring容器中的bean呀。百度大法後,發現swagger好像比較傲嬌,它只從springmvc容器中拿bean...好吧,那我把controller的bean調整到springmvc容器吧,同時移除掉spring容器中的controller(注意:swaggerconfig也應該註冊在springmvc容器中)
(1)spring

 <!--排除掉swagger和controller-->
    <context:component-scan base-package="work,core,projectcore">
        <context:exclude-filter type="regex" expression="work.actionv.*" />
        <context:exclude-filter type="assignable" expression="swaggerConfig.SwaggerConfig"/>
    </context:component-scan>

(2)springmvc

<!--注入controller-->
	<context:component-scan base-package="work" use-default-filters="false">
		<context:include-filter type="regex" expression="work.actionv.*"/>
	</context:component-scan>
	<!--SwaggerConfig配置類注入-->
	<bean id="swaggerConfig" class="swaggerConfig.SwaggerConfig"/>

2.4 只顯示一個介面(google大法好)

重啟,介面列表出來了,但只有一個介面是什麼鬼,我明明每個方法上都有註解啊。觀察程式碼,發現由於每個mapping的url都相同,只是通過引數method來區分的

百度後得知swagger(openapi)的資料結構就是 path -> method -> operation ,沒有通過引數區分的方式,所以多個url相同時只展示一條,也只有零星的幾個帖子提到這個情況,而且大家一致認為沒有什麼好的解決方案。但我還不服氣,google了一下發現了一種解決方案:docket配置enableUrlTemplating,[Springfox not generating different swagger entries for operations with same base path, but one endpoint has query parameters]

相關文章