ide2021
jdk17
springboot3.0.11-SNAPSHOT
在使用springboot3写完一个项目后,想快速生成一篇接口文档,供自己观看。在网上冲浪一段时间后,发现使用Swagger文档比较合适,通过少量的注解来完成一篇复杂的文档。说干就干,直接cope网上的资料写一个demo来用,发现项目无法正常启动。在翻阅了博客后,发现Swagger2暂时无法适配springboot3。后再其他博客中发现可以使用openapi兼容springboot3,同时,knife4j是对swagger的美化,所以使用knife4j-openapi3。
对应的依赖如下:
com.github.xiaoymin knife4j-openapi3-jakarta-spring-boot-starter4.1.0
配置文件采用yml格式,所以在配置中对knife4j进行如下简单配置
# 在线文档配置 springdoc: swagger-ui: # 配置swagger-ui界面访问路径 path: /swagger-ui.html # 包扫描路径 packages-to-scan: com.pjx.sys.controller # 默认开启wend api-docs: enabled: true
上述的 packages-to-scan 也就是包扫描路径,是对控制层进行扫描,也就是你的controller层,只要扫描到外面那一层,不要深入到内部。路径可以直接复制。
此时还需对knife4j进行配置,才可以使用。
在自己的项目中创建SwaggerConfig类进行配置
import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SwaggerConfig { @Bean public OpenAPI springShopOpenAPI() { return new OpenAPI() .info(new Info().title("标题") //描叙 .description("我的API文档") //版本 .version("v1") //作者信息,自行设置 .contact(new Contact().name("彭").email("11111").url("https://www.baidu.com")) //设置接口文档的许可证信息 .license(new License().name("Apache 2.0").url("http://springdoc.org"))); } }
在这里基本的配置算是完成了,接下来用一个简单的demo演示
上面是对应的结构,下面分别为控制层和pojo
import com.example.test.pojo.Books; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Tag(name = "测试",description = "描述") @RestController @RequestMapping("/getBooks") public class BookController { @GetMapping @Operation(summary = "测试接口") public Books getBooks(){ Books books = new Books(); books.setId(1); return books; } }
import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Schema @Data public class Books { @Schema(name = "id",description = "用户id",defaultValue = "12",example = "1") private Integer id; }
以上完成后,一个简单的文档就完成了,直接看效果。
doc.html
swagger-ui
在demo完成,发现没有问题后,便开始在自己的项目中导入配置,然后出现一系列问题。
当时我也不知道怎么回事,在想,为什么不可以显示?为什么swagger-ui可以使用?为什么demo可以使用?程序员的三连懵逼。。。最后在浏览了大量的博客后,发现是自己脑子抽了。
首先,要知道,这些资源在哪里,他们在knife4j的jar包中,包你虽然导入了,但是资源你不告诉spring boot,这让它怎么找?找空气吗?其次,swagger-ui可以可以使用,是因为在yml文件中配置了,doc没有配置,也没有配置方法,demo可以使用,而项目中的不可以使用,是因为springboot版本太高,有时找不到资源,需要你手动告诉它,也就回到问题1了。
对应的资源如下:
在WebConfig配置类中实现WebMvcConfigurer接口,重写addResourceHandlers方法,导入资源的位置。
@Component public class WebConfig implements WebMvcConfigurer { /** * 静态资源映射 * * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } }
如此,资源便让springboot找到了,当然,如果配置了拦截器,则需要忽略一些资源,可以在WebMvcConfigurer接口中实现addInterceptors方法,在内部用addInterceptor定义自己的拦截器,用addPathPatterns添加拦截路径和excludePatterns添加忽略路径,我的忽略路径如下
"/v3/api-docs/**", "/doc.html", "/webjars/**", "/swagger-resources", "/swagger-ui/**"
若不知道要忽略的具体资源,可以直接在浏览器的 网络 中,采用Shift+f5的方式,哪些请求报错,就忽略哪些资源。这样,doc.html便可以访问了。
这个问题说大嘛也不大,但是看着浏览器报错也不是很喜欢,在网上查阅了资料后,发现可能是图标侵权了,然后后面不让用了。
自行在静态资源文件夹下放一张favicon.ico的图片,喜欢什么就放什么,但是后缀名要相同。一定要ico的文件。从网上下载一张喜欢的,后缀名自己改好。
放入后,并没有万事大吉了,还要让spring boot知道这个图标,不然还是无法访问,同样需要添加静态资源映射。在4.1.1方法里面添加
registry.addResourceHandler("favicon.ico").addResourceLocations("classpath:/static/");
同时在忽略路径里面添加 /favicon.ico, 也就是放行这张图,让浏览器可以找到。
最后解决完成。撒花。
开玩笑啦。
直接上代码,好吧。
import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Schema @Data public class User { //id @Schema(name = "id",description = "序列号",defaultValue = "1",example = "1") private Integer id; //用户名 @Schema(name = "username",description = "用户名",defaultValue = "not null",example = "admin") private String username; //密码 @Schema(name = "password",description = "密码",defaultValue = "not null",example = "******") private String password; //权限id @Schema(name = "roleId",description = "权限id,判断是否拥有此权限",defaultValue = "not null",example = "admin") private Integer roleId; //是否默认 @Schema(name = "is_default",description = "0为默认用户,1为普通用户",defaultValue = "1",example = "1") private Integer is_default; //权限 @Schema(hidden = true) private Role role; //token @Schema(name = "token",description = "存储前端的token",defaultValue = "not null",example = "dsafasdff341234123...") private String token; }
@Schema注解用于描述类的属性,description为描叙,defaultValue为默认值,example为举例子,hidden为忽略。
import com.pjx.sys.service.UploadService; import com.pjx.sys.util.R; import com.pjx.sys.util.SYSCode; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.FileNotFoundException; @Tag(name = "上传图片") @RestController @RequestMapping("/adminapi/upload") public class UploadController { //导入UploadService @Resource private UploadService uploadService; @Operation(method = "POST", summary = "更新背景图", description = "通过传入指定规格的图片,更新实验室的背景图") @PostMapping public R uploadBg(@Parameter(description = "图片对象") @RequestParam("file") MultipartFile file) { try { uploadService.uploadBg(file); return new R(SYSCode.CODE_SUCCESS, "上传成功"); } catch (FileNotFoundException e) { e.printStackTrace(); } return new R(SYSCode.CODE_ERROR, "上传失败"); } }
@Tag用于对API接口进行标记和分组。
@Operation用于对API接口方法进行详细的操作描述,method为方法,summary为简介,description为描叙。
@Parameter用于指定操作的参数列表。
其他的方法不全,暂时如下: