前言:RESTFul API功能的扩展是不可避免的,维护API文档也是件非常头痛的事情。 在这里呢整合Swagger工具可以帮助我们完成生成和维护RESTFul API文档的工作,确保我们的API文档在不断扩展的过程中得到维护并保持最新状态。下图展示了构建后效果
首先我们来认识下开源项目 Swagger,其中主要要项目如下:
(1.1)Swagger-tools:提供各种与Swagger进行集成和交互的工具。例如模式检验、Swagger 1.2文档转换成Swagger
2.0文档等功能。
(1.2)Swagger-core:
用于Java/Scala的的Swagger实现。与JAX-RS(Jersey、Resteasy、CXF…)、Servlets和Play框架进行集成。
(1.3)Swagger-js: 用于JavaScript的Swagger实现。
(1.4)Swagger-node-express: Swagger模块,用于node.js的Express web应用框架。
(1.5)Swagger-ui:一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档。
(1.6)Swagger-codegen:一个模板驱动引擎,通过分析用户Swagger资源声明以各种语言生成客户端代码。
本项目整合Swagger2 后构建的RESTFul API文档效果如下,这里选择Swagger2(推荐),是因为在pom文件中添加springfox-swagger-ui就无需从官网下载静态资源了,如果是Swagger1则需要。
1.搭建项目
可以参考本系列文章,博客地址:https://blog.youkuaiyun.com/caiqing116/article/details/84573166
或者直接下载项目,git地址:https://github.com/gitcaiqing/SSM_DEMO.git
2.Maven引入Swagger2需要的Jar包
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
3.添加构建swagger文档的配置类
创建包com/ssm/swagger下创建类Swagger2Config.java
package com.ssm.swagger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.builders.ApiInfoBuilder;
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;
/**
* Swagger2文档构建配置类
* 通过@EnableSwagger2注解来启用Swagger2
* @author
*/
@Configuration
@EnableWebMvc
@EnableSwagger2
public class Swagger2Config {
//接口文档构建配置
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
//通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现
.select()
//所有的接口
//.apis(RequestHandlerSelectors.any())
//指定扫描的路径
.apis(RequestHandlerSelectors.basePackage("com.ssm.restapi"))
.build()
.apiInfo(apiInfo());
}
//接口文档信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SSM_DEMO-RESTFul API接口服务列表")
.description("")
.termsOfServiceUrl("http://192.168.100.104:7080")
.version("1.0")
.build();
}
}
4.Swagger静态资源访问控制在servlet/spring-mvc.xml中添加配置
<!-- 静态资源 -->
<mvc:resources mapping="/static/**" location="/static/" />
<mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/" />
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/" />
5.RESTFul接口实现
基于上一篇文章 https://blog.youkuaiyun.com/caiqing116/article/details/85146823 在这里呢,将实现了的接口简单改造成我们需要的,并添加Swagger相关内容。
这里我们先简单了解些Swagger相关注解
@Api:用在类上,表示标识这个类是swagger的资源 其中tags:表示说明 ;value:也是说明,可以使用tags替代
@ApiOperation:用于方法; 表示一个http请求的操作
(1)value:请求接口说明
(2)httpMethod:请求方式
(3)response:返回值类型
@ApiParam:用于方法,参数,字段说明;
(1)name:参数名
(2)dataType:参数类型
(3)required:参数是否必须传true | false
(4)value:说明参数的意思
(5)defaultValue:参数的默认值
@ApiResponses:用于表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
(1)code:数字,例如400
(2)message:信息例如请求参数没填好
(3)response:抛出异常的类
创建包com.ssm.restapi,创建类BasicUserRestController.java。
package com.ssm.restapi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.ssm.entity.BasicUser;
import com.ssm.service.BasicUserService;
import com.ssm.util.EncryptKit;
import com.ssm.util.ResultModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
/**
* 用户相关RESTFul API
* @author https://blog.youkuaiyun.com/caiqing116
* http://192.168.100.104:7080/SSM_DEMO/static/swagger/index.html
*/
@RestController
@RequestMapping("/ssm/rest/basicUser")
@Api(tags="用户管理接口文档")
public class BasicUserRestController {
@Autowired
private BasicUserService basicUserService;
/**
* GET --> /ssm/basicUser/1 查看某个具体的用户
* POST --> /ssm/basicUser/user 新建一个用户
* PUT --> /ssm/basicUser/1 更新某个具体的用户
* DELETE --> /ssm/basicUser/1 删除某个具体的用户
*/
/**
* 增
* @param basicUser 用户对象
* @return
*/
@RequestMapping(value="/user", method = RequestMethod.POST)
@ApiOperation(value="新增用户信息", httpMethod="POST", response=ResultModel.class)
public ResultModel insertBasicUser(BasicUser basicUser) {
basicUser.setPassword(EncryptKit.MD5(basicUser.getPassword()));
int row = basicUserService.insert(basicUser);
if(row > 0) {
return new ResultModel(201, row, "新增成功");
}
return new ResultModel(200, row, "新增失败");
}
/**
* 删
* @param id 用户id
* @return
*/
@RequestMapping(value="/{id}", method = RequestMethod.DELETE)
@ApiOperation(value="删除用户信息", httpMethod="DELETE", response=ResultModel.class)
public ResultModel deleteById(@PathVariable("id")Integer id) {
int row = basicUserService.deleteById(id);
if(row > 0) {
return new ResultModel(201, row, "删除成功");
}
return new ResultModel(404, row, "删除失败");
}
/**
* 查
* @param id 用户id
* @return
*/
@RequestMapping(value="/{id}", method = RequestMethod.GET)
@ApiOperation(value="获取用户信息", httpMethod="GET", response=ResultModel.class)
public ResultModel selectById(@PathVariable("id")Integer id) {
BasicUser basicUser = basicUserService.selectById(id);
return new ResultModel(200, basicUser, "获取成功");
}
/**
* 改
* @param id 用户id
* @param realname 用户真实姓名
* @return
*/
@RequestMapping(value="/{id}", method = RequestMethod.PUT)
@ApiOperation(value="修改用户信息", httpMethod="PUT", response=ResultModel.class)
public Object updateById(@PathVariable("id")Integer id,
@ApiParam(value="真实姓名", required=true, name="realname")@RequestParam(value="realname") String realname) {
BasicUser basicUser = new BasicUser();
basicUser.setId(id);
basicUser.setRealname(realname);
int row = basicUserService.updateById(basicUser);
if(row > 0) {
return new ResultModel(201, row, "更新成功");
}
return new ResultModel(200, row, "更新失败");
}
**}
6.访问地址 http : // IP地址:端口号/项目名/swagger-ui.html 查看效果
在这里呢我们也可以简单看下查询接口其内部效果,我这就不一一贴图了,各位看官可自己实现
7.指定多个扫描路径,匹配多个Controller
从上文Swagger配置类中可以看到要么所有包,要么单个包
// 指定所有的接口
.apis(RequestHandlerSelectors.any())
//指定扫描的路径
.apis(RequestHandlerSelectors.basePackage("com.ssm.restapi"))
基于这,我们有没有办法扫描指定的某两个或三个路径下接口。我这里给出两个方法:
方法一:扫描的包为多个controller的共同包名,即精确到两个controller的上一级
方法二:指定所有controller都实现的一个接口,比如@RestController
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
//.apis(RequestHandlerSelectors.any()) 所有的接口
//指定扫描的路径
//.apis(RequestHandlerSelectors.basePackage("com.ssm.restapi"))
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.build()
.apiInfo(apiInfo());
}