Skip to content

Commit ba00314

Browse files
committed
Remove @nullable annotation for NativeWebRequest in Spring controller
1 parent e1513f7 commit ba00314

14 files changed

Lines changed: 355 additions & 23 deletions

File tree

bin/configs/spring-boot-4-jspecify.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ validateSpec: false
77
additionalProperties:
88
groupId: org.openapitools.openapi3
99
documentationProvider: springdoc
10-
interfaceOnly: true
10+
interfaceOnly: false
1111
artifactId: springboot
1212
snapshotVersion: "true"
1313
useSpringBoot4: true

modules/openapi-generator/src/main/resources/JavaSpring/apiController.mustache

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,10 @@ public class {{classname}}Controller implements {{classname}} {
8181
{{^isDelegate}}
8282
{{^reactive}}
8383

84-
@Nullable
8584
private final NativeWebRequest request;
8685

8786
@Autowired
88-
public {{classname}}Controller(@Nullable NativeWebRequest request) {
87+
public {{classname}}Controller(NativeWebRequest request) {
8988
this.request = request;
9089
}
9190

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6664,4 +6664,10 @@ public void testJspecify(String library, int springBootVersion, String fooApiFil
66646664
JavaFileAssert.assertThat(files.get("model/package-info.java"))
66656665
.fileContains("@org.jspecify.annotations.NullMarked");
66666666
}
6667+
6668+
@Test
6669+
void testNullableAnnotationOnController() throws IOException {
6670+
Map<String, File> files = generateFromContract("src/test/resources/3_0/petstore.yaml", SPRING_BOOT);
6671+
assertFileContains(files.get("UserApiController.java").toPath(), "import org.springframework.lang.Nullable;", "@Nullable");
6672+
}
66676673
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1+
.openapi-generator-ignore
12
README.md
23
pom.xml
4+
src/main/java/org/openapitools/OpenApiGeneratorApplication.java
5+
src/main/java/org/openapitools/RFC3339DateFormat.java
36
src/main/java/org/openapitools/api/ApiUtil.java
47
src/main/java/org/openapitools/api/FooApi.java
8+
src/main/java/org/openapitools/api/FooApiController.java
59
src/main/java/org/openapitools/api/UploadApi.java
10+
src/main/java/org/openapitools/api/UploadApiController.java
611
src/main/java/org/openapitools/api/package-info.java
12+
src/main/java/org/openapitools/configuration/HomeController.java
13+
src/main/java/org/openapitools/configuration/SpringDocConfiguration.java
714
src/main/java/org/openapitools/model/Foo.java
815
src/main/java/org/openapitools/model/package-info.java
16+
src/main/resources/application.properties
17+
src/main/resources/openapi.yaml
18+
src/test/java/org/openapitools/OpenApiGeneratorApplicationTests.java
Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
1+
# OpenAPI generated server
12

2-
# OpenAPI generated API stub
3+
Spring Boot Server
34

4-
Spring Framework stub
5+
## Overview
6+
This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
7+
By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a server stub.
8+
This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework.
59

610

7-
## Overview
8-
This code was generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
9-
By using the [OpenAPI-Spec](https://openapis.org), you can easily generate an API stub.
10-
This is an example of building API stub interfaces in Java using the Spring framework.
11+
The underlying library integrating OpenAPI to Spring Boot is [springdoc](https://springdoc.org).
12+
Springdoc will generate an OpenAPI v3 specification based on the generated Controller and Model classes.
13+
The specification is available to download using the following url:
14+
http://localhost:8080/v3/api-docs/
1115

12-
The stubs generated can be used in your existing Spring-MVC or Spring-Boot application to create controller endpoints
13-
by adding ```@Controller``` classes that implement the interface. Eg:
14-
```java
15-
@Controller
16-
public class PetController implements PetApi {
17-
// implement all PetApi methods
18-
}
19-
```
16+
Start your server as a simple java application
2017

21-
You can also use the interface to create [Spring-Cloud Feign clients](http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign-inheritance).Eg:
22-
```java
23-
@FeignClient(name="pet", url="http://petstore.swagger.io/v2")
24-
public interface PetClient extends PetApi {
18+
You can view the api documentation in swagger-ui by pointing to
19+
http://localhost:8080/swagger-ui.html
2520

26-
}
27-
```
21+
Change default port value in application.properties
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.openapitools;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.ComponentScan;
7+
import org.springframework.context.annotation.FilterType;
8+
import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator;
9+
10+
@SpringBootApplication(
11+
nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class
12+
)
13+
@ComponentScan(
14+
basePackages = {"org.openapitools", "org.openapitools.api" , "org.openapitools.configuration"},
15+
nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class
16+
)
17+
public class OpenApiGeneratorApplication {
18+
19+
public static void main(String[] args) {
20+
SpringApplication.run(OpenApiGeneratorApplication.class, args);
21+
}
22+
23+
24+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.openapitools;
2+
3+
import tools.jackson.databind.util.StdDateFormat;
4+
5+
import java.text.DateFormat;
6+
import java.text.FieldPosition;
7+
import java.text.ParsePosition;
8+
import java.util.Date;
9+
import java.util.GregorianCalendar;
10+
import java.util.TimeZone;
11+
12+
public class RFC3339DateFormat extends DateFormat {
13+
private static final long serialVersionUID = 1L;
14+
private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC");
15+
16+
private final StdDateFormat fmt = new StdDateFormat()
17+
.withTimeZone(TIMEZONE_Z)
18+
.withColonInTimeZone(true);
19+
20+
public RFC3339DateFormat() {
21+
this.calendar = new GregorianCalendar();
22+
}
23+
24+
@Override
25+
public Date parse(String source, ParsePosition pos) {
26+
return fmt.parse(source, pos);
27+
}
28+
29+
@Override
30+
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
31+
return fmt.format(date, toAppendTo, fieldPosition);
32+
}
33+
34+
@Override
35+
public Object clone() {
36+
return this;
37+
}
38+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.openapitools.api;
2+
3+
import org.springframework.format.annotation.DateTimeFormat;
4+
import org.openapitools.model.Foo;
5+
import org.jspecify.annotations.Nullable;
6+
import java.time.OffsetDateTime;
7+
8+
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.http.HttpStatus;
11+
import org.springframework.http.MediaType;
12+
import org.springframework.http.ResponseEntity;
13+
import org.springframework.stereotype.Controller;
14+
import org.springframework.web.bind.annotation.PathVariable;
15+
import org.springframework.web.bind.annotation.RequestBody;
16+
import org.springframework.web.bind.annotation.RequestHeader;
17+
import org.springframework.web.bind.annotation.RequestMapping;
18+
import org.springframework.web.bind.annotation.CookieValue;
19+
import org.springframework.web.bind.annotation.RequestParam;
20+
import org.springframework.web.bind.annotation.RequestPart;
21+
import org.springframework.web.multipart.MultipartFile;
22+
import org.springframework.web.context.request.NativeWebRequest;
23+
24+
import jakarta.validation.constraints.*;
25+
import jakarta.validation.Valid;
26+
27+
import java.util.List;
28+
import java.util.Map;
29+
import java.util.Optional;
30+
import jakarta.annotation.Generated;
31+
32+
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.22.0-SNAPSHOT")
33+
@Controller
34+
@RequestMapping("${openapi.jspecify.base-path:}")
35+
public class FooApiController implements FooApi {
36+
37+
private final NativeWebRequest request;
38+
39+
@Autowired
40+
public FooApiController(NativeWebRequest request) {
41+
this.request = request;
42+
}
43+
44+
@Override
45+
public Optional<NativeWebRequest> getRequest() {
46+
return Optional.ofNullable(request);
47+
}
48+
49+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.openapitools.api;
2+
3+
import org.jspecify.annotations.Nullable;
4+
5+
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.http.HttpStatus;
8+
import org.springframework.http.MediaType;
9+
import org.springframework.http.ResponseEntity;
10+
import org.springframework.stereotype.Controller;
11+
import org.springframework.web.bind.annotation.PathVariable;
12+
import org.springframework.web.bind.annotation.RequestBody;
13+
import org.springframework.web.bind.annotation.RequestHeader;
14+
import org.springframework.web.bind.annotation.RequestMapping;
15+
import org.springframework.web.bind.annotation.CookieValue;
16+
import org.springframework.web.bind.annotation.RequestParam;
17+
import org.springframework.web.bind.annotation.RequestPart;
18+
import org.springframework.web.multipart.MultipartFile;
19+
import org.springframework.web.context.request.NativeWebRequest;
20+
21+
import jakarta.validation.constraints.*;
22+
import jakarta.validation.Valid;
23+
24+
import java.util.List;
25+
import java.util.Map;
26+
import java.util.Optional;
27+
import jakarta.annotation.Generated;
28+
29+
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.22.0-SNAPSHOT")
30+
@Controller
31+
@RequestMapping("${openapi.jspecify.base-path:}")
32+
public class UploadApiController implements UploadApi {
33+
34+
private final NativeWebRequest request;
35+
36+
@Autowired
37+
public UploadApiController(NativeWebRequest request) {
38+
this.request = request;
39+
}
40+
41+
@Override
42+
public Optional<NativeWebRequest> getRequest() {
43+
return Optional.ofNullable(request);
44+
}
45+
46+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.openapitools.configuration;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.stereotype.Controller;
5+
import org.springframework.web.bind.annotation.RequestMapping;
6+
import org.springframework.web.bind.annotation.ResponseBody;
7+
import org.springframework.web.bind.annotation.GetMapping;
8+
9+
/**
10+
* Home redirection to OpenAPI api documentation
11+
*/
12+
@Controller
13+
public class HomeController {
14+
15+
@RequestMapping("/")
16+
public String index() {
17+
return "redirect:swagger-ui.html";
18+
}
19+
20+
}

0 commit comments

Comments
 (0)