现代化的研发组织架构中,一个研发团队基本包括了产品组、后端组、前端组、APP端研发、测试组、UI组等,各个细分组织人员各司其职,共同完成产品的全周期工作。如何进行组织架构内的有效高效沟通就显得尤其重要。其中,如何构建一份合理高效的接口文档更显重要。
接口文档横贯各个端的研发人员,但是由于接口众多,细节不一,有时候理解起来并不是那么容易,引起‘内战’也在所难免, 并且维护也是一大难题。
类似RAP文档管理系统,将接口文档进行在线维护,方便了前端和APP端人员查看进行对接开发,但是还是存在以下几点问题:
Swagger的出现可以完美解决以上传统接口管理方式存在的痛点。本文介绍Spring Boot整合Swagger2的流程,连带填坑。
使用流程如下:
1)引入相应的maven包:
io.springfox
springfox-swagger2
2.7.0
io.springfox
springfox-swagger-ui
2.7.0
复制代码
2)编写Swagger2的配置类:
package com.trace.configuration;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
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;
/**
* Created by Trace on 2018-05-16.
* Desc: swagger2配置类
*/
@SuppressWarnings({"unused"})
@Configuration @EnableSwagger2
public class Swagger2Config {
@Value("${swagger2.enable}") private boolean enable;
@Bean("UserApis")
public Docket userApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("用户模块")
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.regex("/user.*"))
.build()
.apiInfo(apiInfo())
.enable(enable);
}
@Bean("CustomApis")
public Docket customApis() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("客户模块")
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.regex("/custom.*"))
.build()
.apiInfo(apiInfo())
.enable(enable);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("XXXXX系统平台接口文档")
.description("提供子模块1/子模块2/子模块3的文档, 更多请关注公众号: 随行享阅")
.termsOfServiceUrl("https://xingtian.github.io/trace.github.io/")
.version("1.0")
.build();
}
}复制代码
如上可见:
3)controller层类和方法添加相关注解
package com.trace.controller;
import com.trace.bind.ResultModel;
import com.trace.entity.po.Area;
import com.trace.entity.po.User;
import com.trace.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* Created by Trace on 2017-12-01.
* Desc: 用户管理controller
*/
@SuppressWarnings("unused")
@RestController @RequestMapping("/user")
@Api(tags = "用户管理")
public class UserController {
@Resource private UserService userService;
@GetMapping("/query/{id}")
@ApiOperation("通过ID查询")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "int", paramType = "path")
public ResultModel findById(@PathVariable int id) {
User user = userService.findById(id);
return ResultModel.success("id查询成功", user);
}
@GetMapping("/query/ids")
@ApiOperation("通过ID列表查询")
public ResultModel> findByIdIn(int[] ids) {
List users = userService.findByIdIn(ids);
return ResultModel.success("in查询成功", users);
}
@GetMapping("/query/user")
@ApiOperation("通过用户实体查询")
public ResultModel> findByUser(User user) {
List users = userService.findByUser(user);
return ResultModel.success("通过实体查询成功", users);
}
@GetMapping("/query/all")
@ApiOperation("查询所有用户")
public ResultModel> findAll() {
List users = userService.findAll();
return ResultModel.success("全体查找成功", users);
}
@GetMapping("/query/username")
@ApiOperation("通过用户名称模糊查询")
@ApiImplicitParam(name = "userName", value = "用户名称")
public ResultModel> findByUserName(String userName) {
List users = userService.findByUserName(userName);
return ResultModel.success(users);
}
@PostMapping("/insert")
@ApiOperation("新增默认用户")
public ResultModel insert() {
User user = new User();
user.setUserName("zhongshiwen");
user.setNickName("zsw");
user.setRealName("钟仕文");
user.setPassword("zsw123456");
user.setGender("男");
Area area = new Area();
area.setLevel((byte) 5);
user.setArea(area);
userService.save(user);
return ResultModel.success("新增用户成功", user.getId());
}
@PutMapping("/update")
@ApiOperation("更新用户信息")
public ResultModel update(User user) {
int row = userService.update(user);
return ResultModel.success(row);
}
@PutMapping("/update/status")
@ApiOperation("更新单个用户状态")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "用户ID", required = true),
@ApiImplicitParam(name = "status", value = "状态", required = true)
})
public ResultModel updateStatus(int id, byte status) {
User user = userService.updateStatus(id, status);
return ResultModel.success(user);
}
@DeleteMapping("/delete")
@ApiOperation("删除单个用户")
@ApiImplicitParam(value = "用户ID", required = true)
public ResultModel delete(int id) {
return ResultModel.success(userService.delete(id));
}
}复制代码
4)返回对象ResultModel
package com.trace.bind;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* Created by Trace on 2017-12-01.
* Desc: 接口返回结果对象
*/
@SuppressWarnings("unused")
@Getter @Setter @ApiModel(description = "返回结果")
public final class ResultModel {
@ApiModelProperty("是否成功: true or false")
private boolean result;
@ApiModelProperty("描述性原因")
private String message;
@ApiModelProperty("业务数据")
private T data;
private ResultModel(boolean result, String message, T data) {
this.result = result;
this.message = message;
this.data = data;
}
public static ResultModel success(T data) {
return new ResultModel<>(true, "SUCCESS", data);
}
public static ResultModel success(String message, T data) {
return new ResultModel<>(true, message, data);
}
public static ResultModel failure() {
return new ResultModel<>(false, "FAILURE", null);
}
public static ResultModel failure(String message) {
return new ResultModel<>(false, message, null);
}
}
复制代码
5)ApiModel属性对象 -- User实体
package com.trace.entity.po;
import com.trace.mapper.base.NotPersistent;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
* Created by Trace on 2017-12-01.
* Desc: 用户表tb_user
*/
@SuppressWarnings("unused")
@Data @NoArgsConstructor @AllArgsConstructor
@ApiModel
public class User {
@ApiModelProperty("用户ID") private Integer id;
@ApiModelProperty("账户名") private String userName;
@ApiModelProperty("用户昵称") private String nickName;
@ApiModelProperty("真实姓名") private String realName;
@ApiModelProperty("身份证号码") private String identityCard;
@ApiModelProperty("性别") private String gender;
@ApiModelProperty("出生日期") private LocalDate birth;
@ApiModelProperty("手机号码") private String phone;
@ApiModelProperty("邮箱") private String email;
@ApiModelProperty("密码") private String password;
@ApiModelProperty("用户头像地址") private String logo;
@ApiModelProperty("账户状态 0:正常; 1:冻结; 2:注销") private Byte status;
@ApiModelProperty("个性签名") private String summary;
@ApiModelProperty("用户所在区域码") private String areaCode;
@ApiModelProperty("注册时间") private LocalDateTime registerTime;
@ApiModelProperty("最近登录时间") private LocalDateTime lastLoginTime;
@NotPersistent @ApiModelProperty(hidden = true)
private transient Area area; //用户所在地区
@NotPersistent @ApiModelProperty(hidden = true)
private transient List roles; //用户角色列表
}
复制代码
简单说下Swagger2几个重要注解:
@Api:用在请求的类上,表示对类的说明
@ApiOperation:用在请求的方法上,说明方法的用途、作用
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
@ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
@ApiModel:主要有两种用途:
@ApiModelProperty:用在属性上,描述响应类的属性
最终呈现结果:
如前所述:通过maven导入了swagger-ui:
io.springfox
springfox-swagger-ui
2.7.0
复制代码
那么,启动应用后,会自动生成http://{root-path}/swagger-ui.html页面,访问后,效果如下所示:
可以在线测试接口,如通过ID查询的接口/user/query/{id}
原文地址:https://juejin.im/post/5afe490ff265da0b8c253411