目录
springdoc官网
swagger2与swagger3注解对照
swagger3注解在 io.swagger.v3.oas.annotations 包中,不要导错
swagger2 | swagger3 |
---|---|
@Api | @Tag |
@ApiIgnore | @Parameter(hidden = true) 或 @Operation(hidden = true) 或 @Hidden |
@ApiImplicitParam | @Parameter |
@ApiImplicitParams | @Parameters |
@ApiModel | @Schema |
@ApiModelProperty(hidden = true) | @Schema(accessMode = Schema.AccessMode.READ_ONLY) |
@ApiModelProperty | @Schema |
@ApiOperation(value = “foo”, notes = “bar”) | @Operation(summary = “foo”, description = “bar”) |
@ApiParam | @Parameter |
@ApiResponse(code = 404, message = “foo”) | @ApiResponse(responseCode = “404”, description = “foo”) |
maven依赖
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.5.3</version>
</dependency>
swagger3的开启和关闭
application.yml
springdoc:
api-docs:
enabled: true #默认为true开启
swagger3的配置
Swagger3Config.java
package com.szh.demo.common.config;
import org.springdoc.core.GroupedOpenApi;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.parameters.Parameter;
@Configuration
public class Swagger3Config {
//配置一个test-public组
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("test-public")
.packagesToScan("com.szh.demo.material")
// .pathsToMatch("/material/**")
.addOperationCustomizer(operationCustomizer())
.build();
}
//配置其他组
@Bean
public GroupedOpenApi otherApi() {
return GroupedOpenApi.builder()
.group("test-other")
.packagesToScan("com.szh.demo.other")
// .pathsToMatch("/other/**")
.build();
}
/**
* 给所有@Operation注释的接口添加一个tellerno请求头参数
* @return
*/
@Bean
public OperationCustomizer operationCustomizer () {
return new OperationCustomizer() {
@Override
public Operation customize(Operation operation, HandlerMethod handlerMethod) {
operation.addParametersItem(
new Parameter()
.in(ParameterIn.HEADER.toString())
.name("tellerno")
.description("登录用户账号")
.schema(new StringSchema())
.required(false)
);
return operation;
}
};
}
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info().title("Swagger3 test API")
.description("Swagger3 test sample application")
.version("v1.0.0")
.license(new License().name("Apache 2.0").url("http://springdoc.org")))
.externalDocs(new ExternalDocumentation()
.description("SpringShop Wiki Documentation")
.url("https://springshop.wiki.github.org/docs"));
}
}
实体类示例
Material.java
package com.szh.demo.material.entity;
import java.io.Serializable;
import java.time.LocalDateTime;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Null;
import com.szh.demo.common.validate.ByteSize;
import com.szh.demo.common.validate.In;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "素材表实体", description = "素材表实体description")
public class Material implements Serializable {
public interface Save {}
private static final long serialVersionUID = 1L;
@Null(groups = {Save.class}, message = "id必须为null")
@Schema(description = "主键", example = "0")
private Long id;
@Schema(description = "适用机构号")
private String orgcode;
//@In是自定义的Bean Validation注解,未展示
@In(groups = {Save.class}, value = {"00", "01", "02"}, message = "素材类型必须是{value}之一")
@NotBlank(groups = {Save.class}, message = "素材类型不能为空")
@Schema(description = "素材分类 00图片 01视频 02PDF", allowableValues = {"00", "01", "02"})
private String materialType;
@Schema(description = "素材类型名称", accessMode = Schema.AccessMode.READ_ONLY)
private String materialTypeName;
//@ByteSize是自定义的Bean Validation注解,未展示
@NotBlank(groups = {Save.class}, message = "素材名称不能为空")
@ByteSize(groups = {Save.class}, min = 1, max = 200, message = "素材名称字节长度必须在{min}-{max}之间")
@Schema(description = "素材名称")
private String materialName;
@NotBlank(groups = {Save.class}, message = "素材路径必须包含可见字符")
@Schema(description = "素材路径")
private String materialPath;
@Null(groups = {Save.class}, message = "vertical必须为null")
@Schema(description = "素材方向", accessMode = Schema.AccessMode.READ_ONLY)
private String vertical;
@Schema(description = "素材方向名称", accessMode = Schema.AccessMode.READ_ONLY)
private String verticalName;
@Null(groups = {Save.class}, message = "converted必须为null")
@Schema(description = "视频是否已完成转码", accessMode = Schema.AccessMode.READ_ONLY)
private String converted;
@Null(groups = {Save.class}, message = "failcount必须为null")
@Schema(description = "转码失败次数", accessMode = Schema.AccessMode.READ_ONLY)
private Integer failcount;
@Null(groups = {Save.class}, message = "createId必须为null")
@Schema(description = "创建用户", accessMode = Schema.AccessMode.READ_ONLY)
private Long createId;
@Null(groups = {Save.class}, message = "createDatetime必须为null")
@Schema(description = "创建时间", accessMode = Schema.AccessMode.READ_ONLY)
private LocalDateTime createDatetime;
@Null(groups = {Save.class}, message = "updateId必须为null")
@Schema(description = "修改用户", accessMode = Schema.AccessMode.READ_ONLY)
private Long updateId;
@Null(groups = {Save.class}, message = "updateDatetime必须为null")
@Schema(description = "修改时间", accessMode = Schema.AccessMode.READ_ONLY)
private LocalDateTime updateDatetime;
}
Controller示例
MaterialController.class
package com.szh.demo.material.controller;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.szh.demo.common.dto.Pagination;
import com.szh.demo.material.entity.Material;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
@RestController
@RequestMapping("/material/")
@Tag(name = "素材表", description = "素材表接口")
@Validated
@Slf4j
public class MaterialController {
@Operation(summary = "保存素材表", description = "保存素材表description")
@PostMapping("save")
public void save(@Validated({Material.Save.class}) @RequestBody Material material) {
log.info(material.toString());
}
@Operation(summary = "查询素材表详情", description = "根据主键查询description")
@Parameter(name = "id", description = "主键", required = true)
@GetMapping("detail")
public Material detail(@NotNull(message = "id不能为空") Long id) {
log.info(id.toString());
return null;
}
@Operation(summary = "删除素材表", description = "根据主键删除description")
@Parameter(name = "id", description = "主键", required = true)
@GetMapping("delete")
public void delete(@NotNull(message = "id不能为空") Long id) {
log.info(id.toString());
}
//@Parameter(in = ParameterIn.QUERY) 表示接口参数不是application/json的形式,而是form-data的形式
@Operation(summary = "查询素材表列表", description = "基础列表查询,只包含所有属性and.eq条件description")
@PostMapping("list")
public List<Material> list(@Parameter(in = ParameterIn.QUERY) Material material, @Parameter(in = ParameterIn.QUERY) @Validated Pagination pagination) {
log.info(material.toString());
log.info(pagination.toString());
return new ArrayList<Material>();
}
}
附 Pagination.java示例
package com.szh.demo.common.dto;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 分页参数
* @author Administrator
*
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "分页参数", description = "分页参数description")
public class Pagination {
@NotNull(message = "current不能为空")
@Min(value = 1, message = "current不能小于{value}")
@Schema(description = "当前页", example = "1")
private Integer current;
@NotNull(message = "size不能为空")
@Min(value = 1, message = "size不能小于{value}")
@Schema(description = "每页条数", example = "10")
private Integer size;
}
Swagger UI效果
Swagger UI默认访问地址
http://server:port/context-path/swagger-ui.html
不是http://server:port/context-path/swagger-ui/index.html