SpringBoot 2.1.4与Swagger2的集成生成RESTful接口文档

来源:http://www.bj9420.com

编者: wRitchie(吴理琪)

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful风格的Web服务。总体目标是使客户端的接口文档与服务端接口同步更新,当我们在后台的接口修改了后,Swagger可以实现自动的更新,而不需要人为的维护这个接口进行测试。接口文档的方法,参数和模型紧密集成到服务器端的代码,允许API始终保持同步。

第一步:pom.xml添加依赖,引入jar包:

第一步:pom.xml添加依赖,引入jar包:

Swagger版本声明


2.9.2

版本依赖:


io.springfox
springfox-swagger-ui
${swagger2.version}
io.springfox
springfox-swagger2
${swagger2.version}
第二步:Swagger的配置启动类编写:

第二步:Swagger的配置启动类编写:

使用Swagger需进行一些配置,编写配置启动类Swagger2.java,配置相关信息将在Swagger接口首页上显示,类似于接口说明书,在Swagger2类中使用注解来进行启动Swagger,注意,在SpringBoot的启动类如SmApplication.java同级创建Swagger2.java

Swagger2.java具体配置如下:

package com.bj9420;
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.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @Title: Swagger2.java
* @Description: Swagger2的配置文件 http://IP:端口/swagger-ui.html
* http://localhost:8081/swagger-ui.html
* @author: wRitchie
* @date: 2019/1/4 15:07
* @version: V1.0
* @Copyright (c): 2019 http://bj9420.com All rights reserved.
*/
@Configuration
@EnableSwagger2
public class Swagger2 {
@Value("${swagger2.enable}")
private boolean enable;
/**swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//为当前包路径
.apis(RequestHandlerSelectors.basePackage("com.bj9420.controller"))
.paths(PathSelectors.any())
.build().enable(enable);
}
/**构建 api文档的详细信息函数,注意这里的注解引用的是哪个*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//页面标题
.title("SM项目RESTful API文档")
//创建人
.contact(new Contact("wRitchie", "http://www.bj9420.com", "408873941@qq.com"))
//版本号
.version("1.0.0")
//描述
.description("SM项目接口文档,本项目所有文档终以在线的形式提供,如有疑问,请及时有我们联系,本文档将实时更新,确保最新版的接口可用。")
.build();
}
}

其中: .apis(RequestHandlerSelectors.basePackage("com.bj9420.controller"))指定了以扫描包的方式进行,会把com.bj9420.controller包下的controller都扫描到。

第三步:使用Swagger来进行模拟测试,主要是在controller层,实例如下:

第三步:使用Swagger来进行模拟测试,主要是在controller层,实例如下:

package com.bj9420.controller.user;
import com.bj9420.framework.SystemConstant;
import com.bj9420.framework.util.AESUtil;
import com.bj9420.framework.util.MD5Util;
import com.bj9420.framework.util.StringUtil;
import com.bj9420.model.Result;
import com.bj9420.model.User;
import com.bj9420.service.user.IUserService;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Title: UserController.java
* @Description: 用户控制类,使用Swagger2提供接口文档范本
* @author: wRitchie
* @date: 2019/1/4 15:14
* @version: V1.0
* @Copyright (c): 2019 http://bj9420.com All rights reserved.
*/
@Api(value = "用户控制类", tags = "用户控制类")
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
private static final Logger log = LoggerFactory.getLogger(UserController.class);
/**注意:paramType需要指定为path,不然不能正常获取*/
@ApiOperation(value = "查询用户信息", notes = "根据用户标识查询用户信息")
@ApiImplicitParam(name = "userId", value = "用户标识", paramType = "path", dataType = "Integer")
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public User getUser(@PathVariable Integer userId) {
log.info("开始查询某个用户信息");
return userService.selectByPrimaryKey(userId);
}
/**注意:paramType需要指定为body*/
@ApiOperation(value = "新建用户", notes = "新建一个用户")
@ApiImplicitParams({@ApiImplicitParam(name = "user", value = "用户数据", required = true, paramType = "body", dataType = "User") })
//@RequestMapping(value = "", method = RequestMethod.POST)
@PostMapping("")
public Result addUser(@ApiParam(value = "用户数据", required = true) @RequestBody User user) {
/**模拟客户端app生成的md5密码,实现后台用户与app用户密码的一致性*/
String pwdTmp=MD5Util.encode(user.getPassword());
String sKey = MD5Util.md5(SystemConstant.SYSTEM_SKEY).substring(0, 16);
String pwdEncrypt = AESUtil.encrypt(pwdTmp, sKey).substring(0, 16);
user.setPassword(pwdEncrypt);
int returnValue = userService.insert(user);
if (returnValue > 0) {
return Result.success("新建用户成功。",user);
}else{
return Result.failure("新建用户失败。",null);
}
}
@ApiOperation(value = "获取用户列表", notes = "分页查询获取用户列表信息")
@ApiImplicitParams({@ApiImplicitParam(name = "map",value = "用户数据Map形式",dataType = "Map")})
@GetMapping("")
public Map listByPager(@RequestParam Map map) {
Map jsonMap = new HashMap();
/************* 分页处理 ****************/
//draw : 表示请求次数
String draw=map.get("draw")+"";
//start :第一条数据的起始位置,比如0代表第一条数据
String start=map.get("start")+"";
//length:告诉服务器每页显示的条数
String length=map.get("length")+"";
//排序字段名称
String sortname=map.get("sortname")+"";
//排序升降
String sortorder=map.get("sortorder")+"";
//是否分页标记
String pager=map.get("pager")+"";
if (StringUtil.isEmpty(draw)) {
draw = "0";
}
if(StringUtil.isEmpty(start)) {
start="0";
}
if (StringUtil.isEmpty(length)) {
length = SystemConstant.PAGER_SIZE;
}
if (StringUtil.isEmpty(pager)) {
pager = null;
}
map.put("start", start);
map.put("len", length);
// 排序
String orderbyStr=null;
if(!StringUtil.isEmpty(sortname)){
if("createTime".equals(sortname)){
orderbyStr="order by create_time "+sortorder;
}else if("modifyTime".equals(sortname)){
orderbyStr="order by modify_time "+sortorder;
}else if("userId".equals(sortname)){
orderbyStr="order by user_id "+sortorder;
}else if("loginName".equals(sortname)){
orderbyStr="order by login_name "+sortorder;
}else if("realName".equals(sortname)){
orderbyStr="order by real_name "+sortorder;
}else if("sex".equals(sortname)){
orderbyStr="order by sex "+sortorder;
}else if("orgName".equals(sortname)){
orderbyStr="order by org_id "+sortorder;
}else if("phoneNumber".equals(sortname)){
orderbyStr="order by phone_number "+sortorder;
}else if ("userStatus".equals(sortname)) {
orderbyStr = "order by userStatus " + sortorder;
}
}else{
orderbyStr="order by user_id desc";
}
map.put("pager", pager);
map.put("orderBy", orderbyStr);
List list = userService.selectByPager(map);
int allSize =userService.selectByPagerCount(map);
jsonMap.put("draw", draw);
jsonMap.put("start", start);
jsonMap.put("length", length);
jsonMap.put("sortorder", sortorder);
jsonMap.put("sortname", sortname);
jsonMap.put("pager", pager);
//具体的数据对象数组
jsonMap.put("data", list);
// 总记录数
jsonMap.put("recordsTotal", allSize);
return jsonMap;
}
@ApiOperation(value = "删除用户", notes = "根据用户ID删除用户")
@ApiImplicitParam(name = "userId", value = "用户标识", paramType = "path", dataType = "Integer")
@RequestMapping(value = "/{userId}", method = RequestMethod.DELETE)
public String delUser(@PathVariable int userId) {
int returnValue = userService.deleteByPrimaryKey(userId);
if (returnValue > 0) {
return "删除成功。";
}
return "删除失败。";
}
@ApiOperation(value = "更新用户", notes = "更新已存在用户")
@ApiImplicitParam(name = "user", value = "用户数据", required = true, paramType = "body", dataType = "User")
@RequestMapping(value = "", method = RequestMethod.PUT)
public Result update(@RequestBody User user) {
int returnValue = userService.updateByPrimaryKeySelective(user);
if (returnValue > 0) {
return Result.success("更新用户成功。",user);
}else{
return Result.failure("更新户失败。",null);
}
}
}

Swagger2相关注解介绍

1. @Api:用在类上,说明该类的作用

2. @ApiOperation:用在方法上,说明方法的作用

3. @ApiImplicitParams:用在方法上包含一组参数说明

4. @ApiImplicitParam:用在 @ApiImplicitParams 注解中,指定一个请求参数的各个方面

paramType:参数放在哪个地方

· header --> 请求参数的获取:@RequestHeader

· query -->请求参数的获取:@RequestParam

· path(用于restful接口)--> 请求参数的获取:@PathVariable

· body(不常用)

· form(不常用)

name:参数名

dataType:参数类型

required:参数是否必须传

value:参数的意思

defaultValue:参数的默认值

5. @ApiResponses:用于表示一组响应

6. @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息

code:数字,例如400

message:信息,例如"请求参数没填好"

response:抛出异常的类

7. @ApiModel:描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)

8. @ApiModelProperty:描述一个model的属性

第四步:启动应用,浏览器访问:http://localhost:8081/swagger-ui.html,正常展示 api 接口文档界面,如下:

第四步:启动应用,浏览器访问:http://localhost:8081/swagger-ui.html,正常展示 api 接口文档界面,如下:

第五步,实际应用,选择相应的接口,点击Try it out按钮,输入相关参数,点击Execute,即可看到返回结果,如下图所示:

第五步,实际应用,选择相应的接口,点击Try it out按钮,输入相关参数,点击Execute,即可看到返回结果,如下图所示:

结论:这样很方便,不用像postman一样来编写入口,Swagger2自动完成,而且实时更新。至此Swagger2与SpringBoot集成完毕。

结论:这样很方便,不用像postman一样来编写入口,Swagger2自动完成,而且实时更新。至此Swagger2与SpringBoot集成完毕。