Swagger
最近分析一个前后端分离的项目,发现前后端项目中使用到Swagger,对该技术进行学习。
开源项目地址:
前后端分离:后端分层(服务层、数据层、控制层)、前端也进行分层(前端控制层、视图层)
前后端之间的问题以及解决
前后端交互的问题在于前端的需求会不断变化,进而后端需要更改数据库、修改后端源程序,因此前后端人员无法做到”即使协商、今早解决”。
对于以上的问题解决方案:
1.指定计划提纲(schema),实时更新最新的api,降低继承的风险
2.指定计划文档
3.前后端分离
Swagger简介以及优势
Swagger接口文档生成工具,通过使用Swagger以及衍生工具可以做到生成各种接口文档,支持多种语言(java、php等),RestFul Api文档在线自动生成工具。
官方地址:https://swagger.io/
java项目中使用Swagger需要有springbox、swagger2、ui
springBoot继承swagger
1.创建项目
创建一个springBoot的项目,选中web模块
2.导入依赖
导入spring继承的swagger信息。
<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>
<!--在随后的版本中相关的注解进行了更改,请注意测试时的版本环境问题-->
3.启动运行访问Swagger页面
添加配置类,标注配置信息
@Configuration 标注该类为一个注解类
@EnableSwagger2 标注该类为Swagger配置类,该注解用于标识其支持springFox
Docket(DocumentationType.SWAGGER_2)用于标识swagger版本
select() 创建一个构建器,用于标注控制器的文档和方法对应
apis() 定义要包含的类
paths()允许根据路径映射定义控制器的方法
@Configuration
@EnableSwagger2
public class SwaggerConfig {
}
页面信息
4.描述信息的配置
在Swagger的配置类中将Docket这个类加入spring的同期中,swagger启动会去获取该类最后将配置信息显示在界面上。
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(getApiInfo());
}
//在swagger页面创建自己的信息面板
//标题信息、描述信息、版本信息、团队地址
//contact、开源许可、许可地址、集合类
//String title, String description, String version, String termsOfServiceUrl,
// Contact contact, String license, String licenseUrl, Collection<VendorExtension> vendorExtensions
//Contact 的参数有姓名、地址、邮箱
//配置Swagger信息=apiinfo
private ApiInfo getApiInfo(){
Contact contact = new Contact("冯雁星", "itxiangzai.xyz", "itxingzai@163.com");
return new ApiInfo("Swagger文档标题","简单的描述","1.0",
"itxingzai.xyz",contact,"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",new ArrayList<>());
}
}
5.swagger扫描的接口
Docket.select();对于接口信息的配置,是否扫描以及过滤扫描的信息。
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(getApiInfo())
.select()
//指定swagger扫描的包 RequestHandlerSelectors.basePackage("com.itxing.swagger.controller")
//扫描全部 RequestHandlerSelectors.any()
//不扫描 RequestHandlerSelectors.none()
//扫描类上的注解 questHandlerSelectors.withClassAnnotation(RestController.class)
//扫描方法上的注解 RequestHandlerSelectors.withMethodAnnotation(GetMapping.class)
.apis(RequestHandlerSelectors.basePackage("com.itxing.swagger.controller"))
//过滤路径
//.paths(PathSelectors.ant("/itxing/swagger/**"))
.build() //工厂模式
;
}
6.实际工作工的问题
设置swagger在开发环境中使用,在生产环境中关闭
判断是否为生产环境,使用Environment 类能够获取到当前的系统配置的环境是否处于开发环境还是处于上线环境
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket(Environment environment){
//获取hi安静的信息
Profiles profiles = Profiles.of("dev","test");
//首先获取项目的环境信息
boolean b = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(getApiInfo())
//enable(false)表示swagger不能在浏览器中访问
.enable(b);
}
//配置Swagger信息=apiinfo
private ApiInfo getApiInfo(){
Contact contact = new Contact("冯雁星", "itxiangzai.xyz", "itxingzai@163.com");
return new ApiInfo("Swagger文档标题","简单的描述","1.0",
"itxingzai.xyz",contact,"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",new ArrayList<>());
}
7.Swagger分组
配置API文档的分组
一个Docket返回一个分组
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("xingzai");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("itxing");
}
测试中遇到的一个BUG
由于对RESTFul风格并不是特别的熟悉,因此调用过程中出现错误
对于不是String类型的参数需要使用required 来表示,否则在启动时访问ui界面会出错@PathVariable(value = “age” ,required =true)
//正确的调用
@ApiOperation("查询用户的方法")
@GetMapping("/user/{age}/{name}")
public Object user(@PathVariable(value = "age" ,required =true) int age,@ApiParam("姓名") @PathVariable( "name") String name){
User user = new User();
user.setAge(age);
user.setName(name);
String res = JSON.toJSONString(user);
return res;
}
对于访问的路径:
传统的访问方式,将参数和路径区分开来,后端的注解使用的是
@RequestParam(value = “age”,defaultValue = “30”)
@ApiOperation("查询用户的方法")
@GetMapping("/user")
public Object user(@RequestParam(value = "age",defaultValue = "30") int age,@ApiParam("姓名") @RequestParam( "name") String name){
User user = new User();
user.setAge(age);
user.setName(name);
String res = JSON.toJSONString(user);
return res;
}
Restful风格,传递的参数在路径之中包含
不同之处在于:
小结
1.通过swagger可以给难理解的接口、属性、方法、参数添加注释信息
2.接口文档实时更新
3.可以在线测试