Skip to content

Commit a1244bd

Browse files
authored
Merge pull request #1171 from swagger-api/spring-boot-v3
added support for spring-boot v3
2 parents 66dcca9 + 1924099 commit a1244bd

File tree

9 files changed

+288
-3
lines changed

9 files changed

+288
-3
lines changed

src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation
5959
public static final String USE_TAGS = "useTags";
6060
public static final String SPRING_MVC_LIBRARY = "spring-mvc";
6161
public static final String SPRING_CLOUD_LIBRARY = "spring-cloud";
62+
public static final String SPRING_BOOT_3_LIBRARY = "spring-boot3";
6263
public static final String IMPLICIT_HEADERS = "implicitHeaders";
6364
public static final String SWAGGER_DOCKET_CONFIG = "swaggerDocketConfig";
6465
public static final String TARGET_OPENFEIGN = "generateForOpenFeign";
@@ -127,6 +128,7 @@ public SpringCodegen() {
127128
cliOptions.add(CliOption.newBoolean(DATE_TIME_PATTERN, "use pattern for date time parameters").defaultValue("true"));
128129

129130
supportedLibraries.put(DEFAULT_LIBRARY, "Spring-boot Server application using the SpringFox integration.");
131+
supportedLibraries.put(SPRING_BOOT_3_LIBRARY, "Spring-boot v3 Server application.");
130132
supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration.");
131133
supportedLibraries.put(SPRING_CLOUD_LIBRARY, "Spring-Cloud-Feign client with Spring-Boot auto-configured settings.");
132134
setLibrary(DEFAULT_LIBRARY);
@@ -214,6 +216,10 @@ public void processOpts() {
214216
LOGGER.info("Set base package to invoker package (" + basePackage + ")");
215217
}
216218

219+
if (isSpringBoot3Library()) {
220+
setDateLibrary("java8");
221+
}
222+
217223
super.processOpts();
218224

219225
// clear model and api doc template as this codegen
@@ -324,7 +330,16 @@ public void processOpts() {
324330
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
325331

326332
if (!this.interfaceOnly) {
327-
333+
if (isSpringBoot3Library()) {
334+
useOas2 = false;
335+
additionalProperties.remove("threetenbp");
336+
additionalProperties.put(JAKARTA, jakarta = true);
337+
apiTestTemplateFiles.clear();
338+
supportingFiles.add(new SupportingFile("homeController.mustache", (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "HomeController.java"));
339+
supportingFiles.add(new SupportingFile("openAPISpringBoot.mustache", (sourceFolder + File.separator + basePackage).replace(".", java.io.File.separator), "OpenAPISpringBoot.java"));
340+
supportingFiles.add(new SupportingFile("swaggerUiConfiguration.mustache", (sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "SwaggerUiConfiguration.java"));
341+
supportingFiles.add(new SupportingFile("application.mustache", ("src.main.resources").replace(".", java.io.File.separator), "application.properties"));
342+
}
328343
if (isDefaultLibrary()) {
329344
apiTestTemplateFiles.clear();
330345
supportingFiles.add(new SupportingFile("homeController.mustache",
@@ -385,14 +400,16 @@ public void processOpts() {
385400
(sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "NotFoundException.java"));
386401
supportingFiles.add(new SupportingFile("apiOriginFilter.mustache",
387402
(sourceFolder + File.separator + apiPackage).replace(".", java.io.File.separator), "ApiOriginFilter.java"));
388-
supportingFiles.add(new SupportingFile("swaggerDocumentationConfig.mustache",
403+
if (!isSpringBoot3Library()) {
404+
supportingFiles.add(new SupportingFile("swaggerDocumentationConfig.mustache",
389405
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "SwaggerDocumentationConfig.java"));
406+
}
390407
supportingFiles.add(new SupportingFile("LocalDateConverter.mustache",
391408
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "LocalDateConverter.java"));
392409
supportingFiles.add(new SupportingFile("LocalDateTimeConverter.mustache",
393410
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "LocalDateTimeConverter.java"));
394411
}
395-
} else if ( this.swaggerDocketConfig && !isSpringCloudLibrary()) {
412+
} else if ( this.swaggerDocketConfig && !isSpringCloudLibrary() && !isSpringBoot3Library()) {
396413
supportingFiles.add(new SupportingFile("swaggerDocumentationConfig.mustache",
397414
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "SwaggerDocumentationConfig.java"));
398415
}
@@ -757,6 +774,9 @@ private boolean isSpringMvcLibrary() {
757774
private boolean isDefaultLibrary() {
758775
return library.equals(DEFAULT_LIBRARY);
759776
}
777+
private boolean isSpringBoot3Library() {
778+
return library.equals(SPRING_BOOT_3_LIBRARY);
779+
}
760780

761781
@Override
762782
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package {{configPackage}};
2+
3+
import org.springframework.core.convert.converter.Converter;
4+
import java.time.LocalDate;
5+
import java.time.format.DateTimeFormatter;
6+
7+
public class LocalDateConverter implements Converter<String, LocalDate> {
8+
private final DateTimeFormatter formatter;
9+
10+
public LocalDateConverter(String dateFormat) {
11+
this.formatter = DateTimeFormatter.ofPattern(dateFormat);
12+
}
13+
14+
@Override
15+
public LocalDate convert(String source) {
16+
if(source == null || source.isEmpty()) {
17+
return null;
18+
}
19+
return LocalDate.parse(source, this.formatter);
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package {{configPackage}};
2+
3+
import org.springframework.core.convert.converter.Converter;
4+
import java.time.LocalDateTime;
5+
import java.time.format.DateTimeFormatter;
6+
7+
public class LocalDateTimeConverter implements Converter<String, LocalDateTime> {
8+
private final DateTimeFormatter formatter;
9+
10+
public LocalDateTimeConverter(String dateFormat) {
11+
this.formatter = DateTimeFormatter.ofPattern(dateFormat);
12+
}
13+
14+
@Override
15+
public LocalDateTime convert(String source) {
16+
if(source == null || source.isEmpty()) {
17+
return null;
18+
}
19+
return LocalDateTime.parse(source, this.formatter);
20+
}
21+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{{^interfaceOnly}}# Swagger generated server
2+
3+
Spring Boot Server
4+
5+
6+
## Overview
7+
This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project.
8+
By using the [OpenAPI-Spec](https://github.com/swagger-api/swagger-core), you can easily generate a server stub.
9+
This is an example of building a swagger-enabled server in Java using the SpringBoot framework.
10+
11+
The underlying library integrating swagger to SpringBoot is [springdoc-openapi](https://github.com/springdoc/springdoc-openapi)
12+
13+
Start your server as an simple java application
14+
15+
You can view the api documentation in swagger-ui by pointing to
16+
http://localhost:8080/
17+
18+
Change default port value in application.properties{{/interfaceOnly}}{{#interfaceOnly}}
19+
# Swagger generated API stub
20+
21+
Spring Framework stub
22+
23+
24+
## Overview
25+
This code was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project.
26+
By using the [OpenAPI-Spec](https://github.com/swagger-api/swagger-core), you can easily generate an API stub.
27+
This is an example of building API stub interfaces in Java using the Spring framework.
28+
29+
The stubs generated can be used in your existing Spring-MVC or Spring-Boot application to create controller endpoints
30+
by adding ```@Controller``` classes that implement the interface. Eg:
31+
```java
32+
@Controller
33+
public class PetController implements PetApi {
34+
// implement all PetApi methods
35+
}
36+
```
37+
{{/interfaceOnly}}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
springfox.documentation.open-api.v3.path=/api-docs
2+
server.servlet.contextPath={{^contextPath}}/{{/contextPath}}{{#contextPath}}{{contextPath}}{{/contextPath}}
3+
server.port={{serverPort}}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package {{configPackage}};
2+
3+
import org.springframework.stereotype.Controller;
4+
import org.springframework.web.bind.annotation.RequestMapping;
5+
6+
/**
7+
* Home redirection to swagger api documentation
8+
*/
9+
@Controller
10+
public class HomeController {
11+
@RequestMapping(value = "/")
12+
public String index() {
13+
System.out.println("/swagger-ui/index.html");
14+
return "redirect:/swagger-ui/";
15+
}
16+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package {{basePackage}};
2+
3+
import {{configPackage}}.LocalDateConverter;
4+
import {{configPackage}}.LocalDateTimeConverter;
5+
6+
import org.springframework.boot.CommandLineRunner;
7+
import org.springframework.boot.ExitCodeGenerator;
8+
import org.springframework.boot.SpringApplication;
9+
import org.springframework.boot.autoconfigure.SpringBootApplication;
10+
import org.springframework.context.annotation.ComponentScan;
11+
import org.springframework.context.annotation.Configuration;
12+
import org.springframework.format.FormatterRegistry;
13+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
14+
15+
@SpringBootApplication
16+
@ComponentScan(basePackages = { "{{basePackage}}", "{{apiPackage}}" , "{{configPackage}}"})
17+
public class OpenAPISpringBoot implements CommandLineRunner {
18+
19+
@Override
20+
public void run(String... arg0) throws Exception {
21+
if (arg0.length > 0 && arg0[0].equals("exitcode")) {
22+
throw new ExitException();
23+
}
24+
}
25+
26+
public static void main(String[] args) throws Exception {
27+
new SpringApplication(OpenAPISpringBoot.class).run(args);
28+
}
29+
30+
@Configuration
31+
static class CustomDateConfig extends WebMvcConfigurationSupport {
32+
@Override
33+
public void addFormatters(FormatterRegistry registry) {
34+
registry.addConverter(new LocalDateConverter("{{#datePattern}}{{datePattern}}{{/datePattern}}{{^datePattern}}yyyy-MM-dd{{/datePattern}}"));
35+
registry.addConverter(new LocalDateTimeConverter("{{#dateTimePattern}}{{dateTimePattern}}{{/dateTimePattern}}{{^dateTimePattern}}yyyy-MM-dd'T'HH:mm:ss.SSS{{/dateTimePattern}}"));
36+
}
37+
}
38+
39+
class ExitException extends RuntimeException implements ExitCodeGenerator {
40+
private static final long serialVersionUID = 1L;
41+
42+
@Override
43+
public int getExitCode() {
44+
return 10;
45+
}
46+
47+
}
48+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<groupId>{{groupId}}</groupId>
4+
<artifactId>{{artifactId}}</artifactId>
5+
<packaging>jar</packaging>
6+
<name>{{artifactId}}</name>
7+
<version>{{artifactVersion}}</version>
8+
<properties>
9+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
10+
<maven.compiler.release>17</maven.compiler.release>
11+
<springboot-version>3.1.1</springboot-version>
12+
<swagger-annotations-version>2.2.14</swagger-annotations-version>
13+
</properties>
14+
<parent>
15+
<groupId>org.springframework.boot</groupId>
16+
<artifactId>spring-boot-starter-parent</artifactId>
17+
<version>3.1.1</version>
18+
</parent>
19+
<build>
20+
<sourceDirectory>src/main/java</sourceDirectory>
21+
<plugins>
22+
<plugin>
23+
<groupId>org.springframework.boot</groupId>
24+
<artifactId>spring-boot-maven-plugin</artifactId>
25+
<executions>
26+
<execution>
27+
<goals>
28+
<goal>repackage</goal>
29+
</goals>
30+
</execution>
31+
</executions>
32+
</plugin>
33+
</plugins>
34+
</build>
35+
<dependencies>
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-starter-web</artifactId>
39+
<version>${springboot-version}</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.springframework.boot</groupId>
43+
<artifactId>spring-boot-starter-tomcat</artifactId>
44+
<version>${springboot-version}</version>
45+
</dependency>
46+
{{#withXml}}
47+
<dependency>
48+
<groupId>com.fasterxml.jackson.dataformat</groupId>
49+
<artifactId>jackson-dataformat-xml</artifactId>
50+
</dependency>
51+
{{/withXml}}
52+
{{#useBeanValidation}}
53+
<!-- Bean Validation API support -->
54+
<dependency>
55+
<groupId>jakarta.validation</groupId>
56+
<artifactId>jakarta.validation-api</artifactId>
57+
<version>3.0.2</version>
58+
</dependency>
59+
<dependency>
60+
<groupId>jakarta.xml.bind</groupId>
61+
<artifactId>jakarta.xml.bind-api</artifactId>
62+
<version>4.0.0</version>
63+
</dependency>
64+
<dependency>
65+
<groupId>com.sun.xml.bind</groupId>
66+
<artifactId>jaxb-impl</artifactId>
67+
<version>4.0.3</version>
68+
</dependency>
69+
{{/useBeanValidation}}
70+
{{#notNullJacksonAnnotation}}
71+
<dependency>
72+
<groupId>com.fasterxml.jackson.core</groupId>
73+
<artifactId>jackson-annotations</artifactId>
74+
<version>2.10.1</version>
75+
</dependency>
76+
{{/notNullJacksonAnnotation}}
77+
78+
<dependency>
79+
<groupId>io.swagger.core.v3</groupId>
80+
<artifactId>swagger-annotations</artifactId>
81+
<version>${swagger-annotations-version}</version>
82+
</dependency>
83+
<dependency>
84+
<groupId>org.springframework.plugin</groupId>
85+
<artifactId>spring-plugin-core</artifactId>
86+
<version>3.0.0</version>
87+
</dependency>
88+
89+
<dependency>
90+
<groupId>org.springframework.boot</groupId>
91+
<artifactId>spring-boot-starter-test</artifactId>
92+
<version>${springboot-version}</version>
93+
<scope>test</scope>
94+
</dependency>
95+
</dependencies>
96+
</project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package {{configPackage}};
2+
3+
import org.springframework.context.annotation.Configuration;
4+
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
5+
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
6+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7+
8+
{{>generatedAnnotation}}
9+
@Configuration
10+
public class SwaggerUiConfiguration implements WebMvcConfigurer {
11+
@Override
12+
public void addResourceHandlers(ResourceHandlerRegistry registry) {
13+
registry.
14+
addResourceHandler("/swagger-ui/**")
15+
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
16+
.resourceChain(false);
17+
}
18+
19+
@Override
20+
public void addViewControllers(ViewControllerRegistry registry) {
21+
registry.addViewController("/swagger-ui/").setViewName("forward:/swagger-ui/index.html");
22+
}
23+
}

0 commit comments

Comments
 (0)