一、swagger的作用
1、可以生成接口文档
2、可以进行接口测试,像postman一样
二、swagger的使用
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>
springfox-swagger2:核心依赖,用来生成接口文档
springfox-swagger-ui:制作网页文档
一般两个一起放在controller层中
如果实体类或者VO类是独立模块,可以把springfox-swagger2放到实体类的pom文件中
2、配置类
@Configuration
@EnableSwagger2
public class SwaggerConfig {
/**
* swagger会帮助我们生成接口文档
* 1:配置生成的文档信息
* 2:配置生成规则
*
* *Docket封装接口文档信息
*/
@Bean
public Docket getDocket(){
//创建封面信息对象
ApiInfoBuilder apiInfoBuilder = new ApiInfoBuilder();
apiInfoBuilder.title("《锋迷商城》后端接口说明")
.description("此文档详细说明了项目后端接口规范")
.version("v 2.0.1")
.contact(new Contact("youngcave","www.liangge.com","liang@qq.com"));
ApiInfo apiInfo = apiInfoBuilder.build();
//指定生成策略
Docket docket = new Docket(DocumentationType.SWAGGER_2) //指定文档风格
.apiInfo(apiInfo)//指定生成的文档中的封面信息:文档标题,作者,版本
.select()
.apis(RequestHandlerSelectors.basePackage("com.qfedu.fmmall.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
}
复制过来修改下面这句里的controller包名就行,直接用
.apis(RequestHandlerSelectors.basePackage("com.qfedu.fmmall.controller"))
上面两步做完,已经可以使用了,但是生成的文档是英文的,下面的注解只是把英文显示成中文,可以不看了
3、打开接口文档
启动项目,然后在网页里打开网址:http://localhost:8080/swagger-ui.html
显示如下
goods-controller和user-controller 可以展开查看里面的方法了
每个方法还可以继续展开,这里点开addGoods,显示下面的内容
点开的方向里,可以直接填参数发请求测试接口
4、测试请求
点开user-controller里的login方法
返回结果如下,还是很详细的
上面就是使用方法
然后就是一些注解,用来把页面里的英文改成中文
三、swagger注解
1、Api
加个controller类上面
@Api(value = "提供商品添加、修改、删除及查询的接口管理",tags = "商品管理")
@Api(value = "提供用户的登录和注册接口",tags = "用户管理")
显示效果
2、ApiOperation
方法描述,放在方法上面
@ApiOperation("用户登录接口")
@ApiOperation("用户注册接口")
显示效果如下
3、ApiImplicitParams和ApiImplicitParam
参数描述,写在方法上
多个参数:
@ApiImplicitParams({
@ApiImplicitParam(dataType = "String",name = "username",value = "用户登录帐号",required = true),
@ApiImplicitParam(dataType = "String",name = "password",value = "用户登录密码",required = false,defaultValue = "111111")
})
单个参数:
@ApiImplicitParam(name = "username",required = true)
如果参数是实体类的话,可以不用写,而且直接在实体类上加注角
4、ApiModel
写在实体类上
@ApiModel(value = "User对象",description = "用户/买家信息")
@ApiModel(value = "ResultVO对象",description = "封装接口返回给前端的数据")
5、ApiIgnore
@ApiIgnore
写在方法上,添加此注解的方法不会出现在文档中
基本内容就这些了
光使用的话只要加依赖,加配置类,知道打开的地址就行了
四、swagger的UI插件
在controller层导入依赖就行
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
打开网址是:http://localhost:8080/doc.html
显示效果比原界面好看点
五、异常处理
上面的配置换了台电脑使用,一直报:
Failed to start bean 'documentationPluginsBootstrapper'
百度了好几天,今天终于解决了,方法如下
配置类要继承 WebMvcConfigurationSupport
继承完,发请求还报:
: No mapping for GET /swagger-ui.html
这是找不到静态资源,本来直接可以用的,现在继承了webmvc,出来了新问题,所以再重新配置静态资源,顺便加上/META-INF/resources/ 文件夹
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决静态资源无法访问
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
// 解决swagger无法访问
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
// 解决swagger的js文件无法访问
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
到这为止
http://localhost:8080/swagger-ui.html 可以正常打开了
但是 http://localhost:8080/doc.html 打不开了
最后还是回到最开始,很幸运,第一次使用swagger2的时候是成功的
我把原来的代码翻出来,所有依赖的版本都对照着改了一下
最终发现,springboot 2.5.7 才能和 swagger2 2.9.2 一起使用
这星期都在折腾swagger2上了,要不是第一次走狗屎运导入了2.5.7的springboot,下个星期,下下个星期可能都找不到问题出在哪
下面放个依赖,以后直接复制,swagger2和springboot无冲突版本
<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>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.5.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
六、实体类异常处理
如果有把实体类当参数,还会报下面这个错
java.lang.NumberFormatException: For input string: ""
原因是io.swagger.models.parameters.AbstractSerializableParameter会实例化参数,也就是通过example的值为属性赋值,如果example没有显式的赋值,就是空串"",但是如果实体类用作application/json那么就不会走这个方法去实例化参数。
按照这个原因描述,解决方法就是三个了
第一个解决方法:直接替换替换swagger中的model依赖,这个算是bugger,在下一个版本中已经解决了,默认是1.5.20版,换成1.5.21就行
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
第二个解决方法:手动用example来赋值,只需要给整型参数赋值就行了,就像下面的userId
@ApiModel("用户信息")
public class Users {
@ApiModelProperty(value = "序号",example = "1")
private Integer userId;
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
@ApiModelProperty("用户头像")
private String userImg;
}
第三个解决方法:把实体类当成application/json格式
@PostMapping("/regist")
@ApiOperation(value = "用户注册",notes = "用户注册接口介绍")
public ResultVO regist(@RequestBody Users users){
System.out.println("regist");
return new ResultVO(10000,"注册成功",null);
}