集成Swagger的問題(swagger-resources/configuration/ui 404、彈窗等)解決

一、背景

         關於swagger的特性功能,用過的人都很清楚,確實也好用。可以參考http://springfox.github.io/springfox/docs/current/。另外關於swagger的使用集成,其實比較簡單,網上博客也不少。尤其是SpringBoot出現後,集成更爲簡單方便。當然有時候也會遇到一些問題,以前集成過幾次,都很順手,但這次卻遇到麻煩。

 

二、問題

        這次swagger的集成,是在原有項目的基礎上進行的。開始是打開不了頁面,後面能打開了卻出不來接口的內容。換過swagger的版本,但仍然不行,網上的資料也看過,還是不能解決。嘗試了幾次之後,終於成功!

        出現的問題主要有以下幾種:

  1. swagger-ui.html頁面打不開;
  2. swagger-ui.html頁面打開後,接口的內容出不來;
  3. swagger-resources/configuration/ui報404錯誤;
  4. 換成高一點的版本後,打開swagger-ui.html頁面時彈窗。

       其中比較接近的一些是出現了下面的頁面(下面的圖經過處理了,有點模糊),只是接口的信息沒有列出來。

 

三、問題的分析與解決

3.1 問題分析

        在分析問題時,肯定是要結合項目自身的情況。要清楚項目用了哪些框架,這些框架結合時,哪些地方可能會有影響等。也要清楚swagger本身的一些信息,知道它的結構目錄。大概原理等。當然遇到簡單的問題的話,可以不需要知道這些,但這次解決確實是分析了幾方面的因素。

        先介紹下項目本身的情況,項目是分佈式的,已經上線運行了一些時間。使用的框架大概如下:

  1. Spring MVC;
  2. Shiro;
  3. 相關聯的使用了Hibernate、Mybatis、Spring等等。

        我需要集成swagger的項目,主要使用了Spring MVC和shiro,其它的沒有影響。Spring MVC都熟悉,shiro是安全方面的框架。清楚這些情況後,開始分析出現問題的可能原因:

  1.  web.xml配置的原因,攔截了swagger-ui.html及相關請求;
  2. Spring MVC配置文件的原因,比如沒有掃描到相應的Controller;
  3. shiro的原因,因爲shiro也攔截一些沒有驗證或沒有放開(放開就是可以直接訪問的如js文件)的請求;
  4. 項目使用了過濾器的原因,也將請求攔截了;
  5. 其它原因。

        經過一定程序的熟悉瞭解,清楚了項目確實有濾器,會將所以請求先進行攔截。而我們在集成swagger後訪問的地址是http://ip:port/projectName/swagger-ui.html。如果在web.xml中配置的請求是*.json,那這個請求就進不去,也就訪問不了了。當時的配置如下所示(自然是訪問不了的):

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.json</url-pattern>
</servlet-mapping>

        請求進入過濾器後,對很多請求進行攔截驗證,所以這樣一來,就算我讓swager-ui.html請求通過,但請求swagger-ui.html後swagger的其它請求依然不通過,因爲簡單的讓使用swagger時出現的請求通過,不能從根本上解決問題。

       對使用swagger時,一些請求及靜態文件也會被shiro攔截,所以也需要修改shiro的配置。

       對swagger,要確保它本身請求對應的swagger中的控制器能被掃描到。同時也要在項目中開啓swagger的使用。下面開始找到解決方案,最後解決問題。

 

3.2 解決方案

        根本上面的分析,因爲嘗試過多種方案,所以決定改造swagger-ui,將它本地化。基本做法就是將swagger-ui項目的內容複製到要集成的項目,然後寫Controller以引導swagger-ui.html的訪問,再修改配置文件,最後測試,大概是這樣一個流程。

       下面是當時集成時使用的swagger依賴,版本號是2.6.1。

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${swagger2.version}</version>
</dependency>

 

3.3 問題解決

  3.3.3 修改前端(js、頁面)

         實現swagger-ui本地化時,是在項目中,直接將swagger-ui的文件複製過來。具體的目錄結構如下圖所示:

        其中,webapp/static/swagger目錄下的文件具體目錄如下:

         其實static/swagger中的文件是從swagger-ui裏複製過來的,沒有做過任何修改。但在/WEB-INF/pages/swagger目錄下的頁面,swagger-ui.html和o2c.jsp沒用上,只有index.jsp用上了,它也複製的swagger-ui.html的內容,然後引入了兩個js,實現了中文版的界面。index.jsp的具體代碼如下:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" pageEncoding="UTF-8"%>
<c:set var="ctx" value="${pageContext.request.contextPath}" />

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Swagger UI</title>
        <link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/images/favicon-32x32.png" sizes="32x32"/>
        <link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/images/favicon-16x16.png" sizes="16x16"/>
        <link href='${ctx}/static/swagger/webjars/springfox-swagger-ui/css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
        <link href='${ctx}/static/swagger/webjars/springfox-swagger-ui/css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
        <link href='${ctx}/static/swagger/webjars/springfox-swagger-ui/css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
        <link href='${ctx}/static/swagger/webjars/springfox-swagger-ui/css/reset.css' media='print' rel='stylesheet' type='text/css'/>
        <link href='${ctx}/static/swagger/webjars/springfox-swagger-ui/css/print.css' media='print' rel='stylesheet' type='text/css'/>

        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/object-assign-pollyfill.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/jquery.slideto.min.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/jquery.wiggle.min.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/handlebars-4.0.5.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/lodash.min.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/backbone-min.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/swagger-ui.min.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/highlight.9.1.0.pack_extended.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/jsoneditor.min.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/marked.js' type='text/javascript'></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lib/swagger-oauth.js' type='text/javascript'></script>

        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/springfox.js' type='text/javascript'></script>
        <!-- 加入下面的兩個js後,訪問swagger時語言會切換到中文 -->
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lang/translator.js' type="text/javascript"></script>
        <script src='${ctx}/static/swagger/webjars/springfox-swagger-ui/lang/zh-cn.js' type="text/javascript"></script>
    </head>

    <body class="swagger-section">
        <div id='header'>
            <div class="swagger-ui-wrap">
                <a id="logo" href="http://swagger.io">
                    <img class="logo__img" alt="swagger" height="30" width="30" src="${ctx}/static/swagger/webjars/springfox-swagger-ui/images/logo_small.png" />
                    <span class="logo__title">swagger</span>
                </a>
                <form id='api_selector'>
                    <div class='input'>
                        <select id="select_baseUrl" name="select_baseUrl"/>
                    </div>
                    <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
                    <div id='auth_container'></div>
                    <div class='input'><a id="explore" class="header__btn" href="#" data-sw-translate>Explore</a></div>
                </form>
            </div>
        </div>

        <div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
        <div id="swagger-ui-container" class="swagger-ui-wrap"></div>
    </body>
</html>

  3.3.2 添加Swagger-ui請求的引導類及配置

         在輸入http://localhost:8088/swagger-ui.html時,需要引入此請求進入到/pages/swagger/index.jsp,所以需要寫一個Controller來引導此請求的訪問。代碼如下:

@Controller
@RequestMapping
@Slf4j
public class SwaggerController {

    /**
     * @Description 進入Swagger-ui.html頁面
     * @Author Ethan
     * @Param []
     * @return org.springframework.web.servlet.ModelAndView
     * @Version 1.0
     */
    @RequestMapping("/swagger-ui")
    public ModelAndView index() {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("swagger/index");
        return mv;
    }


//    @RequestMapping(value = "/webjars/springfox-swagger-ui/o2c", method = RequestMethod.GET)
//    public ModelAndView o2c() {
//        ModelAndView mv = new ModelAndView();
//        mv.setViewName("swagger/o2c");
//        return mv;
//    }

}

       然後寫swagger的配置類,代碼如下:

@Configuration
@EnableWebMvc
@EnableSwagger2
@ComponentScan(basePackages = {"com.corn.web.controller"})
public class SwaggerConfig {
}

  3.3.1 關於配置文件:修改web.xml和Spring MVC的配置文件。

       修改web.xml文件,如下:

<!-- 使用swagger時,註釋下面的filter,不然swagger的請求會被攔截而不能通過 -->
<!-- <filter>
    <filter-name>URL-REDIRECT-FILTER</filter-name>
    <filter-class>com.corn.web.filters.UrlAuthAndEncryFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>URL-REDIRECT-FILTER</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping> -->


<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <!-- 啓用swagger時,用此配置,因爲接口的後綴是.json,而swagger請求的後綴不一樣,直接用/ -->
    <!--<url-pattern>/</url-pattern>-->
    <!-- 線上環境時,不啓用swagger,用下面的配置 -->
    <url-pattern>*.json</url-pattern>
</servlet-mapping>

         修改Spring MVC的配置文件,需要加入swagger中controller所在包的路徑掃描這一配置,如下:

<!-- 在啓用swagger時,因爲需要請求swagger的Controller,所以需要把swagger請求的Controller對應的上層路徑springfox.documentation.swagger2加入掃描中 -->
	<context:component-scan base-package="springfox.documentation.swagger2" />

         另外,需要注意的是,最初我寫的掃描路徑是springfox.documentation.swagger2.web,但發現報錯了。後面改成springfox.documentation.swagger2就可以了。

        下面的截圖是swagger依賴的目錄結構圖,swagger的頁面或其它請求,基本上請求的是Swagger2Controller,從圖中可以看出此類所在的位置。

     

  3.3.4 本地測試

        上面的工作完成後,啓動項目,在瀏覽器中輸入地址:http://localhost:8088/swagger-ui.html,打開訪問正常了,說明swagger-ui的本地化成功了。

        需要注意的一點是,訪問swagger時輸入的地址一定要有sagger-ui.html,不然打開頁面是空白的,即那些接口是顯示不出來的。另外,有可能打開swagger-ui.html時,會顯示如下內容,但過可能幾秒鐘,接口內容就出來了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章