Spring3集成Swagger2遇到問題總結

爲什麼要用Swagger?

首先說一下需求:最近公司要開發一個小程序,我負責後臺的接口開發。公司爲了規範接口文檔要統一使用YAPI 進行管理。YAPI支持Swagger 格式json文件導入,所以準備將公司的一個老項目接入Swagger2。在集成的過程中遇到一些問題,特意寫這篇文章與大家分享。希望有同樣需求的你少走些彎路。

項目環境版本

項目Spring版本: 3.2.2.RELEASE ,並且該項目不是mavne項目。

maven項目搭建步驟

Spring4 並且是maven項目的話集成相對簡單一些。集成的步驟如下:
引入Swagger2的2個核心依賴即可,

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>

然後就是配置Swagger 的配置類,配置類具體內容如下:

package com.bfsuol.swagger;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
@EnableWebMvc
public class SwaggerConfig {

    @Bean
	public Docket api() {
		return new Docket(DocumentationType.SWAGGER_2)
				.select()
				// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
				.apis(RequestHandlerSelectors.basePackage("com.bfsuol.app.interfaces.controller"))
				.build().apiInfo(apiInfo());
	}

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("開放接口API")
                .description("HTTP對外開放接口")
                .version("1.0.0")
                .termsOfServiceUrl("http://xxx.xxx.com")
                .license("LICENSE")
                .licenseUrl("http://xxx.xxx.com")
                .build();
    }
}

maven項目使用步驟參考 和光同塵ss 博主的文章 你也可以點擊查看原文的具體操作步驟 Maven+SpringMVC+SwaggerUI

Spring3 項目集成Swagger中遇到的問題

整理jar包的方法

但是我們的項目是非mavne項目。
我的做法是創建mavne項目,然後引入上面2個核心依賴然後去本地倉庫中複製jar包,jar包的具體路徑如下圖紅色框所示。

在這裏插入圖片描述

缺少jar包的問題

整理完jar包複製到我們的jar 項目中。第一次嘗試報如下圖錯誤:


    Caused by: java.io.FileNotFoundException: class path resource [org/mapstruct/Mapper.class] cannot be opened because it does not exist
    	at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:157)
    	at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:50)
    	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:80)
    	at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:102)
    	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:76)
    	at org.springframework.context.annotation.ConfigurationClassParser.getImports(ConfigurationClassParser.java:298)
    	at org.springframework.context.annotation.ConfigurationClassParser.getImports(ConfigurationClassParser.java:300)
    	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:231)
    	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:154)
    	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:131)
    	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:225)
    	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:154)
    	at org.springframework.context.annotation.ConfigurationClassParser.processImport(ConfigurationClassParser.java:349)
    	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:233)
    	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:154)
    	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:131)
    	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.ja

在mavne項目中搜索該類 發現該類在mapstruct-1.1.0.Final.jar包中 我們將該jar包複製到我們的項目中。

聲明@EnableWebMvc報錯問題

第二次嘗試 沒有報上面的錯誤但是報如在錯誤:

Caused by: java.lang.ClassCastException: org.springframework.web.accept.ContentNegotiationManagerFactoryBean$$EnhancerByCGLIB$$dbb6606b cannot be cast to org.springframework.web.accept.ContentNegotiationManager
	at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$269d1c34.mvcContentNegotiationManager(<generated>)
	at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.requestMappingHandlerMapping(WebMvcConfigurationSupport.java:196)
	at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$269d1c34.CGLIB$requestMappingHandlerMapping$19(<generated>)
	at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$269d1c34$$FastClassByCGLIB$$ad3fcfb7.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:286)
	at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$269d1c34.requestMappingHandlerMapping(<generated>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43

去掉 @EnableWebMvc 因爲配置文件中已經配置了mvc:annotation-driven
在次啓動沒有報錯。

Spring版本不兼容的問題

滿心歡喜的去訪問swagger-ui.html頁面取查看我們定義的接口,結果報如下錯誤。此時我的內心是崩潰的。
在這裏插入圖片描述

java.lang.NoSuchMethodError: org.springframework.web.util.UriComponentsBuilder.fromHttpRequest(Lorg/springframework/http/HttpRequest;)Lorg/springframework/web/util/UriComponentsBuilder;
	at springfox.documentation.swagger2.web.HostNameProvider.componentsFrom(HostNameProvider.java:44)
	at springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(Swagger2Controller.java:93)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)

從錯誤中我們發先該類未定義但是spring的jar包確實存在。 明顯是Spring版本太低的問題。現在解決方式只有2種。
1 升級Spring版本
2 降低 Swagger 的版本
我這裏選擇了 降低 Swagger 的版本,百度搜索swagger的pom依賴
在這裏插入圖片描述
在這裏插入圖片描述
這裏選擇最低版本再次進行嘗試。如下圖所示 我們集成成功!

在這裏插入圖片描述
需要集成的jar包的 請點擊鏈接去下載(僅僅是swagger 先關jar沒有spring的jar吧哈):https://download.csdn.net/download/ljk126wy/11099420

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