简介
Knife4j基于swagger2再次封装的一个接口测试工具,是开发中较为常用的接口测试工具,该工具可以使前后端接口连通更加简便,前端程序员更直观的发现后端接口所需的必要参数,从而使我们后端程序员可以减少和前端交流沟通的工作量。
1.依赖
<!--knife4j-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.6.2</version>
</dependency>
2.application.yaml文件
spring:
profiles:
active: test
---
server:
port: 9988
spring:
profiles: test
# Swagger配置
swagger:
# 是否开启swagger
enabled: true
# 请求前缀
pathMapping: /
3.swagger配置
package com.diswdata.basic.config;
import com.diswdata.basic.vo.ResultCode;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
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.builders.ResponseBuilder;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.springframework.http.HttpMethod.*;
/**
* Swagger2的接口配置
*/
@EnableSwagger2
@EnableKnife4j
@Configuration
public class SwaggerConfig {
/**
* 是否开启swagger
*/
@Value("${swagger.enabled}")
private boolean enabled;
/**
* 设置请求的统一前缀
*/
@Value("${swagger.pathMapping}")
private String pathMapping;
/**
* 创建API
*/
@Bean
public Docket createRestApi() {
List<Response> responseList = new ArrayList<>();
Arrays.stream(ResultCode.values()).forEach(resultCode -> {
responseList.add(new ResponseBuilder().code(resultCode.getCode().toString()).description(resultCode.getMsg()).build());
});
return new Docket(DocumentationType.SWAGGER_2)
// 是否启用Swagger
.enable(enabled)
// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
.apiInfo(apiInfo())
// 设置哪些接口暴露给Swagger展示
.select()
// 扫描所有有注解的api,用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解
// .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有
// .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
/* 设置安全模式,swagger可以设置访问token */
// .securitySchemes(securitySchemes())
// .securityContexts(securityContexts())
.pathMapping(pathMapping)
.globalResponses(GET, responseList)
.globalResponses(POST, responseList)
.globalResponses(PUT, responseList)
.globalResponses(DELETE, responseList);
}
/**
* 安全模式,这里指定token通过Authorization头请求头传递
*/
private List<SecurityScheme> securitySchemes() {
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "易启勇", In.HEADER.toValue()));
return apiKeyList;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts() {
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build());
return securityContexts;
}
/**
* 默认的安全上引用
*/
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo() {
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title("标题:基础管理系统接口文档")
// 描述
.description("描述:基础管理系统接口文档")
// 作者信息
.contact(new Contact("", null, null))
// 版本
.version("版本号: ")
.build();
}
}
4.响应VO的封装
package com.diswdata.basic.vo;
import lombok.*;
/**
* @className: ResultCode
* @author: houqd
* @date: 2022/11/1
**/
@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum ResultCode {
SUCCESS(1,"成功"),
ERROR(0,"失败"),
SERVER_ERROR(500,"服务器错误"),
UNLAWFUL(401,"无权限"),
PARAM_ERROR(405,"参数错误"),
NOT_LOGIN(406,"未登录");
private Integer code;
private String msg;
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.diswdata.basic.vo;
import io.swagger.annotations.ApiModel;
import org.springframework.http.HttpStatus;
import java.io.Serializable;
@ApiModel("返回信息封装类")
public class ResponseVO<T> implements Serializable {
private Integer code;
private String msg;
private T data;
public ResponseVO(Integer code) {
this.code = code;
}
public ResponseVO(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public ResponseVO(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public static ResponseVO success() {
return new ResponseVO(HttpStatus.OK.value());
}
public static ResponseVO success(String msg) {
return new ResponseVO(HttpStatus.OK.value(), msg);
}
public static ResponseVO success(Object data) {
return new ResponseVO(HttpStatus.OK.value(), "成功", data);
}
public static ResponseVO success(String msg, Object data) {
return new ResponseVO(HttpStatus.OK.value(), msg, data);
}
public static ResponseVO fail() {
return new ResponseVO(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
public static ResponseVO fail(Object data) {
return new ResponseVO(HttpStatus.INTERNAL_SERVER_ERROR.value(), (String)null, data);
}
public static ResponseVO fail(String msg) {
return new ResponseVO(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg);
}
public static ResponseVO fail(String msg, Object data) {
return new ResponseVO(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg, data);
}
public static ResponseVO fail(Integer code, String msg) {
return new ResponseVO(code, msg);
}
public static ResponseVO tips(String msg) {
return new ResponseVO(HttpStatus.BAD_REQUEST.value(), msg);
}
public static <T> ResponseVOBuilder<T> builder() {
return new ResponseVOBuilder();
}
public ResponseVO() {
}
public Integer getCode() {
return this.code;
}
public String getMsg() {
return this.msg;
}
public T getData() {
return this.data;
}
public void setCode(final Integer code) {
this.code = code;
}
public void setMsg(final String msg) {
this.msg = msg;
}
public void setData(final T data) {
this.data = data;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof ResponseVO)) {
return false;
} else {
ResponseVO<?> other = (ResponseVO)o;
if (!other.canEqual(this)) {
return false;
} else {
label47: {
Object this$code = this.getCode();
Object other$code = other.getCode();
if (this$code == null) {
if (other$code == null) {
break label47;
}
} else if (this$code.equals(other$code)) {
break label47;
}
return false;
}
Object this$msg = this.getMsg();
Object other$msg = other.getMsg();
if (this$msg == null) {
if (other$msg != null) {
return false;
}
} else if (!this$msg.equals(other$msg)) {
return false;
}
Object this$data = this.getData();
Object other$data = other.getData();
if (this$data == null) {
if (other$data != null) {
return false;
}
} else if (!this$data.equals(other$data)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof ResponseVO;
}
public int hashCode() {
int result = 1;
Object $code = this.getCode();
result = result * 59 + ($code == null ? 43 : $code.hashCode());
Object $msg = this.getMsg();
result = result * 59 + ($msg == null ? 43 : $msg.hashCode());
Object $data = this.getData();
result = result * 59 + ($data == null ? 43 : $data.hashCode());
return result;
}
public String toString() {
return "ResponseVO(code=" + this.getCode() + ", msg=" + this.getMsg() + ", data=" + this.getData() + ")";
}
public static class ResponseVOBuilder<T> {
private Integer code;
private String msg;
private T data;
ResponseVOBuilder() {
}
public ResponseVOBuilder<T> code(final Integer code) {
this.code = code;
return this;
}
public ResponseVOBuilder<T> msg(final String msg) {
this.msg = msg;
return this;
}
public ResponseVOBuilder<T> data(final T data) {
this.data = data;
return this;
}
public ResponseVO<T> build() {
return new ResponseVO(this.code, this.msg, this.data);
}
public String toString() {
return "ResponseVO.ResponseVOBuilder(code=" + this.code + ", msg=" + this.msg + ", data=" + this.data + ")";
}
}
}
5.控制层测试
package com.diswdata.demo.controller;
import com.diswdata.basic.vo.ResponseVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/deviceInstance")
@Api(tags = "入侵报警设备实例控制器")
@CrossOrigin//该注解表示该类跨域
public class Knife4jController {
@GetMapping("/getPartition")
@ApiOperation(value = "获取入侵报警分区列表树", notes = "获取入侵报警分区列表树")
public ResponseVO getPartition() {
return ResponseVO.success();
}
}
6.启动类
package com.diswdata;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
public class DiswMuseumApp {
@Autowired
public static void main(String[] args) {
SpringApplication.run(DiswMuseumApp.class, args);
}
}