本文将讲述 springboot 整合swagger 的具体流程。Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
目录
1. 引入swagger 库:
<!--Swagger2接口文档相关依赖-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
不同版本查询https://mvnrepository.com/artifact/io.springfox/springfox-swagger2
这里我们使用最多人使用的 2.9.2 版本。
2. 进行 SwaggerConfig 配置
// SwaggerConfig.java 放在config包下
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;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket buildDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(buildApiInfo())
.select()
// 要扫描的API(Controller)基础包
.apis(RequestHandlerSelectors.basePackage("top.nihilwater.nihilfile"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo buildApiInfo() {
Contact contact = new Contact("nihilwater","blog.nihilwater.top",""); // 作者信息
return new ApiInfoBuilder()
.title("虚拟文件系统后台接口") // 接口业务名称
.description("虚拟文件系统后台接口的描述信息") // 描述西信息
.contact(contact)
.version("1.0.0").build();
}
}
访问方式
好,现在你已经可以重启项目,看看swagger的效果了,访问路由/swagger-ui.html
就可以访问。例如http://localhost:8080/swagger-ui.html 8080为你的springboot服务器所绑定的端口。项目中原有的在controller 定义的接口就显示了出来。
这样虽然也可以使用了,但如果要添加一些其他的解释性内容需要我们配置一些@Api注解内容。往下,将以案例的形式,讲解在项目中常用的 swagger 注解。
使用案例
解析json是最常见的需求,我们需要配实体类或POJO类的信息。举一个例子,我们在用户登陆时如果用json 传输用户名和密码,那么后台解析应该是这样
@PostMapping(value = “/login”)
public String login(@RequestBody NameAndPassWord userinfo){
为了让 swagger 解析 json 数据更具有可读性,要对NameAndPassWord 进行如下的@ApiModel()
和@ApiModelProperty()
,具体的使用方法如下所示。
swagger 解析json
// NameAndPassWord .java 放在 pojo包下
// 对于 登陆参数 NameAndPassWord 的解析案例(根据自己的实际需求修改)
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("用户名、密码") //注释这个类的信息
public class NameAndPassWord {
@ApiModelProperty(value = "用户名", dataType = "String", example = "nihilwater")
String username;
@ApiModelProperty(value = "用户密码", dataType = "String")
String password;
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
(这里也是可以通过配置mybatis-plus-generator 进行生成的)
swagger 通用返回对象
再举一个例子,我们一般会封装自己的返回结构,本质上是swagger 对于 json 的解析。
// Res.java 放在 pojo 包下
// 通用返回对象,你可以直接复制到你的项目中。
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
@ApiModel("通用返回对象")
public class Res<T> implements Serializable {
//解释各字段的意思
@ApiModelProperty(value = "返回码", dataType = "String")
private int code;
@ApiModelProperty(value = "提示信息", dataType = "String")
private String msg;
@ApiModelProperty(value = "返回值", dataType = "String")
private T data;
// getter 和 setter
public int getCode() { return code; }
public void setCode(int code) { this.code = code; }
public String getMsg() { return msg; }
public void setMsg(String msg) { this.msg = msg; }
public T getData() { return data; }
public void setData(T data) { this.data = data; }
//几种构造方法
public Res() { }
public Res(int code, String msg) {
this.code = code;
this.msg = msg;
}
public Res(int code, String msg, T data) {
this.code = code;
this.msg = msg;
if (data != null) {
this.data = data;
}
}
//静态方法要使用泛型参数的话,要声明其为泛型方法
public static <T> Res<T> success() {
return success("操作成功");
}
public static <T> Res<T> success(T data) {
return success("操作成功", data);
}
public static <T> Res<T> success(String msg) {
return success(msg, (T) null);
}
public static <T> Res<T> success(String msg, T data) {
return new Res<T>(Res.SUCCESS, msg, data);
}
public static <T> Res<T> warn(String msg) {
return warn(msg, (T) null);
}
public static <T> Res<T> warn(String msg, T data) {
return new Res<T>(Res.WARN, msg, data);
}
public static <T> Res<T> unAuth() {
return new Res<T>(Res.UNAUTH, "未登陆", (T)null);
}
public static <T> Res<T> error() {
return error("操作失败");
}
public static <T> Res<T> error(String msg) {
return error(msg, (T)null);
}
public static <T> Res<T> error(String msg, T data) {
return new Res<T>(Res.ERROR, msg, data);
}
public static int SUCCESS = 200;
public static int WARN = 402;
public static int UNAUTH = 401;
public static int ERROR = 500;
}
swagger 对于 *Controller.java 的配置
除了配置实体类,我们还可以对一个controller 做整体性的描述。我们以用户登陆为例,在例子中我们实现了两个方法,一个是用户登陆,接收参数为前文定义的NameAndPassWord, 返回值为包含用户信息的token。一个是获取用户信息的方法,他需要的参数是header参数中的token,返回值为用户的userID 和 authority。具体配置如下。
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
import top.nihilwater.nihilfile.config.interceptor.NoNeedToken;
import top.nihilwater.nihilfile.pojo.NameAndPassWord;
import top.nihilwater.nihilfile.pojo.Res;
import top.nihilwater.nihilfile.service.UserService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
@RestController
/** 表示标识这个类是swagger的资源 **/
@Api(value = "用户模块", tags = "用户基础信息接口模块")
@RequestMapping("/user")
public class UserController extends BaseController{
@Resource
UserService userService; // 提供查询功能,根据用户nick查询到用户
// 用户登陆方法
/** 表示一个http请求的操作 **/
@ApiOperation(value = "用户登陆事件", notes = "根据用户名和密码获取用户token")
@PostMapping(value = "/login")
public String login(HttpServletResponse response, @RequestBody NameAndPassWord userinfo){
if(userinfo.getUsername() == null){
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return "";
}
return userService.login(userinfo.getUsername(), userinfo.getPassword());
}
// 获取用户信息方法
@ApiOperation(value = "测试用户token信息", notes = "根据用户token解析出用户id以及")
/** 包含多个 @ApiImplicitParam **/
@ApiImplicitParams({
/** 表示单独的请求参数 **/
@ApiImplicitParam(name = "token", value = "用户token", required = true, dataType = "String", paramType = "header")
})
@GetMapping(value = "/test")
public Res<Map<String, String>> test(){
Map<String, String> res = new HashMap<>();
res.put("userID", this.UserId); // 这里是继承了BaseController
res.put("authority",this.authority);
return new Res<>(Res.SUCCESS, "请求成功", res);
}
}
效果展示
经过以上的配置,我们基本完成了对于用户模型的所有配置,重启项目之后我们可以看见这样的信息。
总结常用注解:
注解名 | 作用域 | 说明 |
---|---|---|
@Api() | 类 | @Api(value = "模块名称", tags = "描述") 表示标识这个类是swagger的资源 |
@ApiOperation() | 方法 | @ApiOperation(value = "处理方法名", notes = "描述") 表示一个http请求的操作 |
@ApiParam() | 方法,参数,字段说明 | public User get(@ApiParam(name="id",value="用户id",required=true) Long id) 表示对参数的添加元数据(说明或是否必填等) |
@ApiModel() | 类 | @ApiModel(value="user对象",description="用户对象user") 表示对类进行说明,用于参数用实体类接收 |
@ApiModelProperty() | 方法,字段 | @ApiModelProperty(value="用户名",name="username",example="xingguo") 表示对model属性的说明或者数据操作更改 |
@ApiIgnore | 类,方法,方法参数 | @ApiIgnore 类 | 方法 | 方法参数 表示这个方法或者类被忽略 |
@ApiImplicitParam() | 方法 | @ApiImplicitParam(name = "token", value = "用户token", required = true, dataType = "String", paramType = "header") 表示单独的请求参数 |
@ApiImplicitParams() | 方法 | 包含多个 @ApiImplicitParam |
常见问题:拦截器放行(可选)
如果你配置了拦截器来进行用户权限的管理或者其他业务,需要使用.excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**")
将swagger排除在拦截路由之外。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Resource
TokenInterceptor tokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 设置所有的路径都要进行拦截,除了 swagger 相关
registry.addInterceptor(tokenInterceptor).addPathPatterns("/**")
.excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
}
}