From 0e1da3342e3c9bf0860836950927aded9a419d1b Mon Sep 17 00:00:00 2001
From: zxj <1845124851@qq.com>
Date: Wed, 18 Oct 2023 16:03:14 +0800
Subject: [PATCH] =?UTF-8?q?SpringBoot=E9=85=8D=E7=BD=AESpringDoc?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
spring-boot-springdoc/pom.xml | 8 +
.../java/com/jnssd/SpringDocApplication.java | 18 +
.../com/jnssd/config/SpringDocConfig.java | 123 ++++++
.../jnssd/config/SpringDocOpenApiConfig.java | 112 ++++++
.../com/jnssd/config/SwaggerProperties.java | 57 +++
.../jnssd/controller/CommonController.java | 17 +
.../com/jnssd/controller/MenuController.java | 52 ++-
.../com/jnssd/controller/RoleController.java | 76 +++-
.../com/jnssd/controller/UserController.java | 80 +++-
.../src/main/resources/api-doc.yaml | 365 ++++++++++++++++++
.../src/main/resources/application.yml | 50 +++
.../src/main/resources/application.yml | 2 +-
12 files changed, 930 insertions(+), 30 deletions(-)
create mode 100644 spring-boot-springdoc/src/main/java/com/jnssd/SpringDocApplication.java
create mode 100644 spring-boot-springdoc/src/main/java/com/jnssd/config/SpringDocConfig.java
create mode 100644 spring-boot-springdoc/src/main/java/com/jnssd/config/SpringDocOpenApiConfig.java
create mode 100644 spring-boot-springdoc/src/main/java/com/jnssd/config/SwaggerProperties.java
create mode 100644 spring-boot-springdoc/src/main/java/com/jnssd/controller/CommonController.java
create mode 100644 spring-boot-springdoc/src/main/resources/api-doc.yaml
create mode 100644 spring-boot-springdoc/src/main/resources/application.yml
diff --git a/spring-boot-springdoc/pom.xml b/spring-boot-springdoc/pom.xml
index 2d52493..818b081 100644
--- a/spring-boot-springdoc/pom.xml
+++ b/spring-boot-springdoc/pom.xml
@@ -23,6 +23,14 @@
com.jnssd
spring-boot-model
+
+
+
+ org.springdoc
+ springdoc-openapi-ui
+ 1.7.0
+
+
diff --git a/spring-boot-springdoc/src/main/java/com/jnssd/SpringDocApplication.java b/spring-boot-springdoc/src/main/java/com/jnssd/SpringDocApplication.java
new file mode 100644
index 0000000..7ca24b9
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/jnssd/SpringDocApplication.java
@@ -0,0 +1,18 @@
+package com.jnssd;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ *
spring-boot-openapi
+ * 入口
+ *
+ * @author zxj
+ * @since 2023-10-17 10:10:28
+ */
+@SpringBootApplication
+public class SpringDocApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(SpringDocApplication.class, args);
+ }
+}
diff --git a/spring-boot-springdoc/src/main/java/com/jnssd/config/SpringDocConfig.java b/spring-boot-springdoc/src/main/java/com/jnssd/config/SpringDocConfig.java
new file mode 100644
index 0000000..edf259d
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/jnssd/config/SpringDocConfig.java
@@ -0,0 +1,123 @@
+package com.jnssd.config;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.ExternalDocumentation;
+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 io.swagger.v3.oas.models.security.*;
+import org.springdoc.core.GroupedOpenApi;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * spring-boot-openapi
+ *
+ *
+ * @author zxj
+ * @since 2023-10-16 17:41:17
+ */
+@Configuration
+@EnableConfigurationProperties(SwaggerProperties.class)
+public class SpringDocConfig {
+ @Bean
+ public OpenAPI openAPI(SwaggerProperties properties) {
+ return new OpenAPI()
+ .info(createInfo(properties))
+ // .externalDocs(new ExternalDocumentation()
+ // .description("SpringDoc API功能 演示")
+ // .url("http://127.0.0.1:" + port + "/"))
+ .components(new Components()
+ .addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic").bearerFormat("JWT"))
+ .addSecuritySchemes("oauth2", securitySchemeOauth2Password()))
+ .addSecurityItem(new SecurityRequirement().addList("basicScheme")
+ .addList("oauth2"));
+ }
+
+ /**
+ * 文档信息
+ * @param properties 配置信息
+ */
+ Info createInfo(SwaggerProperties properties){
+ return new Info()
+ .title(properties.getTitle())
+ .description(properties.getDescription())
+ .termsOfService(properties.getTermsOfServiceUrl())
+ .contact(new Contact().name(properties.getContact().getName()).url(properties.getContact().getUrl()).email(properties.getContact().getEmail()))
+ .license(new License().name("Apache 2.0").url(properties.getLicense()))
+ .version(properties.getVersion());
+ }
+
+ @Bean
+ public GroupedOpenApi menuApi() {
+ return GroupedOpenApi.builder()
+ .addOpenApiCustomiser(openApi -> openApi.info(new Info().title("菜单 API")
+ .description("菜单 API 演示")
+ .version("v1.0.0")
+ .license(new License().name("Apache 2.0").url("jnssd.com"))
+ .contact(new Contact().name("zxj").email("zxj@163.com").url("jnssd.com"))
+ .termsOfService("jnssd")
+ ).externalDocs(new ExternalDocumentation()
+ .description("菜单 API功能 演示").url("jnssd.com")))
+ .group("menu")
+ .pathsToMatch("/menu/**")
+ .addOperationCustomizer((operation, handlerMethod) -> {
+ operation.addSecurityItem(new SecurityRequirement().addList("basicScheme").addList("oauth2"));
+ return operation;
+ })
+ .build();
+ }
+ //
+ // @Bean
+ // public GroupedOpenApi userApi() {
+ // return GroupedOpenApi.builder()
+ // .group("user")
+ // .pathsToMatch("/user/**")
+ // .build();
+ // }
+
+ // @Bean
+ // public OpenAPI customOpenAPI() {
+ // SecurityScheme oauth2Scheme = new SecurityScheme()
+ // .type(SecurityScheme.Type.OAUTH2)
+ // .flows(new OAuthFlows()
+ // .password(new OAuthFlow()
+ // .tokenUrl("/oauth/token")
+ // .scopes(new Scopes()
+ // .addString("read_scope", "Grants read access")
+ // .addString("write_scope", "Grants write access")
+ // .addString("admin_scope", "Grants read write and delete access")
+ // )
+ // )
+ // );
+ //
+ // Components components = new Components().addSecuritySchemes("OAuth2", oauth2Scheme);
+ // SecurityRequirement securityRequirement = new SecurityRequirement().addList("OAuth2");
+ //
+ // return new OpenAPI()
+ // .components(components)
+ // .addSecurityItem(securityRequirement);
+ // }
+
+ /**
+ * 配置oauth2密码模式
+ *
+ * @return
+ */
+ SecurityScheme securitySchemeOauth2Password() {
+ return new SecurityScheme()
+ .type(SecurityScheme.Type.OAUTH2)
+ .flows(new OAuthFlows()
+ .password(new OAuthFlow()
+ .tokenUrl("/oauth/token")
+ .scopes(new Scopes()
+ .addString("read_scope", "Grants read access")
+ .addString("write_scope", "Grants write access")
+ .addString("admin_scope", "Grants read write and delete access")
+ )
+ )
+ );
+ }
+}
diff --git a/spring-boot-springdoc/src/main/java/com/jnssd/config/SpringDocOpenApiConfig.java b/spring-boot-springdoc/src/main/java/com/jnssd/config/SpringDocOpenApiConfig.java
new file mode 100644
index 0000000..a6373ab
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/jnssd/config/SpringDocOpenApiConfig.java
@@ -0,0 +1,112 @@
+// package com.jnssd.config;
+//
+// import io.swagger.v3.oas.models.tags.Tag;
+// import org.springdoc.core.GroupedOpenApi;
+// import org.springdoc.core.customizers.OpenApiCustomiser;
+// import org.springdoc.core.customizers.OperationCustomizer;
+// import org.springdoc.core.customizers.RouterOperationCustomizer;
+// import org.springdoc.core.filters.OpenApiMethodFilter;
+// import org.springframework.context.annotation.Bean;
+// import org.springframework.context.annotation.Configuration;
+// import org.springframework.http.HttpMethod;
+//
+// @Configuration
+// public class SpringDocOpenApiConfig {
+//
+//
+// @Bean
+// public GroupedOpenApi publicApi() {
+// return GroupedOpenApi.builder()
+// .group("menu")
+// .pathsToMatch("/menu/**")
+// .addOperationCustomizer(customizePublicApiOperations())
+// .addOpenApiCustomiser(customizePublicApiOpenApi())
+// .addRouterOperationCustomizer(customizePublicApiRouterOperations())
+// .addOpenApiMethodFilter(publicApiMethodFilter())
+// .build();
+// }
+//
+// @Bean
+// public GroupedOpenApi privateApi() {
+// return GroupedOpenApi.builder()
+// .group("user")
+// .pathsToMatch("/user/**")
+// .addOperationCustomizer(customizePrivateApiOperations())
+// .addOpenApiCustomiser(customizePrivateApiOpenApi())
+// .addRouterOperationCustomizer(customizePrivateApiRouterOperations())
+// .addOpenApiMethodFilter(privateApiMethodFilter())
+// .build();
+// }
+//
+// // Customizing public API operations
+// private OperationCustomizer customizePublicApiOperations() {
+// return (operation, handlerMethod) -> {
+// // Customize the operations for the public API
+// operation.operationId("publicOperation");
+// operation.addTagsItem("Public API");
+// return operation;
+// };
+// }
+//
+// // Customizing public API OpenAPI document
+// private OpenApiCustomiser customizePublicApiOpenApi() {
+// return (openApi) -> {
+// // Customize the OpenAPI document for the public API
+// openApi.addTagsItem(new Tag().name("Public API").description("Endpoints for public API"));
+// };
+// }
+//
+// // Customizing public API router operations
+// private RouterOperationCustomizer customizePublicApiRouterOperations() {
+// return (routerOperation, handlerMethod) -> {
+// // Customize the router operations for the public API
+// // Customize the router operation as needed
+// return routerOperation;
+// };
+// }
+//
+// // Filtering public API methods
+// private OpenApiMethodFilter publicApiMethodFilter() {
+// return (method) -> {
+// // Filter out DELETE methods from the public API
+// return HttpMethod.GET.matches(method.getName());
+// // return true;
+// };
+// }
+//
+// // Customizing private API operations
+// private OperationCustomizer customizePrivateApiOperations() {
+// return (operation, handlerMethod) -> {
+// // Customize the operations for the private API
+// operation.operationId("privateOperation");
+// operation.addTagsItem("Private API");
+// return operation;
+// };
+// }
+//
+// // Customizing private API OpenAPI document
+// private OpenApiCustomiser customizePrivateApiOpenApi() {
+// return (openApi) -> {
+// // Customize the OpenAPI document for the private API
+// openApi.addTagsItem(new Tag().name("Private API").description("Endpoints for private API"));
+// };
+// }
+//
+// // Customizing private API router operations
+// private RouterOperationCustomizer customizePrivateApiRouterOperations() {
+// return (routerOperation, handlerMethod) -> {
+// // Customize the router operations for the private API
+// // Customize the router operation as needed
+// return routerOperation;
+// };
+// }
+//
+// // Filtering private API methods
+// private OpenApiMethodFilter privateApiMethodFilter() {
+// return (method) -> {
+// // Filter out PATCH methods from the private API
+// return true;
+// };
+// }
+// }
+//
diff --git a/spring-boot-springdoc/src/main/java/com/jnssd/config/SwaggerProperties.java b/spring-boot-springdoc/src/main/java/com/jnssd/config/SwaggerProperties.java
new file mode 100644
index 0000000..760aee0
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/jnssd/config/SwaggerProperties.java
@@ -0,0 +1,57 @@
+package com.jnssd.config;
+
+import io.swagger.v3.oas.models.info.Contact;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * spring-boot-openapi
+ * Swagger配置
+ *
+ * @author zxj
+ * @since 2023-10-18 09:57:25
+ */
+@Data
+@ConfigurationProperties(prefix = "swagger")
+public class SwaggerProperties {
+
+ /**
+ * 标题
+ **/
+ private String title = "";
+
+ /**
+ * 描述
+ **/
+ private String description = "";
+
+ /**
+ * 版本
+ **/
+ private String version = "";
+
+ /**
+ * 许可证
+ **/
+ private String license = "";
+
+ /**
+ * 许可证URL
+ **/
+ private String licenseUrl = "";
+
+ /**
+ * 服务条款URL
+ **/
+ private String termsOfServiceUrl = "";
+
+ /**
+ * host信息
+ **/
+ private String host = "";
+
+ /**
+ * 联系人信息
+ */
+ private Contact contact = new Contact();
+}
diff --git a/spring-boot-springdoc/src/main/java/com/jnssd/controller/CommonController.java b/spring-boot-springdoc/src/main/java/com/jnssd/controller/CommonController.java
new file mode 100644
index 0000000..3e0bac7
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/jnssd/controller/CommonController.java
@@ -0,0 +1,17 @@
+package com.jnssd.controller;
+
+/**
+ * spring-boot-openapi
+ *
+ *
+ * @author zxj
+ * @since 2023-10-12 17:35:26
+ */
+// @Controller
+// public class CommonController {
+//
+// @GetMapping("/")
+// public String index() {
+// return "redirect:/swagger-ui/index.html";
+// }
+// }
diff --git a/spring-boot-springdoc/src/main/java/com/jnssd/controller/MenuController.java b/spring-boot-springdoc/src/main/java/com/jnssd/controller/MenuController.java
index 0bf7025..ee9e83e 100644
--- a/spring-boot-springdoc/src/main/java/com/jnssd/controller/MenuController.java
+++ b/spring-boot-springdoc/src/main/java/com/jnssd/controller/MenuController.java
@@ -2,10 +2,13 @@ package com.jnssd.controller;
import com.jnssd.model.Menu;
import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
+import java.util.Objects;
/**
* spring-boot-openapi
@@ -14,39 +17,66 @@ import java.util.List;
* @author zxj
* @since 2023-10-12 16:33:23
*/
-@RestController("menu")
+@RestController
+@RequestMapping("/menu")
public class MenuController {
+ final static String SUCCESS_TEXT = "操作成功!";
+ final static String FAIL_TEXT = "操作失败!";
+
List