分享一个集成在项目中的REST APIs文档框架swagger
1 为什么是使用swagger?
1-1 当后台开发人员开发好接口,是不是还要重新书写一份接口文档提给前端人员,当然对于程序员最不喜欢的就是书写文档(当然文档是必须的,有利于项目的维护)
1-2 当后台人员开发接口,当然后台开发者也是需要测试好接口是否可用,当参数少的时候测试还不是很麻烦,当参数有十多个的时候,就需要后台开发者一个一个的拼接参数,很是耗时间而且还容易写错参数名,swagger就很好解决了这个问题(当然也是可以借助其他插件:rest-client工具,PostMan)
2 搭建环境:window,spring boot,swaager,maven
3 开始搭建:搭建过程很简单,有关于swagger注解本文不详细叙述,其实只使用常用的几个注解就ok了(@ApiOperation,@EnableSwagger2,@Api)
3-1 导入必须jar包 ,修改pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version> 2.6.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version> 2.6.0</version> </dependency> <!-- swagger end -->
3-2 配置swagger
@Configuration @EnableSwagger2 //swagger注解 public class SwaggerConfig { @Bean public Docket allInterface() { return new Docket(DocumentationType.SWAGGER_2).groupName("AllInterface(所有接口)")// 定义组 .select() // 选择那些路径和api会生成document .apis(RequestHandlerSelectors.basePackage("com.lishun.controller")) // 拦截的包路径 .paths(regex("/.*"))// 拦截的接口路径 .build() // 创建 .apiInfo(apiInfo())// 配置说明 .tags(new Tag("index", "起始页"), getTags()); } /** * @Description:这里可以指定其他tag(对应controller的@Api注解的tags属性值) * @author lishun * @date 2018/2/28 * @param [] * @return springfox.documentation.service.Tag[] */ private Tag[] getTags() { Tag[] tags = { new Tag("login", "登录相关") }; return tags; } private ApiInfo apiInfo() { return new ApiInfoBuilder()// .title("swagger api 文档")// 标题 .description("swagger api 文档")// 描述 .termsOfServiceUrl("")// .contact(new Contact("", "", ""))// 联系 .version("1.0")// 版本 .build(); } }
3-3 统一所有接口返回值(便于前端人员开发,和统一处理controller异常)
public class ResultBean<T> implements Serializable { /*提示信息*/ public String message = ""; /*状态码*/ public Integer code; /*总页数*/ private long totalPage; /*页容量*/ private int pages; /*页码*/ private int pageNum; /*返回实体信息*/ private T resultData; /*返回集合实体信息*/ private List<T> resultDataList; public ResultBean() { } public ResultBean(List<T> resultData, long totalPage, int pages, int pageNum) { this.resultDataList = resultData; this.totalPage = totalPage; this.pages = pages; this.pageNum = pageNum; } public ResultBean(T resultData) { this.resultData = resultData; } public void setMessage(String message) { this.message = message; } public long getTotalPage() { return totalPage; } public void setTotalPage(long totalPage) { this.totalPage = totalPage; } public int getPages() { return pages; } public void setPages(int pages) { this.pages = pages; } public int getPageNum() { return pageNum; } public void setPageNum(int pageNum) { this.pageNum = pageNum; } public List<T> getResultDataList() { return resultDataList; } public void setResultDataList(List<T> resultDataList) { this.resultDataList = resultDataList; } public void setMessage(String message, Object... args) { this.message = String.format(message, args); } public String getMessage() { return message; } public void setResultData(T resultData) { this.resultData = resultData; } public T getResultData() { return this.resultData; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public <T> void setResultBean(Integer code, String message, Object... mesaageFormatArgs) { setCode(code); setMessage(message, mesaageFormatArgs); } }
3-4 统一处理controller异常
/** * @author lishun * @Description: 控制器aop拦截 * @date 2017/10/27 */ @Component @Aspect public class ControllerAspect { @Pointcut("execution(public com.lishun.result.ResultBean com.lishun.controller.*.*(..))") public void dataSource(){}; @Around("dataSource()") public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { ResultBean result = null; try { result = (ResultBean<?>)proceedingJoinPoint.proceed(); } catch (Exception e) { result = new ResultBean(); result.setCode(ResultCode.FAILED); result.setMessage(e.getMessage()); e.printStackTrace(); } return result; } }
3-4 contrlloer
@RestController @Api(tags = { "index" }) public class IndexController { @GetMapping("/index/{id}") @ApiOperation(value = "findByOne", notes = "获取一条数据") public ResultBean<String> findByOne(@PathVariable(value = "id") String id) { ResultBean<String> resultBean = new ResultBean<>(); resultBean.setCode(ResultCode.OK); resultBean.setResultData("请求成功"); return resultBean; } @PostMapping("/index/add") @ApiOperation(value = "add", notes = "新增") public ResultBean<String> add(Users users) { ResultBean<String> resultBean = new ResultBean<>(); resultBean.setCode(ResultCode.OK); resultBean.setResultData("请求成功"); return resultBean; } @DeleteMapping("/index/delete/{id}") @ApiOperation(value = "delete", notes = "删除") public ResultBean<String> delete(@PathVariable(value = "id") String id) { ResultBean<String> resultBean = new ResultBean<>(); resultBean.setCode(ResultCode.OK); resultBean.setResultData("请求成功"); return resultBean; } }
3-5 测试
主要是测试接口api,所以这里就没有数据库访问的业务逻辑层
启动项目,访问http://localhost:8080/swagger-ui.html#/
展开add接口
3-6 注意!!!!! 生成环境需要把swagger禁用,swagger只是适合在开发和测试环境中使用,源代码