一、Swagger简介
Swagger 是一个规范和完整的框架,是一款RESTFUL接口的、基于YAML、JSON语言的文档在线自动生成、代码自动生成的工具。它用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。它提供了一个方法,使我们可以用指定的 JSON 或者 YAML 摘要来描述你的 API文档接口。
使用Swagger的好处:
Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和测试API接口。
Swagger 可以生成客户端SDK代码用于各种不同的平台上的实现。
Swagger 文件可以在许多不同的平台上从代码注释中自动生成。
Swagger 有一个强大的社区,里面有许多强悍的贡献者。
二、Swagger开源组件介绍
1. Swagger-tools:提供各种与Swagger进行集成和交互的工具。例如模式检验、Swagger 1.2文档转换成Swagger 2.0文档等功能。
2. Swagger-core: 用于Java/Scala的的Swagger实现。与JAX-RS(Jersey、Resteasy、CXF...)、Servlets和Play框架进行集成。
3. Swagger-js: 用于JavaScript的Swagger实现。
4. Swagger-node-express: Swagger模块,用于node.js的Express web应用框架。
5. Swagger-ui:一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档。是一套 HTML/CSS/JS 框架用于解析遵守 Swagger spec 的 JSON 或 YML 文件,并且生成API文档的UI导航。它可以将你的规格文档转换成Swagger Petsotre-like UI。
6. Swagger-codegen:一个模板驱动引擎,通过分析用户Swagger资源声明以各种语言生成客户端代码。它为不同的平台生成客户端 SDK(比如 Java、JavaScript、Python 等)。这些客户端代码帮助开发者在一个规范平台中整合 API ,并且提供了更多健壮的实现,可能包含了多尺度、线程,和其他重要的代码。SDK 是用于支持开发者使用 REST API 的工具。
7. Swagger-Editor: 在线编辑器,用于验证你的 YML 格式的内容是否违反 Swagger spec 。YML 是一种句法,依赖于空格和嵌套。Swagger 编辑器会标出错误并且给你格式提醒(Swagger spec 文件可以使用 JSON 或者 YAML 中的任意一种格式)。
三、引入Swagger依赖
在与项目整合(包含SpringBoot项目)时,需要引入相关Swagger依赖,有两种依赖方式:
(1)使用第三方依赖
<!-- https://mvnrepository.com/artifact/com.spring4all/swagger-spring-boot-starter --> <dependency> <groupId>com.spring4all</groupId> <artifactId>swagger-spring-boot-starter</artifactId> <version>1.8.0.RELEASE</version> </dependency>
(2)使用官方依赖
<!-- 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.9.2的
四、编写Swagger配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @ClassName: SwaggerConfig
* @Desc: swagger文档配置
* @Author: liuhefei
* @Date: 2019/3/11 10:29
*/
@Configuration
@EnableSwagger2
@Profile(value = {"dev", "test"}) //指定运行环境(开发,测试)
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("你项目的包名"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Api接口接口")
.description("api接口描述信息")
.contact(new Contact("作者", "url", "email"))
.termsOfServiceUrl("https://swagger.io/swagger-ui/")
.version("1.0")
.build();
}
}五、Swagger相关注解说明
swagger通过注解表明该接口会生成文档,包括接口名、请求方法、参数、返回信息的等等。
(1) @Api:修饰整个类,描述Controller的作用。比如:@Api(value = "/userlist", description = "用户列表API")
(2) @ApiModelProperty: 用在出入参数对象的字段上,比如:@ApiModelProperty(value = "记录创建时间", notes = "", example = "")
(3) @ApiOperation:描述一个类的一个方法,或者说一个接口,以说明它的作用,用在controller的方法上。比如:@ApiOperation(value = "",notes = "",response = Order,tags = {""})
(4) @ApiParam:单个参数描述,比如:@ApiParam(value = "用户", required = true) User user)
(5) @ApiModel:用对象来接收参数,用在返回对象类上,比如:@ApiModel(value="用户对象模型")
(6) @ApiProperty:用对象接收参数时,描述对象的一个字段
(7) @ApiResponse:HTTP响应其中1个描述,用在 @ApiResponses里边,比如:@ApiResponse(code = 400, message = "Invalid user supplied")
(8) @ApiResponses:HTTP响应整体描述,用在controller的方法上,比如:@ApiResponses({ @ApiResponse(code = 400, message = "Invalid Order") })
(9) @ApiIgnore:使用该注解忽略这个API
(10) @ApiError :发生错误返回的信息
(11) @ResponseHeader:响应头设置,比如:@ResponseHeader(name="openid",description="用户openid")
(12) @ApiImplicitParam:一个请求参数,用在@ApiImplicitParams的方法里边
(13) @ApiImplicitParams:多个请求参数,用在controller的方法上
其中@ApiImplicitParam的参数说明如下:
属性:paramType ,用于查询参数类型,其值为:path/query/body/header/form,含义如下:
path 以地址的形式提交数据
query 直接跟参数完成自动映射赋值
body 以流的形式提交 仅支持POST
header 参数在request headers 里边提交
form 以form表单的形式提交 仅支持POST
属性:dataType ,指定参数的数据类型(Long,String) 只作为标志说明,并没有实际验证
属性:name ,接收参数名(必须与方法中参数名一致)
属性:value ,接收参数的意义描述(描述信息)
属性:required ,参数是否必填,其值为:true(必填),false(非必填)
属性:defaultValue ,为参数设置默认值
实例代码:
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
* @ClassName: ActivityList
* @Desc: 活动管理列表
* @Author: liuhefei
* @Date: 2019/3/11 15:16
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ActivityList implements Serializable {
private static final long serialVersionUID = -2323114201346199834L;
@ApiModelProperty(value = "活动列表id",notes = "主键id不可更改",example = "1")
private Integer id;
@ApiModelProperty(value = "图片缩略图", notes = "", example = "")
private String imageUrl;
@ApiModelProperty(value = "标题", notes = "", example = "")
private String title;
@ApiModelProperty(value = "跳转链接", notes = "", example = "")
private String jumpUrl;
@ApiModelProperty(value = "运营文案", notes = "", example = "")
private String content;
@ApiModelProperty(value = "发布时间", notes = "", example = "")
private Date releaseTime;
@ApiModelProperty(value = "编辑者", notes = "", example = "")
private String editAuthor;
@ApiModelProperty(value = "审核者", notes = "", example = "")
private String auditor;
@ApiModelProperty(value = "活动状态:0:已结束;1:进行中", notes = "", example = "")
private Integer activityStatus;
@ApiModelProperty(value = "状态信息:1:草稿; 2:待审核; 3:未通过; 4:待发布; 5:发布中; 6:已下线", notes = "", example = "")
private Integer statusInfo;
@ApiModelProperty(value = "排序", notes = "", example = "1")
private Integer sort;
@ApiModelProperty(value = "记录创建时间", notes = "", example = "")
private Date createTime;
@ApiModelProperty(value = "记录更新时间", notes = "", example = "")
private Date updateTime;
}import com.chuangzhan.fuwuhao.entity.ActivityList;
import com.chuangzhan.fuwuhao.pojo.ActivityListParam;
import com.chuangzhan.fuwuhao.service.ActivityListService;
import com.chuangzhan.fuwuhao.utils.CommonResponse;
import com.chuangzhan.fuwuhao.utils.PageData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.jfaster.mango.plugin.page.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
/**
* @ClassName: ActivityListController
* @Desc: 活动列表api接口
* @Author: liuhefei
* @Date: 2019/3/12 11:01
*/
@Api(tags="活动列表API后台管理接口")
@RestController
@RequestMapping("/activity")
public class ActivityListController {
final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
ActivityListService activityListService;
@ApiOperation(value = "添加或更新活动", notes="活动信息")
@RequestMapping(value = "/addAcitivity", method = RequestMethod.POST)
public CommonResponse<String> addActivityInfo(@RequestParam(value = "id",required = false) @ApiParam("活动编号id,添加活动时,不填;更新活动时,必填")Integer id,
@RequestBody ActivityListParam activityListParam){
ActivityList activityList = new ActivityList();
if(id != null){
activityList.setId(id); //更新活动时,才传此参数
}
activityList.setTitle(activityListParam.getTitle());
activityList.setImageUrl(activityListParam.getImageUrl());
activityList.setJumpUrl(activityListParam.getJumpUrl());
activityList.setContent(activityListParam.getContent());
Long releaseTime = activityListParam.getReleaseTime();
Date reTime = (releaseTime==null)?null:new Date(releaseTime);
activityList.setReleaseTime(reTime);
activityList.setEditAuthor(activityListParam.getEditAuthor());
activityList.setAuditor(activityListParam.getAuditor());
activityList.setActivityStatus(activityListParam.getActivityStatus());
activityList.setStatusInfo(activityListParam.getStatusInfo());
Integer num = null;
try {
if(id == null){
num = activityListService.insertActivityList(activityList); //保存活动信息,id自增
}else {
num = activityListService.updateActivityList(activityList); //更新活动信息,需要传id
}
}catch (Exception e){
logger.info("保存活动信息时发生异常{}", e.getMessage());
}
if(num > 1){
return CommonResponse.ok(1).setMsg("活动信息保存成功");
}else {
return CommonResponse.fail(-1).setMsg("活动信息保存失败");
}
}
@ApiOperation(value = "根据时间/标题查询活动(活动配置查询)")
@RequestMapping(value = "/queryAcitivity", method = RequestMethod.GET)
public CommonResponse<PageData<ActivityList>> getActivityList(@RequestParam(value = "startTime",required = false) @ApiParam("发布时间")Long startTime,
@RequestParam(value = "endTime",required = false) @ApiParam("发布时间")Long endTime,
@RequestParam(value = "title",required = false) @ApiParam("活动标题")String title,
@RequestParam(value = "pageNum",defaultValue = "1")int pageNum,
@RequestParam(value = "pageSize",defaultValue = "5")int pageSize){
if((startTime!=null)^(endTime!=null)){
return CommonResponse.fail(-1).setMsg("时间区间不全");
}
Date begin = (startTime==null)?null:new Date(startTime);
Date end = (endTime==null)?null:new Date(endTime);
PageData<ActivityList> pageData = new PageData<>();
Page page = Page.create(pageNum,pageSize);
List<ActivityList> activityLists = activityListService.getActivityList(begin, end, title, page);
pageData.setData(activityLists);
pageData.setTotalCount(new Long(page.getTotal()));
return CommonResponse.ok(0).setData(pageData);
}
@ApiOperation(value = "活动列表排序")
@RequestMapping(value = "/sort", method = RequestMethod.GET)
public CommonResponse<PageData<ActivityList>> activityListSort(@PathVariable Integer[] ids){
ActivityList activityList = new ActivityList();
Integer id = null;
Integer sortId = null;
Integer num = null;
for(int i=0; i < ids.length; i++){
id = i;
sortId = ids[i];
num = activityListService.updateActivitySort(sortId, id);
}
if(num > 0){
return CommonResponse.ok(0).setMsg("排序成功");
}else {
return CommonResponse.fail("-1").setMsg("排序失败");
}
}
@ApiOperation(value = "根据时间/标题查询活动(活动顺序查询)")
@RequestMapping(value = "/queryAcitivitySort", method = RequestMethod.GET)
public CommonResponse<PageData<ActivityList>> getActivityListSort(@RequestParam(value = "startTime",required = false) @ApiParam("发布时间")Long startTime,
@RequestParam(value = "endTime",required = false) @ApiParam("发布时间")Long endTime,
@RequestParam(value = "title",required = false) @ApiParam("活动标题")String title,
@RequestParam(value = "pageNum",defaultValue = "1")int pageNum,
@RequestParam(value = "pageSize",defaultValue = "5")int pageSize){
if((startTime!=null)^(endTime!=null)){
return CommonResponse.fail(-1).setMsg("时间区间不全");
}
Date begin = (startTime==null)?null:new Date(startTime);
Date end = (endTime==null)?null:new Date(endTime);
PageData<ActivityList> pageData = new PageData<>();
Page page = Page.create(pageNum,pageSize);
List<ActivityList> activityLists = activityListService.getActivityListSort(begin, end, title, page);
pageData.setData(activityLists);
pageData.setTotalCount(new Long(page.getTotal()));
return CommonResponse.ok(0).setData(pageData);
}
@ApiOperation(value = "根据活动编号id删除活动")
@RequestMapping(value = "/deleteActivity", method = RequestMethod.GET)
public CommonResponse<String> removeActivity(@RequestParam(value = "id",required = false) @ApiParam("活动编号id")Integer id){
Integer num = null;
/*if(statusInfo == 1 || statusInfo == 3 || statusInfo == 4 || statusInfo == 6){
}else {
return CommonResponse.fail(-1).setMsg("不能删除该条记录");
}*/
num = activityListService.deleteActivityListById(id);
if(num > 0){
return CommonResponse.ok(1).setMsg("删除成功");
}else {
return CommonResponse.fail(-1).setMsg("删除失败");
}
}
}启动SpringBoot项目,访问Swagger文档:http://localhost:8820/swagger-ui.html#/
效果如图:
六、Swagger相关学习资源
Swagger官网:https://swagger.io/
Swagger 编辑网址:http://editor.swagger.io/#/
swagger-codegen
spring-boot-starter-swagger
更多关于Swagger文档相关的知识,请自行查阅!