Spring Boot整合Swagger3.0及Knife4j

时间:2022-12-16 18:54:37

一、什么是 Swagger

Swagger是一组围绕 OpenAPI 规范构建的开源工具,可帮助您设计、构建、记录和使用 REST API。主要的 Swagger 工具包括:

  1. Swagger Editor – 基于浏览器的编辑器,您可以在其中编写 OpenAPI 规范。

  2. Swagger UI – 将 OpenAPI规范呈现为交互式 API 文档。

  3. swagger2于17年停止维护,现在最新的版本为 Swagger3(Open Api3)。

二、什么是knife4j

knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍!

三、依赖引入

  • springfox引入方式
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>
  • knife4j引入方式
<dependency>
	<groupId>com.github.xiaoymin</groupId>
	<artifactId>knife4j-spring-boot-starter</artifactId>
	<version>3.0.3</version>
</dependency>
  • 引入美化bootstrap-UI
<!-- 引入swagger-bootstrap-ui包 -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>swagger-bootstrap-ui</artifactId>
    <version>1.8.5</version>
</dependency>

四、Swagger注解详解

  1. 使用 swagger3 注解代替 swagger2对应表

Spring Boot整合Swagger3.0及Knife4j

  1. swagger3注解详解
  • @Api

@Api 注解用于标注一个Controller(Class)在默认情况下,Swagger-Core只会扫描解析具有@Api注解的类,而会自动忽略其他类别资源(JAX-RS endpoints,Servlets等等)的注解

属性名称 备注
value url的路径值
tags 如果设置这个值、value的值会被覆盖
description 对api资源的描述
basePath 基本路径可以不配置
position 如果配置多个Api 想改变显示的顺序位置
produces For example, “application/json, application/xml”
consumes For example, “application/json,application/xml”
protocols Possible values: http, https, ws, wss.
authorizations 高级特性认证时配置
hidden 配置为true 将在文档中隐藏

实例:

@Controller
@RequestMapping(value = "/api/pet", produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE})
@Api(value = "/pet", description = "Operations about pets")
public class PetController {}
  • @ApiOperation

@ApiOperation 注解在用于对一个操作或HTTP方法进行描述。具有相同路径的不同操作会被归组为同一个操作对象。不同的HTTP请求方法及路径组合构成一个唯一操作。

属性 描述
value url的路径值
tags 如果设置这个值、value的值会被覆盖
description 对api资源的描述
basePath 基本路径可以不配置
position 如果配置多个Api 想改变显示的顺序位置
produces For example, “application/json, application/xml”
consumes For example, “application/json, application/xml”
protocols Possible values: http, https, ws, wss.
authorizations 高级特性认证时配置
hidden 配置为true 将在文档中隐藏
response 返回的对象
responseContainer 这些对象是有效的 “List”, “Set” or “Map”.,其他无效
httpMethod “GET”, “HEAD”, “POST”, “PUT”, “DELETE”, “OPTIONS” and “PATCH”
code http的状态码 默认 200
extensions 扩展属性
@RequestMapping(value = "/order/{orderId}", method = GET)
  @ApiOperation(
      value = "Find purchase order by ID",
      notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
      response = Order.class,
      tags = { "Pet Store" })
   public ResponseEntity<Order> getOrderById(@PathVariable("orderId") String orderId)
      throws NotFoundException {
    Order order = storeData.get(Long.valueOf(orderId));
    if (null != order) {
      return ok(order);
    } else {
      throw new NotFoundException(404, "Order not found");
    }
  }
  • @ApiParam

@ApiParam作用于请求方法的参数上,定义api参数的注解。

属性 描述
name 属性名称
value 属性值
defaultValue 默认属性值
allowableValues 可以不配置
required 是否属性必填
access 不过多描述
allowMultiple 默认为false
hidden 隐藏该属性
example 举例子
public ResponseEntity<Order> getOrderById(
      @ApiParam(value = "ID of pet that needs to be fetched", allowableValues = "range[1,5]", required = true)
      @PathVariable("orderId") String orderId)
public DataResult<ZonesEiaPlanPageInfoVO> detail(@RequestParam("id") @ApiParam(value = "主键", required = true) String id) {}
  • @ApiImplicitParams、@ApiImplicitParam

@ApiImplicitParams、@ApiImplicitParam也可以定义参数.

  • @ApiImplicitParams:用在请求的方法上,包含一组参数说明
  • @ApiImplicitParam:对单个参数的说明
属性 描述
name 参数名
value 参数的说明、描述
required 参数是否必须必填
paramType 参数放在哪个地方 query --> 请求参数的获取:@RequestParam header --> 请求参数的获取:@RequestHeader path(用于restful接口)–> 请求参数的获取:@PathVariable body(请求体)–> @RequestBody User user form(普通表单提交)
dataType 参数类型,默认String,其它值dataType=“Integer”
defaultValue 参数的默认值
@ApiImplicitParams({
		@ApiImplicitParam(name="mobile",value="手机号",required=true,paramType="form"),
		@ApiImplicitParam(name="password",value="密码",required=true,paramType="form"),
		@ApiImplicitParam(name="age",value="年龄",required=true,paramType="form",dataType="Integer")
	})
	@PostMapping("/login")
	public JsonResult login(@RequestParam String mobile, @RequestParam String password,
	@RequestParam Integer age){
		//...
	    return JsonResult.ok(map);
	}
  • @ApiResponses、@ApiResponse

@ApiResponses、@ApiResponse进行方法返回对象的说明
主要属性:

属性 描述
code 数字,例如400
message 信息,例如"请求参数没填好"
response 返回的类
@ApiResponses({
		@ApiResponse(code = 200, message = "请求成功",response = RestMessage .class),
		@ApiResponse(code = 400, message = "请求参数没填好",response = RestMessage .class),
		@ApiResponse(code = 404, message = "请求路径没有或页面跳转路径不对",response = RestMessage .class)
	}) 
	@ResponseBody
	@RequestMapping("/list")
	public JsonResult list(@RequestParam String userId) {
		...
		return JsonResult.ok().put("page", pageUtil);
	}
  • @ApiModel、@ApiModelProperty
  • @ApiModel用于描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)
  • @ApiModelProperty用来描述一个Model的属性
@ApiModel属性 描述
value 默认 为模型提供一个替代名称
description 描述
referencey 指定对相应类型定义的引用,覆盖指定的任何其他元数据
@ApiModelProperty属性 描述
value 默认 字段说明
name 重写属性名字
dataType 重写属性类型
required 是否必填
example 举例说明
hidden 配置为true将在文档中隐藏
@ApiModel(description= "返回响应数据")
@Data
public class RestMessage implements Serializable{

	@ApiModelProperty(value = "是否成功",required=true)
	private boolean success=true;	
	
	@ApiModelProperty(value = "错误码")
	private Integer errCode;
	
	@ApiModelProperty(value = "提示信息")
	private String message;
	
    @ApiModelProperty(value = "数据")
	private Object data;
}
  • 注: @ApiImplicitParam 跟 @ApiParam 两个注解的区别

@ApiParam和@ApiImplicitParam的功能是相同的,但是@ApiImplicitParam的适用范围更广。在非JAX-RS的场合(比如使用servlet提供HTTP接口),只能使用@ApiImplicitParam进行参数说明。我认为,这是因为接口并不显式展示入参的名称,所以没有地方去使用@ApiParam,只能在接口的方法声明上方写@ApiImplicitParam

参考文章

五、详细例子

配置文件加上@EnableOpenApi、@Configuration 会自动开启配置,启动类不需要加任何注解

@EnableOpenApi//该注解是Springfox-swagger框架提供的使用Swagger注解,该注解必须加
@EnableKnife4j//该注解是knife4j提供的增强注解,Ui提供了例如动态参数、参数过滤、接口排序等增强功能,如果你想使用这些增强功能就必须加该注解,否则可以不用加
@Configuration
public class SwaggerConfig {
/**
 * 接口构建器
 *
 * @return
 */
@Bean
public Docket docket() {
    return new Docket(DocumentationType.OAS_30).apiInfo(apiInfo())
            //用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
            .apiInfo(apiInfo())
            //设置哪些接口暴露给Swagger展示
            .select()
             // (第一种方式)扫描所有有注解的api,用这种方式更灵活
            .apis( RequestHandlerSelectors.withMethodAnnotation( ApiOperation.class ) )

            // (第二种方式)扫描指定包中的swagger注解
            .apis(RequestHandlerSelectors.basePackage("com.swagger_knife4j.swagger4j.controller"))//构建API

            // (第三种方式)扫描所有
            .apis(RequestHandlerSelectors.any())
            .paths( PathSelectors.any() )

            .paths(PathSelectors.any())
            .build()
            .groupName("XimenesChen")
            .enable(true);
  }

   /**
     * 添加摘要信息
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     * 访问地址:http://项目实际地址/swagger-ui.html
     */
   private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("整合knife-4j,swaggerui基本注解")//标题
                    .description("整合knife-4j,swaggerui基本注解-描述")//描述
                    .contact(new Contact("cxm", "https://mp.csdn.net/mp_blog/manage/article?spm=1001.2014.3001.5114", "cristianoxm@qq.com"))
                    .version("V2.05")
                    .build();
   }
}
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@ApiModel("common-result")
public class Result<T> {
    @ApiModelProperty(value = "返回状态码")
    private Integer code;
    @ApiModelProperty(value = "返回信息")
    private String message;
    @ApiModelProperty(value = "返回实体信息")
    private T data;
}
@EnableOpenApi//该注解是Springfox-swagger框架提供的使用Swagger注解,该注解必须加
@EnableKnife4j//该注解是knife4j提供的增强注解,Ui提供了例如动态参数、参数过滤、接口排序等增强功能,如果你想使用这些增强功能就必须加该注解,否则可以不用加
@Configuration
public class SwaggerConfig {
/**
 * 接口构建器
 *
 * @return
 */
@Bean
public Docket docket() {
    return new Docket(DocumentationType.OAS_30).apiInfo(apiInfo())
            //用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
            .apiInfo(apiInfo())
            //设置哪些接口暴露给Swagger展示
            .select()
             // (第一种方式)扫描所有有注解的api,用这种方式更灵活
            .apis( RequestHandlerSelectors.withMethodAnnotation( ApiOperation.class ) )

            // (第二种方式)扫描指定包中的swagger注解
            .apis(RequestHandlerSelectors.basePackage("com.swagger_knife4j.swagger4j.controller"))//构建API

            // (第三种方式)扫描所有
            .apis(RequestHandlerSelectors.any())
            .paths( PathSelectors.any() )

            .paths(PathSelectors.any())
            .build()
            .groupName("XimenesChen")
            .enable(true);
  }

   /**
     * 添加摘要信息
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     * 访问地址:http://项目实际地址/swagger-ui.html
     */
   private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("整合knife-4j,swaggerui基本注解")//标题
                    .description("整合knife-4j,swaggerui基本注解-描述")//描述
                    .contact(new Contact("cxm", "https://mp.csdn.net/mp_blog/manage/article?spm=1001.2014.3001.5114", "cristianoxm@qq.com"))
                    .version("V2.05")
                    .build();
   }
}
@Api(tags = "技术学习规划表-控制器")//@Api:用在类上,说明该类的作用
@RestController
@RequestMapping("/skillStudyPlan")
public class SkillStudyPlanController {
    @ApiOperation("插入技术学习规划")//@ApiOperation:注解来给API增加方法说明
    @PostMapping("insertPlan")
    @ApiResponses({
		@ApiResponse(code = 200, message = "请求成功",response = Result.class),
		@ApiResponse(code = 400, message = "404错误",response = Result.class),
		@ApiResponse(code = 404, message = "路径不存在",response = Result.class)
	})
    public Result<ResponseB> insertPlan(@ApiParam @RequestBody(required = false) SkillStudyPlanDTO skillStudyPlanDTO) {
        ResponseB build = ResponseB.builder().message("ss").code(200).data("data").build();
        System.out.println(skillStudyPlanDTO);
        return new Result<>(200,"ok",build);
    }

    @ApiOperation("查询所有技术学习规划")
    @GetMapping("selectAll")
    public String selectAll(@RequestParam String name,@RequestParam(required = false) Integer age) {
        System.out.print(name);
        System.out.print(age);
        return "success";
    }

    @PostMapping("pageHelp")
    @ApiOperation(value = "分页获取标签列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name="pageNo",value="请求页数",required = false,dataType="Integer",paramType="query"
            ),
            @ApiImplicitParam(name="pageSize",value="请求页大小",required = false,dataType="Integer",paramType="query"),
    })
    //header:请求头
    //query:?param=value的形式
    //path:路径,Restful风格接口
    //body:请求体
    //form:以form表单的形式提交
   @ApiResponses({
		@ApiResponse(code = 200, message = "请求成功",response = Result.class),
		@ApiResponse(code = 400, message = "请求参数没填好",response = Result.class),
		@ApiResponse(code = 404, message = "请求路径没有或页面跳转路径不对",response = Result.class)
	})
    public Result<ResponseA> pageHelp(@RequestParam Integer pageNo, @RequestParam Integer pageSize){
        ResponseA build = ResponseA.builder().message("ss").code(200).data("data").build();
        return new Result<>(200,"ok",build);
    }
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ApiModel("SkillStudyPlanDTO实体类")
public class SkillStudyPlanDTO {

    @ApiModelProperty("SkillStudyPlanDTO.name属性")
    private String name;
    @ApiModelProperty("SkillStudyPlanDTO.age属性")
    private Integer age;
}

代码链接

参考文章
参考文章
参考文章