- 一款号称全世界最流行的API框架
- 支持多种语言
搭建好访问:
1、导入依赖
遇到一个问题springboot如果导入2.6 死活启动不了报错
Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerException
改成2.2.x就可以了 具体原因待定
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2、配置swagger
2.1、创建配置类
@Configuration //配置类
@EnableSwagger2// 开启Swagger2的自动配置
public class SwaggerConfig {
}
2.2、修改描述信息
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());//Docket 实例关联上 apiInfo()
}
//可以通过apiInfo()属性配置文档信息
private ApiInfo apiInfo() {
Contact contact = new Contact("奇乐云", "http://www.qileyun.cn", "1541177517@qq.com");
return new ApiInfo(
"Swagger学习", // 标题
"学习演示如何配置Swagger", // 描述
"v1.0", // 版本
"http://terms.service.url/组织链接", // 组织链接
contact, // 联系人信息
"Apach 2.0 许可", // 许可
"许可链接", // 许可连接
new ArrayList<>()// 扩展
);
}
2.3、Swagger配置扫描接口
1、构建Docket时通过select()方法配置怎么扫描接口。
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
/*
any() // 扫描所有,项目中的所有接口都会被扫描到
none() // 不扫描接口
// 通过方法上的注解扫描,如withMethodAnnotation(GetMapping.class)只扫描get请求
withMethodAnnotation(final Class<? extends Annotation> annotation)
// 通过类上的注解扫描,如.withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口
withClassAnnotation(final Class<? extends Annotation> annotation)
basePackage(final String basePackage) // 根据包路径扫描接口
*/
.apis(RequestHandlerSelectors.basePackage("cn.qileyun.swaggerdemo.controller"))
.build();
}
2、除此之外,我们还可以配置接口扫描过滤:
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("cn.qileyun.swaggerdemo.controller"))
// 配置如何通过path过滤,即这里只扫描请求以/kuang开头的接口
/*
any() // 任何请求都扫描
none() // 任何请求都不扫描
regex(final String pathRegex) // 通过正则表达式控制
ant(final String antPattern) // 通过ant()控制
*/
.paths(PathSelectors.ant("/aa/**"))
.build();
}
2.4、配置多个分组
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("group1");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("group2");
}
@Bean
public Docket docket3(){
return new Docket(DocumentationType.SWAGGER_2).groupName("group3");
}
2.5、配置Swagger开关
1、通过enable()方法配置是否启用swagger,如果是false,swagger将不能在浏览器中访问了
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(false) //配置是否启用Swagger,如果是false,在浏览器将无法访问
...
}
2、如何动态配置当项目处于test、dev环境时显示swagger,处于prod时不显示?
@Bean
public Docket docket(Environment environment) {
// 设置要显示swagger的环境
Profiles of = Profiles.of("dev", "test");
// 判断当前是否处于该环境
// 通过 enable() 接收此参数判断是否要显示
boolean b = environment.acceptsProfiles(of);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(b) //配置是否启用Swagger,如果是false,在浏览器将无法访问
...
}
3、application.properties
spring.profiles.active=dev
3、常用注解
3.1、实体类
- @ApiModel为类添加注释
- @ApiModelProperty为类属性添加注释
实体类
@ApiModel("用户实体")
public class User {
@ApiModelProperty("用户名")
public String username;
@ApiModelProperty("密码")
public String password;
}
控制器
@RequestMapping("/getUser")
public User getUser(){
return new User();
}
3.2、Controller控制器注解
- @Api: 修饰整个类,用于controller类上
- @ApiOperation: 描述一个接口,用户controller方法上
- @ApiParam: 单个参数描述
- @ApiModel: 用来对象接收参数,即返回对象
- @ApiModelProperty: 对象接收参数时,描述对象的字段
- @ApiResponse: Http响应其中的描述,在ApiResonse中
- @ApiResponses: Http响应所有的描述,用在
- @ApiIgnore: 忽略这个API
- @ApiError: 发生错误的返回信息
- @ApiImplicitParam: 一个请求参数
- @ApiImplicitParam: 多个请求参数
注解 | 属性 | 值 | 备注 |
---|---|---|---|
@Api | value | 字符串 | 可用在class 头上,class 描述 |
description | 字符串 | ||
@Api (value = “xxx”, description = “xxx”) | |||
@ApiOperation | value | 字符串 | 可用在方法头上.参数的描述容器 |
notes | 字符串 | ||
@ApiOperation (value = “xxx”, notes = “xxx”) | |||
@ApiImplicitParams | {} | @ApiImplicitParam 数组 | 可用在方法头上.参数的描述容器 |
@ApiImplicitParams ({@ApiImplicitParam1 ,@ApiImplicitParam2 ,…}) | |||
@ApiImplicitParam | name | 字符串 与参数命名对应 | 可用在@ApiImplicitParams 里 |
value | 字符串 | 参数中文描述 | |
required | 布尔值 | true/false | |
dataType | 字符串 | 参数类型 | |
paramType | 字符串 | 参数请求方式:query/path | |
query:对应@RequestParam ?传递 | |||
path: 对应@PathVariable {}path传递 | |||
defaultValue | 字符串 | 在api测试中默认值 | |
用例参见项目中的设置 | |||
@ApiResponses | {} | @ApiResponse 数组 | 可用在方法头上.参数的描述容器 |
@ApiResponses ({@ApiResponse1 ,@ApiResponse2 ,…}) | |||
@ApiResponse | code | 整形 | 可用在@ApiResponses 里 |
message | 字符串 | 错误描述 | |
@ApiResponse (code = 200, message = “Successful”) |
4、完整案例
4.1、完整配置文件(以后直接复制就可以了)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import springfox.documentation.builders.PathSelectors;
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;
import springfox.documentation.service.Contact;
import java.util.ArrayList;
@Configuration //配置类
@EnableSwagger2// 开启Swagger2的自动配置
public class SwaggerConfig {
private ApiInfo apiInfo() {
Contact contact = new Contact("联系人名字", "http://xxx.xxx.com/联系人访问链接", "联系人邮箱");
return new ApiInfo(
"Swagger学习", // 标题
"学习演示如何配置Swagger", // 描述
"v1.0", // 版本
"http://terms.service.url/组织链接", // 组织链接
contact, // 联系人信息
"Apach 2.0 许可", // 许可
"许可链接", // 许可连接
new ArrayList<>()// 扩展
);
}
@Bean
public Docket docket(Environment environment) {
// 设置要显示swagger的环境
Profiles of = Profiles.of("dev", "test");
// 判断当前是否处于该环境
// 通过 enable() 接收此参数判断是否要显示
boolean b = environment.acceptsProfiles(of);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(b) //配置是否启用Swagger,如果是false,在浏览器将无法访问
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("cn.qileyun.swaggerdemo.controller"))
// 配置如何通过path过滤,即这里只扫描请求以/api开头的接口
.paths(PathSelectors.ant("/api/**"))
.build();
}
}
4.2、实例测试代码
@Api(value = "API - VehiclesController", description = "车辆模块接口详情")
@RestController
@RequestMapping("/api")
public class HelloController {
@ApiOperation(value = "查询车辆接口", notes = "此接口描述xxxxxxxxxxxxx<br/>xxxxxxx<br>值得庆幸的是这儿支持html标签<hr/>", response = String.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "vno", value = "车牌", required = false,
dataType = "string", paramType = "query", defaultValue = "辽A12345"),
@ApiImplicitParam(name = "page", value = "page", required = false,
dataType = "Integer", paramType = "query",defaultValue = "1"),
@ApiImplicitParam(name = "count", value = "count", required = false,
dataType = "Integer", paramType = "query",defaultValue = "10")
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful — 请求已完成"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器不能完成请求")}
)
@ResponseBody
@RequestMapping(value = "", method = RequestMethod.GET)
public ModelMap findVehicles(@RequestParam(value = "vno", required = false) String vno,
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "count", required = false) Integer count)
throws Exception {
ModelMap map = new ModelMap();
map.addAttribute("vno", vno);
map.addAttribute("page", page);
return map;
}
@ApiOperation(value = "根据车牌查询车辆", notes = "这种类型的查询是精确查询,其结果只有一条数据", response = String.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "vno", value = "车牌", required = false,
dataType = "string", paramType = "path", defaultValue = "辽A12345")
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful — 请求已完成"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器不能完成请求")}
)
@ResponseBody
@RequestMapping(value = "vno={vno}", method = RequestMethod.GET)
public ModelMap getVno(@PathVariable(value = "vno") String vno)
throws Exception {
ModelMap map = new ModelMap();
map.addAttribute("vno", vno);
return map;
}
@ApiOperation(value = "车辆位置查询接口", notes = "根据车牌查询车辆位置信息", response = String.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "vno", value = "车牌", required = false,
dataType = "string", paramType = "path", defaultValue = "辽A12345")
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful — 请求已完成"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器不能完成请求")}
)
@ResponseBody
@RequestMapping(value = "vno={vno}/location", method = RequestMethod.GET)
public ModelMap getLocation(@PathVariable(value = "vno") String vno)
throws Exception {
ModelMap map = new ModelMap();
map.addAttribute("vno", vno);
return map;
}
@ApiOperation(value = "根据车辆id查询", notes = "精确查询,最常规的方式,支持POST和GET方式", response = String.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "id", required = false,
dataType = "string", paramType = "path", defaultValue = "12344444")
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful — 请求已完成"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器不能完成请求")}
)
@ResponseBody
@RequestMapping(value = "{id}", method = {RequestMethod.GET,RequestMethod.POST})
public ModelMap getById(@PathVariable(value = "id") String id)
throws Exception {
ModelMap map = new ModelMap();
map.addAttribute("{RequestMethod.GET,RequestMethod.POST}", id);
return map;
}
@ApiOperation(value = "根据车辆id查询", notes = "精确查询,最常规的方式,支持POST和GET方式", response = String.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "id", required = false,
dataType = "string", paramType = "path", defaultValue = "12344444")
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful — 请求已完成"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 403, message = "服务器拒绝请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器不能完成请求")}
)
@ResponseBody
@RequestMapping(value = "{id}", method = {RequestMethod.DELETE})
public ModelMap delById(@PathVariable(value = "id") String id)
throws Exception {
ModelMap map = new ModelMap();
map.addAttribute("RequestMethod.DELETE", id);
return map;
}
@ApiOperation(value = "网点挂靠", notes = "嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻", response = String.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful — 请求已完成"),
@ApiResponse(code = 400, message = "请求中有语法问题,或不能满足请求"),
@ApiResponse(code = 401, message = "未授权客户机访问数据"),
@ApiResponse(code = 404, message = "服务器找不到给定的资源;文档不存在"),
@ApiResponse(code = 500, message = "服务器不能完成请求")}
)
@ResponseBody
@RequestMapping(value = "change_rentalshop", method = {RequestMethod.PUT,RequestMethod.PATCH})
public ModelMap changeRentalShop(@RequestBody User user)
throws Exception {
ModelMap map = new ModelMap();
map.addAttribute("网点挂靠", new Date());
return map;
}
}