在开发接口完后,我们都要编写接口规范文档,今天整一个能自动生成接口规范文档,并且能在开发的时候顺带的就能把文档更新的东西,她就是Swagger!
Swagger是个啥?包括很多东西,比如没开源的Swagger Hub,我使用的是开源的功能,能自动生成Restful风格的接口文档,哦对,还能直接当作端点来调试接口,有了它就卸载掉Postman吧。
目前使用Swagger最新版本可以直接引入Springfox,以前叫swagger-springmvc,Springfox是一个通过扫描代码提取代码中的信息,生成API文档的工具。
在SpringBoot中集成Swagger,我们直接看最新引入方式:
一、引入依赖项
<!--集成swagger3--><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency>
我在使用的时候,发现报了个spring-plugin-core版本的错误,我打开包看了下,依赖项版本默认是1.2,我改成了2.0就不报错了:
<!--集成swagger3--><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency><!--集成swagger3默认是1.2要使用2.0--><dependency><groupId>org.springframework.plugin</groupId><artifactId>spring-plugin-core</artifactId><version>2.0.0.RELEASE</version></dependency>
SpringBoot的“习惯优于配置”特性,其实现在已经自动配置好了
@EnableOpenApi
直接访问:
http://localhost:port/swagger-ui/index.html
默认的样式不好看哈:
接口内容都是可以自定义的,直接贴完整代码:
importcom.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; importio.swagger.models.auth.In; importorg.apache.commons.lang3.reflect.FieldUtils; importorg.springframework.boot.SpringBootVersion; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.context.annotation.Import; importorg.springframework.util.ReflectionUtils; importorg.springframework.web.servlet.config.annotation.InterceptorRegistration; importorg.springframework.web.servlet.config.annotation.InterceptorRegistry; importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer; importspringfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; importspringfox.documentation.builders.ApiInfoBuilder; importspringfox.documentation.builders.PathSelectors; importspringfox.documentation.builders.RequestHandlerSelectors; importspringfox.documentation.oas.annotations.EnableOpenApi; importspringfox.documentation.service.*; importspringfox.documentation.spi.DocumentationType; importspringfox.documentation.spi.service.contexts.SecurityContext; importspringfox.documentation.spring.web.plugins.Docket; importjava.lang.reflect.Field; importjava.util.*; BeanValidatorPluginsConfiguration.class) (publicclassSwaggerConfigimplementsWebMvcConfigurer { () { returnnewDocket(DocumentationType.OAS_30).pathMapping("/") //定义是否开启swagger,false为关闭,可以通过变量控制 .enable(true) //将api的元信息设置为包含在jsonResourceListing响应中。 .apiInfo(apiInfo()) //接口调试地址// .host() //选择哪些接口作为swagger的doc发布 .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build() //支持的通讯协议集合 .protocols(newHashSet("https", "http")) //授权信息设置,必要的headertoken等认证信息 .securitySchemes(securitySchemes()) //授权信息全局应用 .securityContexts(securityContexts()); } /***API页面上半部分展示信息*/privateApiInfoapiInfo() { returnnewApiInfoBuilder().title("queryBasic接口文档"+" Api Doc") .description("基本信息接口文档") .contact(newContact("rt", null, "")) .version("Application Version: 1.0, Spring Boot Version: "+SpringBootVersion.getVersion()) .build(); } /***设置授权信息*/privateList<SecurityScheme>securitySchemes() { ApiKeyapiKey=newApiKey("BASE_TOKEN", "token", In.HEADER.toValue()); returnCollections.singletonList(apiKey); } /***授权信息全局应用*/privateList<SecurityContext>securityContexts() { returnCollections.singletonList( SecurityContext.builder() .securityReferences( Collections.singletonList( newSecurityReference( "BASE_TOKEN", newAuthorizationScope[]{newAuthorizationScope("global", "")}))) .build() ); } <T>Set<T>newHashSet(T... ts) { if (ts.length>0) { returnnewLinkedHashSet<>(Arrays.asList(ts)); } returnnull; } /***通用拦截器排除swagger设置,所有拦截器都会自动加swagger相关的资源排除信息*@paramregistryregistry*/"unchecked") (InterceptorRegistryregistry) { (try { FieldregistrationsField=FieldUtils.getField(InterceptorRegistry.class, "registrations", true); List<InterceptorRegistration>registrations= (List<InterceptorRegistration>) ReflectionUtils.getField(registrationsField, registry); if (registrations!=null) { for (InterceptorRegistrationinterceptorRegistration : registrations) { interceptorRegistration .excludePathPatterns("/swagger**/**") .excludePathPatterns("/webjars/**") .excludePathPatterns("/v3/**") .excludePathPatterns("/doc.html"); } } } catch (Exceptione) { e.printStackTrace(); } } }
上面implements WebMvcConfigurer 是为了解决 swagger静态资源无法访问的问题,试了下发现不解决也能直接访问,想去就去掉。
然后来美化下页面!
二、使用swagger-bootstrap-ui美化
<!--https://mvnrepository.com/artifact/com.github.xiaoymin/swagger-bootstrap-ui--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.6</version></dependency>
其实就是引入了一个封装好的bootstrap-ui哈,可以让页面更好看,访问改成:
http://localhost:port/doc.html
不贴图了,自己试试哇
三、感觉这个样式最屌-knife4j-spring-boot-starter
<!--整合UI美化swagger--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version></dependency>
这个添加以下配置:
BeanValidatorPluginsConfiguration.class) (
优秀 ,奥里给!可以像使用Postman一样来调试接口:
四、使用
一些常用注解说明
@Api:用在controller类,描述API接口
@ApiOperation:描述接口方法
@ApiModel:描述对象
@ApiModelProperty:描述对象属性
@ApiImplicitParams:描述接口参数
@ApiResponses:描述接口响应
@ApiIgnore:忽略接口方法
Controller使用:
"/hi") (//@ApiIgnore忽略该接口方法publicStringsayHi(){ return"hi"; } "/hello/{id}") (value="测试接口",produces=MediaType.TEXT_PLAIN_VALUE,httpMethod="GET",notes="打印字符串到页面,用来测试服务是否部署成功") (name="id", value="用户ID", required=true, dataType="Long") (publicStringsayHello(@PathVariableStringid){ logger.info("HELLO WOLD -> id:"+id); return"Hello Wold"+id; } value="/getBasicList",produces= {MediaType.APPLICATION_JSON_UTF8_VALUE}) ( ( value="基本信息列表查询接口", consumes=MediaType.APPLICATION_JSON_UTF8_VALUE, produces="application/json;charset=UTF-8", httpMethod="POST", notes="根据传入对象中的值获取对应列表信息", response=ResponseCommonVO.class ) publicResponseCommonVO<Object>getQueryBasicList(HttpServletRequestrequest, HttpServletResponseresponse, <BasicInfo>data){ }
实体类使用:
/***公共请求类*/value="RequestCommonVo",description="公共的请求实体类") (publicclassRequestCommonVo<T> { value="请求头",required=true) (privateHeadCommonhead; value="请求体",required=true,notes="请求内容对象") (privateTObj; }
这个注解最蛋疼,有时候不起作用,要多研究下:
required=true,name="data",value="请求对象",dataTypeClass=RequestCommonVo.class) (required=true指定参数是否是必需的。name="data"参数的名称。为了实现正确的斯瓦格功能,请在根据paramType()命名参数时遵循以下规则: 如果paramType是“路径”,则该名称应该是路径中的关联部分。对于所有其他情况,该名称应该是您的应用程序期望接受的参数名称。value="请求对象"参数的简短描述。dataType=""参数的数据类型。这可以是类名或原语。dataTypeClass=参数的类。覆盖dataType(如果提供) defaultValue=描述参数的默认值。allowableValues=限制此参数的可接受值。有三种方法来描述允许值: 要设置值列表,请提供逗号分隔的列表。比如:第一,第二,第三。要设置值的范围,请以“范围”开始值,并用方括号括起来,包括最小值和最大值,或者用圆括号括起来,表示唯一的最小值和最大值。例如:范围[1,5],范围(1,5),范围[1,5]。要设置最小值/最大值,请使用相同的范围格式,但使用“无穷大”或“-infinity”作为第二个值。例如,范围[1,无穷大]表示该参数的最小允许值为1。access=""允许从应用编程接口文档中过滤参数allowMultiple=false指定参数是否可以通过多次出现来接受多个值。paramType=""参数的参数类型。有效值为路径、查询、正文、标题或表单。example=""非实体类型参数的单个示例type=""添加覆盖检测到的类型的能力format=""增加了提供自定义格式的能力allowEmptyValue() defaultfalse增加了将格式设置为空的能力readOnly() defaultfalse; 增加了被指定为只读的能力。collectionFormat() =""; 增加了用“数组”类型覆盖集合格式的能力
tags 可以设置将多个接口设置成一组接口
比如 @ApiOperation(value = "基本信息保存接口",tags = {"基本信息保存"},httpMethod = "POST")
tags = {"基本信息保存"}
tags = "基本信息保存"
总结:
我感觉写代码的时候要加那么多的注解有点不习惯,不是想象中的那么屌!@ApiParam(value = “ID”) 注解中的value参数只有和:@PathVariable(value = “id”) 以及@RequestParam使用,value参数才会有效果。
END