备注:学习并整理自:“狂神说java”网上教程
swagger
- 流行的API开发工具,具备:
- 快速生成API开发文档
- 实时在线测试
- 便捷快速的生成注释等相关信息
开发java api文档
- 创建springboot工程
- 添加maven依赖:
<dependencies>
<!--springboot核心启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--全栈式Web开发,包括Tomcat和spring-webmvc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--swagger相关的依赖-->
<!--JSON API documentation for spring based applications-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<!--JSON API documentation for spring based applications-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
- 创建swagger配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* 定制swagger的配置
* @Configuration: spring自动配置
* @EnableSwagger2: 开启swagger配置
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
private String contextPath;
/**
* 定制swagger的展示配置
* @return
*/
@Bean
public Docket create() {
ParameterBuilder parameterBuilder = new ParameterBuilder();
List<Parameter> parameters = new ArrayList<>();
// 创建定制字段,这里做一个示例:添加一个默认header
parameterBuilder.name("cToken")
.description("token字段")
.modelRef(new ModelRef("String"))
.parameterType("header")
.required(true)
.defaultValue("test-token")
.build();
parameters.add(parameterBuilder.build());
return new Docket(DocumentationType.SWAGGER_2)
/** 设置分组名称 */
.groupName("分组1")
.globalOperationParameters(parameters)
.apiInfo(getApiInfo())
/** 是否启动,默认为true */
.enable(true)
.securitySchemes(securitySchemes())
.securityContexts(securityContexts())
.select()
/**
* apis(): 定义了API扫描规则
* RequestHandlerSelectors: 含有如下方法,可返回Predicate函数,作为apis入参
* RequestHandlerSelectors.basePackage(包路径):定义扫描package路径
* RequestHandlerSelectors.any(): 返回所有的扫描路径
* RequestHandlerSelectors.none(): 任何都不扫描
* RequestHandlerSelectors.withClassAnnotation(注解): 扫描含有某类注解的类
* RequestHandlerSelectors.withMethodAnnotation(注解): 扫描含有某类注解的类
*/
//.apis(RequestHandlerSelectors.basePackage("com.lanyyyy.springbootswagger"))
//.apis(RequestHandlerSelectors.any())
//.apis(RequestHandlerSelectors.none())
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
/**
* paths(): 定义了url过滤规则
* PathsSelectors: 含有如下方法,可返回Predicate函数,作为paths入参
* PathSelectors.any(): 任意url
* PathSelectors.none(): 都不匹配
* PathSelectors.regex(""): 正则表达式匹配:java的Pattern类(注意正则和通配符的区别)
* PathSelectors.ant():按照Matcher进行匹配:也是正则,不过会按照匹配返回每个字符的匹配结果
* 备注:这个ant不是很理解,待分析(测试来看,跟regex不一样,需要用两个星号这种来匹配)
*/
.paths(PathSelectors.regex(".*/api/.*"))
//.paths(PathSelectors.regex(".*/api/v2/.*"))
//.paths(PathSelectors.ant("/api/**"))
.build();
}
/** 设置多个分组:分组2 */
@Bean
public Docket create2() {
return new Docket(DocumentationType.SWAGGER_2).groupName("分组2");
}
/** 设置多个分组:分组3 */
@Bean
public Docket create3() {
return new Docket(DocumentationType.SWAGGER_2).groupName("分组3");
}
/** 这个主题参考自:https://www.jianshu.com/p/07a6d2ac9fed */
private List<ApiKey> securitySchemes() {
List<ApiKey> apiKeyList= new ArrayList();
apiKeyList.add(new ApiKey("x-auth-token", "x-auth-token", "header"));
return apiKeyList;
}
private List<SecurityContext> securityContexts() {
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$"))
.build());
return securityContexts;
}
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences=new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
/**
* 配置swagger的描述信息
* @return ApiInfo
*/
private ApiInfo getApiInfo() {
// 方式1:通过ApiInfo的构造方法
// 作者信息
//Contact contact = new Contact("lanyyyy", "csdn.net", "123456789@qq.com");
//ApiInfo apiInfo = new ApiInfo(
// "Api from lanyyyy (from ApiInfo)", // 标题
// "This is built by lanyyyy", // 描述
// "1.0", // 版本
// "http://xxx.com", // 组织url
// contact, // 联系人信息
// "Apache 2.0", // license信息
// "http://www.apache.org/licenses/LICENSE-2.0", // license地址
// new ArrayList<VendorExtension>()); // 供应商信息
// 方式2:通过ApiInfoBuilder构造:
ApiInfo apiInfo = new ApiInfoBuilder()
.title("Api from lanyyyy (from ApiInfoBuilder)")
.description("This is built by lanyyyy")
.version("1.0")
.termsOfServiceUrl("http://xxx.com")
.contact(new Contact("lanyyyy", "csdn.net", "123456789@qq.com"))
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.extensions(new ArrayList<>())
.build();
return apiInfo;
}
}
-
说明:swagger通过Docket的Bean定义各种swagger的实现,主要有如下:
- 页面描述(ApiInfo类):定义了swagger界面显示的Info信息
- 扫描规则: select().apis().paths().build():按照扫描规则,过滤展示swagger上的api信息
- 分组(swagger右上角展示):
- groupName控制名称
- 可以通过生成多个Docket Bean实例实现分组
- 修改API参数配置
@API、@ApiModel、@ApiModelProperty…
UI界面
-
添加各种测试类:
- User数据类
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "测试类:User")
public class User {
//@ApiModel(value = "usernmae") // 这会报错,因为元注解限定了只能用于TYPE(不包括属性Field)
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "用户年龄")
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
- UserController类:
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1")
@Api(tags = "测试User Controller")
public class UserController {
@ApiOperation(value = "获取用户")
@RequestMapping(method = RequestMethod.GET, value = "/user")
public User getUser(@ApiParam(value = "用户名") @RequestParam String username) {
User user = new User();
user.setUsername(username);
user.setAge(15);
return user;
}
}
- HelloController
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/v1")
public class HelloController {
@RequestMapping(method = RequestMethod.GET, value = "/hello")
@ResponseBody
public String hello() {
return "Hello World ";
}
@RequestMapping(method = RequestMethod.GET, value = "/helloAgain")
@ResponseBody
public String helloAgain() {
return "Hello World Again";
}
}
* ByeController:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v2")
public class ByeController {
@RequestMapping(method = RequestMethod.GET, value = "/bye")
@ResponseBody
public String bye() {
return "Bye World ";
}
@RequestMapping(method = RequestMethod.GET, value = "/byeAgain")
@ResponseBody
public String byeAgain() {
return "Bye World Again";
}
}
- 效果图: