一. 接口文档概述swagger是当下比较流行的实时接口文文档生成工具。接口文档是当前前后端分离项目中必不可少的工具,在前后端开发之前,后端要先出接口文档,前端根据接口文档来进行项目的开发,双方开发结束后在进行联调测试。
所以接口文档其实就是开发之前双方之间的一种约定。通常接口文档分为离线的和实时的。离线的接口文档工具有: word(相当于没说), yapi, 小幺鸡等,这种文档需要程序员在上面编写,也一般具备接口测试功能。通常是由开发人员先在离线接口文档上编写信息,然后交给前端人员参照开发。最大的弊端是当我们的接口程序发生变动时,需要回过头来维护上面的内容,很麻烦,是真的麻烦。
实时接口文档就是可以根据我们的代码来自动生成相应的接口文档,优点就是我们的代码发生变化时,生成的接口文档也会自动更新,无需我们关注修改,主需要按时发布即可。但是由于是根据代码自动生成的,所以最大的弊端就是代码侵入性强,需要我们在项目代码中集成生成接口文档的相关代码。实时接口文档现在的方案有很多,但是swagger还是其中比较有影响力的一个。
二. springboot集成swagger2官网地址: swagger.io 当然,官网都是英文的,看起来还是比较麻烦的。建议大家直接按照我的步骤来,还是很简单的。
同时在说一点: swagger分为swagger2 和swagger3两个常用版本。二者区别不是很大,主要对于依赖和注解进行了优化。swagger2需要引入2个jar包,swagger3只需要一个,用起来没有什么大的区别。下面以swagger2为例。
2.1 引入依赖<dependency> <groupid>io.springfox</groupid> <artifactid>springfox-swagger2</artifactid> <version>2.9.2</version></dependency><dependency> <groupid>io.springfox</groupid> <artifactid>springfox-swagger-ui</artifactid> <version>2.9.2</version></dependency>
2.2 引入配置首先需要添加一个注解 : @enableswagger2。 这个注解我们可以添加到springboot的启动类上,也可以自定义一个配置类,放到上面。添加了这个注解以后,就代表我们已经在项目中开启了swagger的功能。
我们采用第二种方式,自己定义一个配置类,正好还可以添加一个docket配置。 所谓docket配置,就是一组(一个项目或一个版本)接口文档的配置,比如设置名称, 联系人等等。
我们在config文件夹下,添加一个swaggerconfig类。
@configuration@enableswagger2public class swaggerconfig { /** * 设置多个: * * @bean * public docket appapi() { * * list<parameter> 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<parameter> 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实战").termsofserviceurl("") .version("1.0").build(); } /** * @description: 设置swagger文档中全局参数 * @param * @date: 2020/9/11 10:15 * @return: java.util.list<springfox.documentation.service.parameter> */ private list<parameter> setheadertoken() { list<parameter> 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; }}
上面就是一个配置案例, 还设置了一个settoken方法,代表生成文档的所有接口中,都要包含一个header类型的token参数。
2.3 给controller 添加注解我们接口文档的直接描述主要就是在controller这一层,比如这个接口的功能,参数的名称,返回值的名称等。这些值我们都需要在controller上通过给方法上,请求参数和返回参数上添加对应的注解,swagger才能帮我们生成相应的接口文档。这也就是我前面提到的对现有代码的侵入性。
我们来写一个案例。
首先先创建一个vo的包,里边写我们的请求和相应参数,使用javabean定义出请求和响应的数据结构。注意这里要添加相应的注解:
请求类:
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("创建swagger请求参数")public class swaggerreqvo { @apimodelproperty("id") private integer id; @apimodelproperty("姓名") private string name; @apimodelproperty("性别") private integer gender;}
响应类:
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("创建swagger响应结果")public class swaggerresvo { @apimodelproperty("id") private integer id; @apimodelproperty("姓名") private string name; @apimodelproperty("性别") private integer gender; @apimodelproperty("啥啥") private string what;}
这里分别使用了 @apimodel注解和 @@apimodelproperty 注解定义了实体的名称和字段的名称,方便生成接口文档时展示。
再来看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("根据条件查询用户") public swaggerresvo getbyid(@requestbody swaggerresvo req) { return new swaggerresvo(); }}
这里使用了@api注解和 @apioperation注解分别标注了接口组名和接口的名称。现在我们启动项目。
发现报了这个错误。
上网查询原因说是springboot2.6版本和swagger2.9.2不兼容导致的。 也有人说是由于guava这个包的版本过低导致的。
我都分别试了一下,替换了guava的高版本依赖问题还是存在。
这个问题的主要原因确实是springboot版本过高导致。如果你用的是springboot2.5.x及之前版本是没有问题的。
spring boot 2.6.x使用pathpatternmatcher匹配路径,swagger引用的springfox使用的路径匹配是基于antpathmatcher的。
所以要想解决,添加配置,将springboot mvc的路劲匹配模式修改一下即可。
在springboot配置文件中添加配置:
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
如果是yml格式的配置文件:
再次启动问题解决。
访问地址: ip:端口号/swagger-ui.html
正常情况就可以看到我们的界面了。一会再说非正常情况。由于我们只给用户接口添加了注解,所有用户接口是可以直接观察中文文档的。而剩下的两个接口,由于没添加注解,所以都是以默认的形式展示的。
点开接口,我们可以看到接口中的想详细信息
点击model,可以看到字段的中文描述。点击 try it out,就可以直接调试接口。同时注意接口中都让填一个token,这就是我们之前的设置成效了。
截止到目前其实swagger的集成就已经完毕了,主要就是根据我们的注解生成文档,并且可以在线调用调试。开发的时候,我们只需要把controller这一层的请求和响应,以及方法描述等内容先开发完毕,就可以提供给前端让他们参照开发了。
2.4 [404]问题解决正常情况我们按照上面的步骤就可以出现页面,但是有些时候可能是由于springboot的版本过高导致的,我们输入之前的地址,出现404的情况,这个主要是由于项目中无法读取到swagger依赖包下的页面导致的。如果出现了这个问题,我们可以添加一个配置类,让他实现webmvcconfigurer 接口,在添加一个方法:
@overridepublic 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 */@configurationpublic 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/"); }}
这个时候在启动就可以了!
2.5 替换ui上面的整个过程已经完成了,但是生成的接口文档的页面,其实很多人不太喜欢,觉得不太符合国人的使用习惯,所有又有一些大神,提供了其他的ui测试页面。这个页面的使用还是比较广泛的。
修改方式:只需引入一个依赖包:
<dependency> <groupid>com.github.xiaoymin</groupid> <artifactid>swagger-bootstrap-ui</artifactid> <version>1.9.6</version></dependency>
然后把刚才实现的那个的那个方法再添加一条:
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 */@configurationpublic 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/"); }}
重新启动项目: 访问路径发生了变化:** ip:端口号/doc.html**
页面出现了。我们在看看我们的用户接口:
这个风格确实更加的直观,同时也是可以直接进行调试的。大部分的swagger都用的这个风格的文档。
三. springboot集成swagger3上面已经很详细的讲解了swagger2的集成方式,而swagger3的集成方式更加的简洁一些。
首先引入依赖:
<dependency> <groupid>io.springfox</groupid> <artifactid>springfox-boot-starter</artifactid> <version>3.0.0</version></dependency>
然后是替换注解: swagger2使用的开启注解是: @enableswagger2
而在swagger3中,这个注解要换成: @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;@configurationpublic class swaggerconfig { @bean public docket createrestapi() { return new docket(documentationtype.oas_30) // v2 不同 .select() .apis(requesthandlerselectors.basepackage("com.example.swaggerv3.controller")) // 设置扫描路径 .build(); }}
要注意,里边的版本类型换成了 oas_30, 就是swagger3的意思。
oas 是 openapi specification 的简称,翻译成中文就是 openapi 说明书。
同时访问地址:原始地址,也就是没换ui的地址: localhost:8080/swagger-ui/index.html这个要和swagger2区分开。
swagger3的原始ui风格也发生了一些变化:
同时swagger3也是可以更换ui的。方法和swagger2一样。
四. swaggerui 拦截器和跨域冲突处理如果我们的项目中有关于跨域的处理,同时还有拦截器,然后还要使用swagger,这种情况大家要注意了,有可能我们的拦截器会将swagger中的页面路径拦截掉导致swagger页面出不来,当我们在拦截器中把swagger的页面排除掉的时候,也有可能会导致跨域配置的失效。
具体解决方案简单提一下:
拦截器:
/** * 拦截器配置 * * @author liushuai */@configurationpublic 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/"); }}
跨域配置:
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 */@configurationpublic 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); }}
用这两种方式去配置,就可以让他们和平共处了。
另: 配套项目代码已托管中gitcode: gitcode.net/lsqingfeng/…
分支: feautre/mybatisplus
以上就是springboot集成swagger实例分析的详细内容。
