삑 하는 소리
머리말
이 글은 API 시각화 프레임워크인 Swagger를 SpringBoot 프레임워크에 통합하는 과정을 소개하고, 통합 과정에서 부딪히는 문제점을 논의하고, Swagger2의 일련의 콘텐츠를 테스트해 볼 것입니다.
Swagger에 대한 간략한 소개
Swagger는 RESTful 웹 서비스를 생성, 설명, 호출 및 시각화하기 위한 사양 및 완전한 프레임워크입니다. 전반적인 목표는 클라이언트와 파일 시스템이 서버와 동일한 속도로 업데이트되도록 하는 것입니다. 메서드, 매개변수 및 모델 문서화는 서버 측 코드에 긴밀하게 통합되어 API가 항상 동기화 상태를 유지할 수 있도록 합니다. Swagger를 사용하면 배포 관리와 강력한 API 사용이 그 어느 때보다 쉬워집니다.
준비
통합을 시작하기 전에 SpringBoot 프로젝트를 생성해야 합니다.이 문서에서 사용된 도구 및 버전은 다음과 같습니다.
프로젝트 | 콘텐츠 |
---|---|
IDE | 나는 그 생각을 이해한다 |
자바 | 만년 동안 변하지 않은 Java8 |
스프링부트 | 2.2.5.릴리스 |
SpringBoot 버전이 2.6 이상인 경우 기본 경로 일치 방법은 PathPatternMatcher이고 Swagger2는 AntPathMatcher를 기반으로 하며 documentationPluginsBootstrapper'가 있을 것이며 중첩 예외는 java.lang.NullPointer 오류입니다. 둘의 궁합! ! !
종속성 소개
이 기사에서는 Maven을 관리 도구로 사용하는 방법에 대해 설명합니다. Swagger2를 도입하는 두 가지 방법, 즉 스타터 방법과 기본 Maven 종속성 방법이 있습니다.
기본 Maven 종속성
Swagger2의 종속성은 Maven 창고 에서 찾을 수 있습니다 . 사용된 버전은 2.9.2
이며 종속성은 여기에 게시됩니다.
<!-- swagger start -->
<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>
<!-- swagger end -->
스타터 소개
SpringForAll의 spring-boot-starter-swagger는 Spring Boot의 자동 구성 기능을 사용하여 swagger2를 스프링 부트 애플리케이션에 신속하게 도입하여 API 문서를 생성하고 swagger2의 기본 사용을 위한 통합 코드를 단순화합니다.
spring-boot-starter-swagger의 GitHub 페이지에 매우 자세한 소개 및 통합 자습서가 있으므로 여기서는 너무 자세히 설명하지 않고 이러한 방식으로 통합해야 하는 경우 spring-boot로 이동하십시오. -스타터- 스웨거 .
기타 의존성
롬복
swagger2 및 SpringBoot의 종속성 외에도 Lombok을 도입하여 일부 get/set/toString 메서드 작성을 줄이고 전임자가 만든 휠을 합리적으로 사용합니다.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
물론 IDEA를 활용하여 프로젝트를 만들 때 Lombok을 도입하는 것이 불가능한 것은 아닙니다.
commons-lang3
commons-lang3에는 많은 도구 클래스가 있으며 여기에서도 인용합니다.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
구성
여기서는 여전히 기본 Maven 종속성의 통합에 중점을 둡니다.구성을 위해 구성 파일을 사용하는 Starter와 달리 기본 메서드는 구성 클래스를 사용하여 구성해야 합니다.
물론 이 기사에서는 구성 클래스와 구성 파일을 함께 사용하여 유연하지 않은 구성 문제도 해결할 수 있습니다.
Swagger 속성
여기서는 Swagger2 구성 클래스에 필요한 매개변수를 Properties 클래스로 캡슐화합니다. src/main/java 패키지에서 Properties 클래스를 저장할 config/properties 패키지를 만듭니다.
package com.javafeng.boxcloud.config.properties;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.stereotype.Component;
import java.util.List;
@Data
@Component
@ConfigurationProperties(prefix = "swagger")
public class SwaggerProperties {
// 是否启用Swagger
private boolean enable;
// 扫描的基本包
@Value("${swagger.base.package}")
private String basePackage;
// 联系人邮箱
@Value("${swagger.contact.email}")
private String contactEmail;
// 联系人名称
@Value("${swagger.contact.name}")
private String contactName;
// 联系人网址
@Value("${swagger.contact.url}")
private String contactUrl;
// 描述
private String description;
// 标题
private String title;
// 网址
private String url;
// 版本
private String version;
}
application.yml
다음으로 application.yml 또는 application.properties 구성 파일을 구성합니다. 이 문서에서는 Properties 클래스와 일치하는 application.yml을 사용합니다.
spring:
application:
name: BoxCloud
swagger:
# 是否启用
enable: true
base:
# 扫描的包,多个包使用逗号隔开
package: com.javafeng
contact:
email: [email protected]
name: JAVAFENG
url: https://www.javafeng.com
description:
title: ${
spring.spring.name} API Document
url: https://www.javafeng.com
version: @project.version@
Swagger2Config
매개변수가 구성된 후 Swagger2Config를 구성합니다. 여기서는 spring-boot-plus 의 구성 방법 을 참조 하고 몇 가지 단순화합니다.
package com.javafeng.boxcloud.config;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.javafeng.boxcloud.config.properties.SwaggerProperties;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.RequestHandler;
import springfox.documentation.annotations.ApiIgnore;
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.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Autowired
private SwaggerProperties swaggerProperties;
// 扫描多包时,包路径的拆分符,分号
private static final String SPLIT_COMMA = ",";
// 扫描多包时,包路径的拆分符,逗号
private static final String SPLIT_SEMICOLON = ";";
// Swagger忽略的参数类型
private Class<?>[] ignoredParameterTypes = new Class[]{
ServletRequest.class,
ServletResponse.class,
HttpServletRequest.class,
HttpServletResponse.class,
HttpSession.class,
ApiIgnore.class
};
@Bean
public Docket createRestApi() {
// 获取需要扫描的包
String[] basePackages = getBasePackages();
ApiSelectorBuilder apiSelectorBuilder = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select();
// 如果扫描的包为空,则默认扫描类上有@Api注解的类
if (ArrayUtils.isEmpty(basePackages)) {
apiSelectorBuilder.apis(RequestHandlerSelectors.withClassAnnotation(Api.class));
} else {
// 扫描指定的包
apiSelectorBuilder.apis(basePackage(basePackages));
}
Docket docket = apiSelectorBuilder.paths(PathSelectors.any())
.build()
.enable(swaggerProperties.isEnable())
.ignoredParameterTypes(ignoredParameterTypes);
return docket;
}
/**
* 获取apiInfo
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(swaggerProperties.getTitle())
.description(swaggerProperties.getDescription())
.termsOfServiceUrl(swaggerProperties.getUrl())
.contact(new Contact(swaggerProperties.getContactName(), swaggerProperties.getContactUrl(), swaggerProperties.getContactEmail()))
.version(swaggerProperties.getVersion())
.build();
}
/**
* 获取扫描的包
*
* @return
*/
public String[] getBasePackages() {
String basePackage = swaggerProperties.getBasePackage();
if (StringUtils.isBlank(basePackage)) {
throw new RuntimeException("Swagger basePackage不能为空");
}
String[] basePackages = null;
if (basePackage.contains(SPLIT_COMMA)) {
basePackages = basePackage.split(SPLIT_COMMA);
} else if (basePackage.contains(SPLIT_SEMICOLON)) {
basePackages = basePackage.split(SPLIT_SEMICOLON);
}
return basePackages;
}
public static Predicate<RequestHandler> basePackage(final String[] basePackages) {
return input -> declaringClass(input).transform(handlerPackage(basePackages)).or(true);
}
private static Function<Class<?>, Boolean> handlerPackage(final String[] basePackages) {
return input -> {
// 循环判断匹配
for (String strPackage : basePackages) {
boolean isMatch = input.getPackage().getName().startsWith(strPackage);
if (isMatch) {
return true;
}
}
return false;
};
}
@SuppressWarnings("deprecation")
private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
return Optional.fromNullable(input.declaringClass());
}
}
knife4j 강화
Enhancement의 구성이 간단하고 Enhancement 사용의 효율성이 높기 때문에 이 부분의 콘텐츠를 고급화했습니다. 이전과 함께 설명하지 않은 이유는 Swagger에서 나온 것과 knife4j에서 나온 것을 구분하기 쉽도록 이해하기 쉽기 때문입니다.
이 기사에서는 Swagger의 향상된 기능으로 knife4j를 통합하고 pom에 종속성을 추가합니다.
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
application.yml에 다음 구성을 추가합니다.
knife4j:
enable: ${swagger.enable} -- knife4j启用与否取决于Swagger是否启用
basic:
enable: true
username: admin
password: admin
Swagger2Config를 수정하고 knife4j를 활성화하기 위한 관련 메모를 추가합니다.
......
@Configuration
@EnableSwagger2
@EnableKnife4j
public class Swagger2Config {
......
}
knife4j의 자세한 구성은 필요에 따라 공식 웹 사이트에서 확인할 수 있습니다.
Knife4j 2.0.6 이상, @EnableKnife4j 주석을 사용할 필요 없이 구성 파일에서 knife4j.enable = true를 구성하기만 하면 됩니다. 여기서 구분하기 위해 데모용으로 2.0.2를 사용한다.
시험
위의 단계가 완료되면 기본적으로 예비 구성 작업이 완료되며 브라우저에서 직접 액세스할 수 있습니다: http://localhost:8080/swagger-ui.html, 구성이 완료되었음을 나타내는 다음 인터페이스가 나타납니다. 성공적인:
향상이 구성되었으므로 knife4j를 사용하여 확인하는 것이 좋습니다. http://localhost:8080/doc.html을 방문하면 향상 구성이 성공했음을 나타내는 다음 인터페이스가 나타납니다(이 페이지 전에 사용자 이름과 암호가 필요한 페이지는 구성을 따르십시오. 작성하십시오):
사용
이 부분의 스크린샷은 knife4j 페이지의 스크린샷이며 표시 효과와 페이지 논리가 더 명확합니다.
다음으로 컨트롤러를 생성하고 테스트를 위한 일부 인터페이스를 선언합니다.여기에서는 사용자 추가, 삭제, 확인 및 수정, 아바타 업로드 및 로그인과 같은 기능을 시뮬레이션하여 Swagger2를 전반적으로 사용하는 방법을 보여줍니다. 클래스에 나타나는 Swagger2 주석은 클래스가 끝난 후 소개될 예정입니다(공통 속성만 소개되며, 심층 연구가 필요한 경우 공식 웹사이트의 문서를 참조하는 것이 좋습니다).
실제로 여기에서 구별해야 할 몇 가지 상황이 있습니다.
- 입력 매개변수가 엔티티 클래스인지 여부
- 응답이 엔티티 클래스인지 여부
위에서 언급한 Api 인터페이스 중 간단한 분석:
- 새 인터페이스, 수정된 인터페이스, 로그인 인터페이스 및 기타 입력 매개변수는 엔티티 클래스이고 기타 입력 매개변수는 비엔티티 클래스입니다.
- 검색 인터페이스의 응답은 엔터티 클래스이고 나머지 응답은 비엔티티 클래스입니다.
다른 상황에 따라 다른 Swagger 주석이 처리에 사용됩니다.
엔티티 클래스
import lombok.Data;
@Data
@ApiModel(value = "用户", description = "查询用户")
public class Users {
@ApiModelProperty(value = "ID", example = "1")
private Integer id;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "头像")
private String avatar;
public Users(Integer id, String username, String password, String avatar) {
this.id = id;
this.username = username;
this.password = password;
this.avatar = avatar;
}
public Users() {
}
}
@ApiModel
주석/공통 속성 | 설명하다 |
---|---|
@ApiModel | 엔터티 클래스(모델)를 수정하는 데 사용되며 엔터티 클래스에 대한 설명으로 간주할 수 있습니다. |
값 | 모델의 대체 이름 |
설명 | 수업에 대한 자세한 설명 |
@ApiModelProperty
주석/공통 속성 | 설명하다 |
---|---|
@ApiModelProperty | 필드의 모든 측면에 대한 설명 및 제한으로 간주될 수 있는 엔터티 클래스 필드를 수정하는 데 사용됩니다. |
값 | 필드 설명 |
이름 | 원래 필드 이름을 재정의하는 새 필드 이름 |
예 | 기본값(이 필드가 문자열 유형인 경우 기본값은 ""임) |
허용 가능한 값 | 제한된 값 목록({1,2,3}), 범위 값([1,5]), 최대/최소 값([1, infinity] infinity 또는 -infinity는 무한을 의미함) 으로 표현되는 이 필드의 값 범위를 제한합니다. 가치) |
필수의 | 이 필드가 필수인지 여부를 표시합니다. 기본값은 false입니다. |
숨겨진 | 필드가 숨겨져 있는지 표시, 기본값은 false |
엔터티 클래스를 입력 매개변수로 사용할 때 위의 주석을 사용하여 엔터티 클래스 매개변수를 설명하는 목적을 달성하기 위해 엔터티 클래스를 수정할 수 있습니다.
제어 장치
여기에서 컨트롤러는 상황에 따라 별도로 설명합니다.첫 번째는 Controller 컨트롤러 클래스의 정의입니다.
package com.javafeng.boxcloud.controller;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
@Api(tags = {
"用户管理"})
public class UsersController {
/** 此处编写Api接口方法 **/
/** --start-- **/
/** --end-- **/
}
주석/공통 속성 | 설명하다 |
---|---|
@아피 | 인터페이스 그룹이라고 할 수 있는 Controller를 꾸미기 위해 사용되며, 이 클래스의 Api는 자동으로 문서를 생성합니다. |
태그 | 인터페이스 그룹의 이름으로 간주될 수 있습니다. |
다음은 인터페이스 메소드의 정의입니다.이 섹션의 시작 부분에서 인터페이스 메소드의 중앙 매개 변수 및 응답에 대해 배웠습니다.여기서 이러한 다양한 상황을 설명합니다.
- 입력 매개변수로서의 엔티티 클래스
새 인터페이스와 수정된 인터페이스는 모두 입력 매개변수로서의 엔티티 클래스입니다.
@PostMapping("/add")
@ApiOperation(value = "新增用户", notes = "用户不得为空")
public Boolean add(@RequestBody Users user) {
return true;
}
@PostMapping("/update")
@ApiOperation(value = "修改用户", notes = "用户不得为空")
public Boolean update(@RequestBody Users user) {
return true;
}
@ApiOperation
주석/공통 속성 | 설명하다 |
---|---|
@ApiOperation | 인터페이스 그룹이라고 할 수 있는 Controller를 꾸미기 위해 사용되며, 이 클래스의 Api는 자동으로 문서를 생성합니다. |
값 | API 인터페이스 이름 |
노트 | 인터페이스 설명 |
태그 | 추가 인터페이스 그룹 정의 예: @Api(tags = 'User Management')에 인터페이스 그룹이 정의된 경우에도 이 주석에 @ApiOperation(tags = 'Account Management')와 같은 다른 인터페이스 그룹을 지정할 수 있으므로 이 인터페이스는 동시에 두 인터페이스 그룹(사용자 관리 및 계정 관리)에 나타날 수 있습니다. |
엔터티 클래스를 입력 매개변수로 사용할 때 해당 매개변수 설명 주석 및 사용법은 앞선 [엔티티 클래스] 부분에서 소개했으며, @ApiOperation을 제외한 다른 주석(@ApiModel, @ApiModelProperty)은 여기서는 설명하지 않는다.
- 비엔티티 클래스를 입력 매개변수로 사용
비엔티티 클래스를 입력 매개변수로 사용하는 경우 다음과 같은 상황으로 세분할 수 있습니다.
- 일반 쿼리 매개변수
여기에서 특정 사용자를 찾는 매개변수를 공통 매개변수의 Api 메소드로 정의합니다.
@GetMapping("/get")
@ApiOperation(value = "查询单个用户")
@ApiImplicitParams({
@ApiImplicitParam(name = "id",
value = "用户ID",
required = true,
paramType = "query"
)
})
public Users get(@RequestParam("id") Integer id) {
return new Users(id, "admin", "123456", "/resource/image/head.png");
}
@ApiImplicitParams 및 ApiImplicitParam
주석/공통 속성 | 설명하다 |
---|---|
@ApiImplicitParams | 요청 매개변수를 선언하도록 Api 인터페이스 메소드 수정 |
@ApiImplicitParam | @ApiImplicitParams에 정의된 각 @ApiImplicitParam은 매개변수에 해당합니다. |
이름 | 매개변수 이름 [일반적으로 입력 매개변수 이름에 해당] |
값 | 매개변수 설명 |
필수의 | 이 매개변수가 필요한지 여부를 표시합니다. 기본값은 false입니다. |
paramType | 경로, 쿼리, 본문, 양식, 헤더 등을 포함하여 매개변수의 위치를 표시합니다. [일반적으로 본문 및 양식은 엔터티 클래스를 입력 매개변수로 사용하는 것이 좋습니다.] |
- 경로 매개변수
@DeleteMapping("/delete/{id}")
@ApiOperation(value = "删除用户", notes = "用户ID不得为空")
@ApiImplicitParams({
@ApiImplicitParam(name = "id",
value = "用户ID",
required = true,
paramType = "path"
)
})
public Boolean delete(@PathVariable("id") Integer id) {
return true;
}
매개변수가 경로 매개변수인 경우 @ApiImplicitParam의 paramType 값은 경로여야 하며 동시에 @PathVariable 주석을 사용하여 경로 매개변수를 수정합니다.
@PathVariable 어노테이션은 위 인터페이스의 {id}와 같이 URL에서 템플릿을 식별할 수 있으며, Swagger 어노테이션에 속하지 않는 템플릿을 기반으로 매개변수가 획득되었음을 표시할 수 있으며 여기서 소개하지 않습니다. .
- 헤더 매개변수
@PostMapping("/login")
@ApiOperation(value = "登录")
@ApiImplicitParams({
@ApiImplicitParam(name = "username",
value = "用户名",
required = true,
paramType = "header"
),
@ApiImplicitParam(name = "password",
value = "密码",
required = true,
paramType = "header"
)
})
public Boolean login(@RequestHeader("username") String username,@RequestHeader("password") String password) {
System.out.println(username + password);
return true;
}
매개변수가 경로 매개변수인 경우 @ApiImplicitParam의 paramType 값은 헤더여야 하며 동시에 @RequestHeader 주석을 사용하여 매개변수를 수정하고 헤더에서 얻은 매개변수의 획득 위치를 표시하여 SpringMVC가 Header. 매개변수에서 올바르게 가져올 수 있습니다.
- 파일 매개변수
여기에서는 복잡한 상황을 직접 설명합니다. 즉, 파일 매개변수와 공통 매개변수를 동시에 포함하는 것을 고려하고 실제 개발 과정에서 필요에 따라 수정합니다.
@PostMapping("/upload")
@ApiOperation(value = "上传头像", notes = "参数需要头像文件以及对应用户ID")
@ApiImplicitParams({
@ApiImplicitParam(name = "id",
value = "该头像对应的用户ID",
required = true
)
})
public Boolean upload(@ApiParam(value = "图片文件", required = true) @RequestParam("avatar") MultipartFile avatar, @RequestParam("id") Integer id) {
System.out.println(avatar);
return true;
}
对于非文件参数的普通参数,参照第一条【普通查询参数】中的声明方式即可;
对于文件参数,则需要使用@ApiParam对参数进行修饰;
@ApiParam
注解/常用属性 | 说明 |
---|---|
@ApiImplicitParams | 修饰Api接口方法,用来声明请求参数 |
value | 参数名称 |
required | 标记该参数是否必需,默认false |
allowMultiple | 是否允许多个文件,默认false |
同样的,需要在参数上使用@RequestParam进行修饰。
这里插入一个解释,就是对于同时出现Swagger注解(一般以Api作为前缀)和非Swagger注解同时对参数进行修饰时,并不会彼此影响,Swagger注解只是用来对Api方法进行描述,并不会对该方法造成实质影响,
而例如@RequestParam、@RequestHeader在内的注解是决定SpringMVC是否能正确读取到参数的关键
这里对于两种注解之间的侵入性,掘金大佬1黄鹰在其源码剖析@ApiImplicitParam对@RequestParam的required属性的侵入性做了深入剖析,感兴趣的可以去看看
- 实体类作为响应
当实体类作为响应时,通常在实体类上的注解所生成的描述也会作为响应的描述出现,在此处不再进行赘述。
- 非实体类作为响应
我们对新增接口进行修改,在其方法上添加@ApiResponses来对响应进行描述:
@PostMapping("/add")
@ApiOperation(value = "新增用户", notes = "用户不得为空")
@ApiResponses({
@ApiResponse(code = 200, message = "添加成功"),
@ApiResponse(code = 500, message = "服务器错误"),
@ApiResponse(code = 400, message = "参数异常")
})
public Boolean add(@RequestBody Users user) {
return true;
}
需要注意的是,Swagger无法对非实体类响应进行详细描述,只能通过@ApiResponses和@ApiResponse描述响应码信息。同时,在以实体类作为响应时,同样可也以使用@ApiResponses和@ApiResponse。
Token处理
在做前后端分离的应用时,后端接口通常会要求在Header中添加Token以保证安全性,这里我们依然是参考SpringBootPlus的处理方式,对Token进行处理。
需要注意的是,此处的Token处理是基于Swagger进行接口测试时的,并不是对接口如何增加Token进行讲解,只是对有Token的接口如何通过Swagger进行测试做出讲解。
修改SwaggerProperties
思路是,在Swagger配置中添加默认的全局参数描述,对Token进行处理,这里我们默认Token信息附加在Header中。
首先在SwaggerProperties中新增以下内容:
@NestedConfigurationProperty
private List<ParameterConfig> parameterConfig;
// 自定义参数配置
@Data
public static class ParameterConfig {
// 名称
private String name;
// 描述
private String description;
// 参数类型
// header, cookie, body, query
private String type = "head";
// 数据类型
private String dataType = "String";
// 是否必填
private boolean required;
// 默认值
private String defaultValue;
}
修改application.yml
随后在application.yml中对新增部分编写对应的配置项,这里贴出整体内容,自定义参数配置部分为新增内容:
spring:
application:
name: BoxCloud
swagger:
enable: true
base:
package: com.javafeng
contact:
email: [email protected]
name: JAVAFENG
url: https://www.javafeng.com
description:
title: ${spring.application.name} API Document
url: https://www.javafeng.com
version: @project.version@
# 自定义参数配置,可配置N个
parameter-config:
- name: token
description: Token Request Header
# header, cookie, body, query
type: header
data-type: String
required: false
# 测试接口时,自动填充token的值
default-value:
knife4j:
enable: ${swagger.enable}
basic:
enable: true
username: admin
password: admin
这里可以根据不同的需求,配置多个自定义参数,这里只演示了Token一个参数,如果是多个参数的话,配置多个即可,如下:
parameter-config: - name: param1 description: This is param1 type: header data-type: String required: false default-value: parameter-config: - name: param2 description: This is param2 type: header data-type: String required: false default-value: parameter-config: - name: param3 description: This is param3 type: header data-type: String required: false default-value:
修改Swagger2Config
接下来,我们在Swagger2Config中对Token参数进行处理,首先在Swagger2Config中添加如下方法,从application.yml中获取到配置的额外Token参数并进行封装:
/**
* 添加额外参数
*
* @return
*/
private List<Parameter> getParameters() {
// 获取自定义参数配置
List<SwaggerProperties.ParameterConfig> parameterConfig = swaggerProperties.getParameterConfig();
if (CollectionUtils.isEmpty(parameterConfig)) {
return null;
}
List<Parameter> parameters = new ArrayList<>();
parameterConfig.forEach(parameter -> {
// 设置自定义参数
parameters.add(new ParameterBuilder()
.name(parameter.getName())
.description(parameter.getDescription())
.modelRef(new ModelRef(parameter.getDataType()))
.parameterType(parameter.getType())
.required(parameter.isRequired())
.defaultValue(parameter.getDefaultValue())
.build());
});
return parameters;
}
随后修改createRestApi方法,在声明Docket的位置添加对额外参数的处理,添加后如下:
... ...
Docket docket = apiSelectorBuilder.paths(PathSelectors.any())
.build()
.enable(swaggerProperties.isEnable())
.ignoredParameterTypes(ignoredParameterTypes)
.globalOperationParameters(getParameters()); // 此处为新增
... ...
重启项目后,我们随意打开一个接口的文档,这里我们打开的是knife4j的页面,选择调试,在请求头部位置就可以看到Token的相关内容:
当然,在Swagger的原生界面也可以看到:
参考和引用
- dynamicbeam:swagger2常用注解API,来源 CSDN
- 随风行云:Spring Boot整合swagger使用教程,来源 CNBLOG
- 1 Yellow Eagle : @ApiImplicitParam이 @RequestParam의 필수 속성 , 소스 Nuggets 에 대한 침입성에 대한 소스 코드 분석
- 스프링부트플러스