在开发过程中,很多后台开发者没有写接口文档的习惯,而接手没有文档的项目令人狂抓,因此在二次开发时大量的时间浪费在解读原代码的过程中。Swagger 是一款优秀的接口文档生成框架,使用注解就可以自动生成接口文档,省去了后台开发者专门写接口文档的时间,也让项目的可读性变得更好。本文将介绍 Spring Boot 2.X 集成 Swagger 2 的教程。
Swagger 官方文档: https://swagger.io/
../pom.xml ../demo-common/pom.xml ../demo-model/pom.xml
<!-- Swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger2.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger2.version}</version> </dependency>
其中对应的版本号为:
<swagger2.version>2.9.2</swagger2.version>
../demo-common/src/main/java/com/ljq/demo/springboot/common/config/Swagger2Config.java
package com.ljq.demo.springboot.common.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** * @Description: Swagger2 配置信息 * @Author: junqiang.lu * @Date: 2019/3/23 */ @Configuration @EnableSwagger2 public class Swagger2Config { @Value("${swagger.enable}") private boolean enableSwagger; @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .enable(enableSwagger) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } }
其中使用 ${swagger.enable}
属性是为了实现根据不同环境动态开启 Swagger
。如在开发环境开启 Swagger
,而在生产环境关闭 Swagger
功能。
在 yml
配置swagger
属性
../demo-web/src/main/resources/application-dev.yml ../demo-web/src/main/resources/application-test.yml
# Swagger config swagger: enable: true
../demo-web/src/main/resources/application-pro.yml
# Swagger config swagger: enable: false
参数接收类
../demo-model/src/main/java/com/ljq/demo/springboot/vo/swagger2/ModelAnnotationBean.java
package com.ljq.demo.springboot.vo.swagger2; import com.ljq.demo.springboot.BaseBean; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; /** * @Description: Swagger2 注解示例 bean * @Author: junqiang.lu * @Date: 2019/3/23 */ @Data @ApiModel(value = "Swagger2 @ApiModel 注解",description = "Swagger 2 注解接收参数") public class ModelAnnotationBean extends BaseBean { private static final long serialVersionUID = -3891566801822635611L; // 当前页 @NotNull(message = "当前页不能为空") @Min(value = 1, message = "当前页至少为 1") @ApiModelProperty(value = "当前页,不能为空,至少为 1", name = "currPage", required = true, example = "1") private Integer currPage; // 每页显示条数 @NotNull(message = "每页显示条数不能为空") @Min(value = 5, message = "每页至少展示 5 条结果") @ApiModelProperty(value = "每页显示条数,不能为空,至少为 5", name = "pageLimit", required = true, example = "6") private Integer pageLimit; // 排序依据,如依据 "id" 排序 @NotNull(message = "排序依据不能为空") @Pattern(regexp = "^[\\s\\S]{1,30}$", message = "排序依据需要控制在 1-30 个字符以内") @ApiModelProperty(value = "排序依据,不能为空,1-30 个字符", name = "sidx", required = true, example = "id") private String sidx; // 排序规则,升序: asc;降序: desc @NotNull(message = "排序规则不能为空") @Pattern(regexp = "^[\\s\\S]{1,10}$", message = "排序规则需要控制在 1-10 个字符以内") @ApiModelProperty(value = "排序规则,升序:asc;降序:desc", name = "order",required = true, example = "desc") private String order; }
Controller 层注解
../demo-web/src/main/java/com/ljq/demo/springboot/web/controller/Swagger2Controller.java
package com.ljq.demo.springboot.web.controller; import com.ljq.demo.springboot.common.api.ApiResult; import com.ljq.demo.springboot.common.api.ResponseCode; import com.ljq.demo.springboot.common.exception.ParamsCheckException; import com.ljq.demo.springboot.service.Swagger2Service; import com.ljq.demo.springboot.vo.swagger2.ModelAnnotationBean; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /** * @Description: Swagger2 示例控制中心 * @Author: junqiang.lu * @Date: 2019/3/23 */ @RestController @RequestMapping(value = "api/swagger2") @Slf4j @Api(value = "Swagger 2 控制层", tags = "Swagger 2 控制层") public class Swagger2Controller { @Autowired private Swagger2Service swagger2Service; /** * 实体类注解测试 * * @param modelAnnotationBean * @return */ @RequestMapping(value = "modelAnnotation", method = RequestMethod.POST) @ApiOperation(value = "Swagger 2 注解示范",notes = "Swagger 2 注解示范") public ApiResult modelAnnotation(@RequestBody ModelAnnotationBean modelAnnotationBean) { ApiResult apiResult = null; try { apiResult = swagger2Service.modelAnnotation(modelAnnotationBean); } catch (Exception e) { if (ParamsCheckException.class.isAssignableFrom(e.getClass())){ log.error("参数错误"); return apiResult.failure(ResponseCode.PARAM_ERROR.getCode(), e.getMessage()); } log.error("未知异常",e); return apiResult.failure(ResponseCode.UNKNOWN_ERROR.getMsg()); } return apiResult; } }
其他模块示例代码(不涉及 Swagger 使用)
Service 层
../demo-service/src/main/java/com/ljq/demo/springboot/service/Swagger2Service.java
package com.ljq.demo.springboot.service; import com.ljq.demo.springboot.common.api.ApiResult; import com.ljq.demo.springboot.vo.swagger2.ModelAnnotationBean; /** * @Description: Swagger2 业务接口 * @Author: junqiang.lu * @Date: 2019/3/23 */ public interface Swagger2Service { /** * Swagger2 参数接受实体类注解@ApiModel...示例 * * @param modelAnnotationBean * @return * @throws Exception */ ApiResult modelAnnotation(ModelAnnotationBean modelAnnotationBean) throws Exception; }
../demo-service/src/main/java/com/ljq/demo/springboot/service/impl/Swagger2ServiceImpl.java
package com.ljq.demo.springboot.service.impl; import com.ljq.demo.springboot.common.api.ApiResult; import com.ljq.demo.springboot.common.page.PageUtil; import com.ljq.demo.springboot.common.page.QueryUtil; import com.ljq.demo.springboot.common.util.MapUtil; import com.ljq.demo.springboot.dao.user.UserDao; import com.ljq.demo.springboot.entity.UserDO; import com.ljq.demo.springboot.service.Swagger2Service; import com.ljq.demo.springboot.vo.swagger2.ModelAnnotationBean; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Map; /** * @Description: Swagger2 业务具体实现类 * @Author: junqiang.lu * @Date: 2019/3/23 */ @Service("swagger2Service") @Transactional(rollbackFor = Exception.class) @Slf4j public class Swagger2ServiceImpl implements Swagger2Service { @Autowired private UserDao userDao; /** * Swagger2 参数接受实体类注解@ApiModel...示例 * * @param modelAnnotationBean * @return * @throws Exception */ @Override public ApiResult modelAnnotation(ModelAnnotationBean modelAnnotationBean) throws Exception { /** * 获取参数 */ Map<String, Object> map = MapUtil.beanToMap(modelAnnotationBean); QueryUtil queryUtil = new QueryUtil(map); // 列表查询 List<UserDO> userDBList = userDao.queryList(queryUtil); if (userDBList == null || userDBList.isEmpty()) { return ApiResult.success(new PageUtil(null, 0, queryUtil.getPageLimit(), queryUtil.getCurrPage())); } int total = userDao.queryCount(queryUtil); // 分页处理 PageUtil pageUtil = new PageUtil(userDBList, total, queryUtil.getPageLimit(), queryUtil.getCurrPage()); return ApiResult.success(pageUtil); } }
启动项目,打开以下链接
http://localhost:8088/swagger-ui.html
界面显示如下:
Swagger
界面使用步骤:
Swagger
注解的时候, 同一个注解 value
值不能设置相同,否则会出现在界面上显示不同的接口,但是接口参数却相同如下图,有两个接口,一个 Save
接口,一个 FindById
接口,两个接口的请求参数不同,使用 @ApiModel
注解时设置的value
值相同,结果导致在 swagger-ui
界面两个接口显示的参数相同,从而导致在请求接口时请求的参数并不是实际接口所需要的参数
Setting Up Swagger 2 with a Spring REST API
Spring Boot RESTful API Documentation with Swagger 2
配置不同环境下启用swagger,在生产环境关闭swagger
Gtihub 源码地址 : https://github.com/Flying9001/springBootDemo
个人公众号:404Code,分享半个互联网人的技术与思考,感兴趣的可以关注.