diff --git a/bin/configs/spring-mvc-headers-validation-with-optional.yaml b/bin/configs/spring-mvc-headers-validation-with-optional.yaml
new file mode 100644
index 000000000000..3474a9a8a8ee
--- /dev/null
+++ b/bin/configs/spring-mvc-headers-validation-with-optional.yaml
@@ -0,0 +1,10 @@
+generatorName: spring
+outputDir: samples/server/petstore/spring-mvc-headers-validation-with-optional
+inputSpec: modules/openapi-generator/src/test/resources/3_0/headers-validation.yaml
+templateDir: modules/openapi-generator/src/main/resources/JavaSpring
+additionalProperties:
+ java8: true
+ performBeanValidation: "true"
+ useOptional: true
+ hideGenerationTimestamp: "true"
+ artifactId: spring-mvc-headers-validation
diff --git a/bin/configs/spring-mvc-headers-validation-without-optional.yaml b/bin/configs/spring-mvc-headers-validation-without-optional.yaml
new file mode 100644
index 000000000000..d6257681d427
--- /dev/null
+++ b/bin/configs/spring-mvc-headers-validation-without-optional.yaml
@@ -0,0 +1,10 @@
+generatorName: spring
+outputDir: samples/server/petstore/spring-mvc-headers-validation-without-optional
+inputSpec: modules/openapi-generator/src/test/resources/3_0/headers-validation.yaml
+templateDir: modules/openapi-generator/src/main/resources/JavaSpring
+additionalProperties:
+ java8: true
+ performBeanValidation: "true"
+ useOptional: false
+ hideGenerationTimestamp: "true"
+ artifactId: spring-mvc-headers-validation
diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/headerParams.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/headerParams.mustache
index bfee41347652..7d5fc272b694 100644
--- a/modules/openapi-generator/src/main/resources/JavaSpring/headerParams.mustache
+++ b/modules/openapi-generator/src/main/resources/JavaSpring/headerParams.mustache
@@ -1 +1 @@
-{{#isHeaderParam}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}{{/isContainer}}) @RequestHeader(value = "{{baseName}}", required = {{#required}}true{{/required}}{{^required}}false{{/required}}) {{>optionalDataType}} {{paramName}}{{/isHeaderParam}}
\ No newline at end of file
+{{#isHeaderParam}}{{#useBeanValidation}}{{#useOptional}}{{#required}}{{>beanValidationCore}}{{/required}}{{/useOptional}}{{^useOptional}}{{>beanValidationCore}}{{/useOptional}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}{{/isContainer}}) @RequestHeader(value = "{{baseName}}", required = {{#required}}true{{/required}}{{^required}}false{{/required}}) {{>optionalDataType}} {{paramName}}{{/isHeaderParam}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/test/resources/3_0/headers-validation.yaml b/modules/openapi-generator/src/test/resources/3_0/headers-validation.yaml
new file mode 100644
index 000000000000..b1d706f4098a
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_0/headers-validation.yaml
@@ -0,0 +1,70 @@
+openapi: 3.0.1
+info:
+ title: Test for Issue 7125
+ description: desc
+ version: 1.0.0
+tags:
+ - name: verify-headers-validation
+ description: verify headers validation
+paths:
+ /test-headers-validation:
+ get:
+ tags:
+ - verify-headers-validation
+ summary: test headers validation
+ description: desc
+ operationId: headersValidationTest
+ parameters:
+ - name: requiredStringWithMinLength
+ in: header
+ required: true
+ schema:
+ type: string
+ minLength: 32
+ - name: requiredStringWithMaxLength
+ in: header
+ required: true
+ schema:
+ type: string
+ maxLength: 32
+ - name: requiredStringWithLength
+ in: header
+ required: true
+ schema:
+ type: string
+ minLength: 32
+ maxLength: 32
+ - name: requiredStringWithPattern
+ in: header
+ required: true
+ schema:
+ type: string
+ pattern: ^([0-9a-fA-F]{32})$
+ - name: optionalStringWithMinLength
+ in: header
+ required: false
+ schema:
+ type: string
+ minLength: 32
+ - name: optionalStringWithMaxLength
+ in: header
+ required: false
+ schema:
+ type: string
+ maxLength: 32
+ - name: optionalStringWithLength
+ in: header
+ required: false
+ schema:
+ type: string
+ minLength: 32
+ maxLength: 32
+ - name: optionalStringWithPattern
+ in: header
+ required: false
+ schema:
+ type: string
+ pattern: ^([0-9a-fA-F]{32})$
+ responses:
+ 200:
+ description: default response
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator-ignore b/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator-ignore
new file mode 100644
index 000000000000..7484ee590a38
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator/FILES b/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator/FILES
new file mode 100644
index 000000000000..35aa0d2ed4fa
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator/FILES
@@ -0,0 +1,10 @@
+README.md
+pom.xml
+src/main/java/org/openapitools/OpenAPI2SpringBoot.java
+src/main/java/org/openapitools/RFC3339DateFormat.java
+src/main/java/org/openapitools/api/ApiUtil.java
+src/main/java/org/openapitools/api/TestHeadersValidationApi.java
+src/main/java/org/openapitools/api/TestHeadersValidationApiController.java
+src/main/java/org/openapitools/configuration/HomeController.java
+src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java
+src/main/resources/application.properties
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator/VERSION b/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator/VERSION
new file mode 100644
index 000000000000..4b448de535c7
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/.openapi-generator/VERSION
@@ -0,0 +1 @@
+5.3.0-SNAPSHOT
\ No newline at end of file
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/README.md b/samples/server/petstore/spring-mvc-headers-validation-with-optional/README.md
new file mode 100644
index 000000000000..1ff91b81b2ec
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/README.md
@@ -0,0 +1,18 @@
+# OpenAPI generated server
+
+Spring Boot Server
+
+
+## Overview
+This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
+By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a server stub.
+This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework.
+
+The underlying library integrating OpenAPI to SpringBoot is [springfox](https://github.com/springfox/springfox)
+
+Start your server as a simple java application
+
+You can view the api documentation in swagger-ui by pointing to
+http://localhost:8080/
+
+Change default port value in application.properties
\ No newline at end of file
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/pom.xml b/samples/server/petstore/spring-mvc-headers-validation-with-optional/pom.xml
new file mode 100644
index 000000000000..d5dfad90558f
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/pom.xml
@@ -0,0 +1,78 @@
+
+ 4.0.0
+ org.openapitools
+ spring-mvc-headers-validation
+ jar
+ spring-mvc-headers-validation
+ 1.0.0
+
+ 1.8
+ ${java.version}
+ ${java.version}
+ 2.9.2
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.3.RELEASE
+
+
+ src/main/java
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox-version}
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${springfox-version}
+
+
+ jakarta.xml.bind
+ jakarta.xml.bind-api
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ org.openapitools
+ jackson-databind-nullable
+ 0.2.1
+
+
+
+ jakarta.validation
+ jakarta.validation-api
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/OpenAPI2SpringBoot.java b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/OpenAPI2SpringBoot.java
new file mode 100644
index 000000000000..7cad28eed8ac
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/OpenAPI2SpringBoot.java
@@ -0,0 +1,57 @@
+package org.openapitools;
+
+import com.fasterxml.jackson.databind.Module;
+import org.openapitools.jackson.nullable.JsonNullableModule;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.ExitCodeGenerator;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@SpringBootApplication
+@ComponentScan(basePackages = {"org.openapitools", "org.openapitools.api" , "org.openapitools.configuration"})
+public class OpenAPI2SpringBoot implements CommandLineRunner {
+
+ @Override
+ public void run(String... arg0) throws Exception {
+ if (arg0.length > 0 && arg0[0].equals("exitcode")) {
+ throw new ExitException();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new SpringApplication(OpenAPI2SpringBoot.class).run(args);
+ }
+
+ static class ExitException extends RuntimeException implements ExitCodeGenerator {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public int getExitCode() {
+ return 10;
+ }
+
+ }
+
+ @Bean
+ public WebMvcConfigurer webConfigurer() {
+ return new WebMvcConfigurer() {
+ /*@Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOrigins("*")
+ .allowedMethods("*")
+ .allowedHeaders("Content-Type");
+ }*/
+ };
+ }
+
+ @Bean
+ public Module jsonNullableModule() {
+ return new JsonNullableModule();
+ }
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/RFC3339DateFormat.java b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/RFC3339DateFormat.java
new file mode 100644
index 000000000000..bcd3936d8b34
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/RFC3339DateFormat.java
@@ -0,0 +1,38 @@
+package org.openapitools;
+
+import com.fasterxml.jackson.databind.util.StdDateFormat;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+public class RFC3339DateFormat extends DateFormat {
+ private static final long serialVersionUID = 1L;
+ private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC");
+
+ private final StdDateFormat fmt = new StdDateFormat()
+ .withTimeZone(TIMEZONE_Z)
+ .withColonInTimeZone(true);
+
+ public RFC3339DateFormat() {
+ this.calendar = new GregorianCalendar();
+ }
+
+ @Override
+ public Date parse(String source, ParsePosition pos) {
+ return fmt.parse(source, pos);
+ }
+
+ @Override
+ public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
+ return fmt.format(date, toAppendTo, fieldPosition);
+ }
+
+ @Override
+ public Object clone() {
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/ApiUtil.java b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/ApiUtil.java
new file mode 100644
index 000000000000..1245b1dd0ccf
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/ApiUtil.java
@@ -0,0 +1,19 @@
+package org.openapitools.api;
+
+import org.springframework.web.context.request.NativeWebRequest;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class ApiUtil {
+ public static void setExampleResponse(NativeWebRequest req, String contentType, String example) {
+ try {
+ HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class);
+ res.setCharacterEncoding("UTF-8");
+ res.addHeader("Content-Type", contentType);
+ res.getWriter().print(example);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/TestHeadersValidationApi.java b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/TestHeadersValidationApi.java
new file mode 100644
index 000000000000..2b4a80a34c10
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/TestHeadersValidationApi.java
@@ -0,0 +1,57 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (5.3.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import io.swagger.annotations.*;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+@Validated
+@Api(value = "test-headers-validation", description = "the test-headers-validation API")
+public interface TestHeadersValidationApi {
+
+ default Optional getRequest() {
+ return Optional.empty();
+ }
+
+ /**
+ * GET /test-headers-validation : test headers validation
+ * desc
+ *
+ * @param requiredStringWithMinLength (required)
+ * @param requiredStringWithMaxLength (required)
+ * @param requiredStringWithLength (required)
+ * @param requiredStringWithPattern (required)
+ * @param optionalStringWithMinLength (optional)
+ * @param optionalStringWithMaxLength (optional)
+ * @param optionalStringWithLength (optional)
+ * @param optionalStringWithPattern (optional)
+ * @return default response (status code 200)
+ */
+ @ApiOperation(value = "test headers validation", nickname = "headersValidationTest", notes = "desc", tags={ "verify-headers-validation", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "default response") })
+ @RequestMapping(
+ method = RequestMethod.GET,
+ value = "/test-headers-validation"
+ )
+ default ResponseEntity headersValidationTest(@Size(min = 32) @ApiParam(value = "", required = true) @RequestHeader(value = "requiredStringWithMinLength", required = true) String requiredStringWithMinLength,@Size(max = 32) @ApiParam(value = "", required = true) @RequestHeader(value = "requiredStringWithMaxLength", required = true) String requiredStringWithMaxLength,@Size(min = 32, max = 32) @ApiParam(value = "", required = true) @RequestHeader(value = "requiredStringWithLength", required = true) String requiredStringWithLength,@Pattern(regexp = "^([0-9a-fA-F]{32})$") @ApiParam(value = "", required = true) @RequestHeader(value = "requiredStringWithPattern", required = true) String requiredStringWithPattern,@ApiParam(value = "") @RequestHeader(value = "optionalStringWithMinLength", required = false) Optional<@Size(min = 32) String> optionalStringWithMinLength,@ApiParam(value = "") @RequestHeader(value = "optionalStringWithMaxLength", required = false) Optional<@Size(max = 32) String> optionalStringWithMaxLength,@ApiParam(value = "") @RequestHeader(value = "optionalStringWithLength", required = false) Optional<@Size(min = 32, max = 32) String> optionalStringWithLength,@ApiParam(value = "") @RequestHeader(value = "optionalStringWithPattern", required = false) Optional<@Pattern(regexp = "^([0-9a-fA-F]{32})$") String> optionalStringWithPattern) {
+ return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+ }
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/TestHeadersValidationApiController.java b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/TestHeadersValidationApiController.java
new file mode 100644
index 000000000000..ff7e66a13728
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/api/TestHeadersValidationApiController.java
@@ -0,0 +1,24 @@
+package org.openapitools.api;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.request.NativeWebRequest;
+import java.util.Optional;
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+@Controller
+@RequestMapping("${openapi.testForIssue7125.base-path:}")
+public class TestHeadersValidationApiController implements TestHeadersValidationApi {
+
+ private final NativeWebRequest request;
+
+ @org.springframework.beans.factory.annotation.Autowired
+ public TestHeadersValidationApiController(NativeWebRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public Optional getRequest() {
+ return Optional.ofNullable(request);
+ }
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/configuration/HomeController.java b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/configuration/HomeController.java
new file mode 100644
index 000000000000..25727830541b
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/configuration/HomeController.java
@@ -0,0 +1,19 @@
+package org.openapitools.configuration;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+
+/**
+ * Home redirection to OpenAPI api documentation
+ */
+@Controller
+public class HomeController {
+
+ @RequestMapping("/")
+ public String index() {
+ return "redirect:swagger-ui.html";
+ }
+
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java
new file mode 100644
index 000000000000..670dbb4cde67
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java
@@ -0,0 +1,72 @@
+package org.openapitools.configuration;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import org.springframework.web.util.UriComponentsBuilder;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.paths.Paths;
+import springfox.documentation.spring.web.paths.RelativePathProvider;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.Optional;
+import javax.servlet.ServletContext;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+@Configuration
+@EnableSwagger2
+public class OpenAPIDocumentationConfig {
+
+ ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("Test for Issue 7125")
+ .description("desc")
+ .license("")
+ .licenseUrl("http://unlicense.org")
+ .termsOfServiceUrl("")
+ .version("1.0.0")
+ .contact(new Contact("","", ""))
+ .build();
+ }
+
+ @Bean
+ public Docket customImplementation(ServletContext servletContext, @Value("${openapi.testForIssue7125.base-path:}") String basePath) {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("org.openapitools.api"))
+ .build()
+ .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath))
+ .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class)
+ .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class)
+ .genericModelSubstitutes(Optional.class)
+ .apiInfo(apiInfo());
+ }
+
+ class BasePathAwareRelativePathProvider extends RelativePathProvider {
+ private String basePath;
+
+ public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) {
+ super(servletContext);
+ this.basePath = basePath;
+ }
+
+ @Override
+ protected String applicationPath() {
+ return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString());
+ }
+
+ @Override
+ public String getOperationPath(String operationPath) {
+ UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/");
+ return Paths.removeAdjacentForwardSlashes(
+ uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString());
+ }
+ }
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/resources/application.properties b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/resources/application.properties
new file mode 100644
index 000000000000..b80025e1aa33
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-with-optional/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+springfox.documentation.swagger.v2.path=/api-docs
+server.port=8080
+spring.jackson.date-format=org.openapitools.RFC3339DateFormat
+spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator-ignore b/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator-ignore
new file mode 100644
index 000000000000..7484ee590a38
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator/FILES b/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator/FILES
new file mode 100644
index 000000000000..35aa0d2ed4fa
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator/FILES
@@ -0,0 +1,10 @@
+README.md
+pom.xml
+src/main/java/org/openapitools/OpenAPI2SpringBoot.java
+src/main/java/org/openapitools/RFC3339DateFormat.java
+src/main/java/org/openapitools/api/ApiUtil.java
+src/main/java/org/openapitools/api/TestHeadersValidationApi.java
+src/main/java/org/openapitools/api/TestHeadersValidationApiController.java
+src/main/java/org/openapitools/configuration/HomeController.java
+src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java
+src/main/resources/application.properties
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator/VERSION b/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator/VERSION
new file mode 100644
index 000000000000..4b448de535c7
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/.openapi-generator/VERSION
@@ -0,0 +1 @@
+5.3.0-SNAPSHOT
\ No newline at end of file
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/README.md b/samples/server/petstore/spring-mvc-headers-validation-without-optional/README.md
new file mode 100644
index 000000000000..1ff91b81b2ec
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/README.md
@@ -0,0 +1,18 @@
+# OpenAPI generated server
+
+Spring Boot Server
+
+
+## Overview
+This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
+By using the [OpenAPI-Spec](https://openapis.org), you can easily generate a server stub.
+This is an example of building a OpenAPI-enabled server in Java using the SpringBoot framework.
+
+The underlying library integrating OpenAPI to SpringBoot is [springfox](https://github.com/springfox/springfox)
+
+Start your server as a simple java application
+
+You can view the api documentation in swagger-ui by pointing to
+http://localhost:8080/
+
+Change default port value in application.properties
\ No newline at end of file
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/pom.xml b/samples/server/petstore/spring-mvc-headers-validation-without-optional/pom.xml
new file mode 100644
index 000000000000..d5dfad90558f
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/pom.xml
@@ -0,0 +1,78 @@
+
+ 4.0.0
+ org.openapitools
+ spring-mvc-headers-validation
+ jar
+ spring-mvc-headers-validation
+ 1.0.0
+
+ 1.8
+ ${java.version}
+ ${java.version}
+ 2.9.2
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.3.RELEASE
+
+
+ src/main/java
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox-version}
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${springfox-version}
+
+
+ jakarta.xml.bind
+ jakarta.xml.bind-api
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ org.openapitools
+ jackson-databind-nullable
+ 0.2.1
+
+
+
+ jakarta.validation
+ jakarta.validation-api
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/OpenAPI2SpringBoot.java b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/OpenAPI2SpringBoot.java
new file mode 100644
index 000000000000..7cad28eed8ac
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/OpenAPI2SpringBoot.java
@@ -0,0 +1,57 @@
+package org.openapitools;
+
+import com.fasterxml.jackson.databind.Module;
+import org.openapitools.jackson.nullable.JsonNullableModule;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.ExitCodeGenerator;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@SpringBootApplication
+@ComponentScan(basePackages = {"org.openapitools", "org.openapitools.api" , "org.openapitools.configuration"})
+public class OpenAPI2SpringBoot implements CommandLineRunner {
+
+ @Override
+ public void run(String... arg0) throws Exception {
+ if (arg0.length > 0 && arg0[0].equals("exitcode")) {
+ throw new ExitException();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new SpringApplication(OpenAPI2SpringBoot.class).run(args);
+ }
+
+ static class ExitException extends RuntimeException implements ExitCodeGenerator {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public int getExitCode() {
+ return 10;
+ }
+
+ }
+
+ @Bean
+ public WebMvcConfigurer webConfigurer() {
+ return new WebMvcConfigurer() {
+ /*@Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOrigins("*")
+ .allowedMethods("*")
+ .allowedHeaders("Content-Type");
+ }*/
+ };
+ }
+
+ @Bean
+ public Module jsonNullableModule() {
+ return new JsonNullableModule();
+ }
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/RFC3339DateFormat.java b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/RFC3339DateFormat.java
new file mode 100644
index 000000000000..bcd3936d8b34
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/RFC3339DateFormat.java
@@ -0,0 +1,38 @@
+package org.openapitools;
+
+import com.fasterxml.jackson.databind.util.StdDateFormat;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+public class RFC3339DateFormat extends DateFormat {
+ private static final long serialVersionUID = 1L;
+ private static final TimeZone TIMEZONE_Z = TimeZone.getTimeZone("UTC");
+
+ private final StdDateFormat fmt = new StdDateFormat()
+ .withTimeZone(TIMEZONE_Z)
+ .withColonInTimeZone(true);
+
+ public RFC3339DateFormat() {
+ this.calendar = new GregorianCalendar();
+ }
+
+ @Override
+ public Date parse(String source, ParsePosition pos) {
+ return fmt.parse(source, pos);
+ }
+
+ @Override
+ public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
+ return fmt.format(date, toAppendTo, fieldPosition);
+ }
+
+ @Override
+ public Object clone() {
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/ApiUtil.java b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/ApiUtil.java
new file mode 100644
index 000000000000..1245b1dd0ccf
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/ApiUtil.java
@@ -0,0 +1,19 @@
+package org.openapitools.api;
+
+import org.springframework.web.context.request.NativeWebRequest;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class ApiUtil {
+ public static void setExampleResponse(NativeWebRequest req, String contentType, String example) {
+ try {
+ HttpServletResponse res = req.getNativeResponse(HttpServletResponse.class);
+ res.setCharacterEncoding("UTF-8");
+ res.addHeader("Content-Type", contentType);
+ res.getWriter().print(example);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/TestHeadersValidationApi.java b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/TestHeadersValidationApi.java
new file mode 100644
index 000000000000..f736abb37113
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/TestHeadersValidationApi.java
@@ -0,0 +1,57 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (5.3.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import io.swagger.annotations.*;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+@Validated
+@Api(value = "test-headers-validation", description = "the test-headers-validation API")
+public interface TestHeadersValidationApi {
+
+ default Optional getRequest() {
+ return Optional.empty();
+ }
+
+ /**
+ * GET /test-headers-validation : test headers validation
+ * desc
+ *
+ * @param requiredStringWithMinLength (required)
+ * @param requiredStringWithMaxLength (required)
+ * @param requiredStringWithLength (required)
+ * @param requiredStringWithPattern (required)
+ * @param optionalStringWithMinLength (optional)
+ * @param optionalStringWithMaxLength (optional)
+ * @param optionalStringWithLength (optional)
+ * @param optionalStringWithPattern (optional)
+ * @return default response (status code 200)
+ */
+ @ApiOperation(value = "test headers validation", nickname = "headersValidationTest", notes = "desc", tags={ "verify-headers-validation", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "default response") })
+ @RequestMapping(
+ method = RequestMethod.GET,
+ value = "/test-headers-validation"
+ )
+ default ResponseEntity headersValidationTest(@Size(min = 32) @ApiParam(value = "", required = true) @RequestHeader(value = "requiredStringWithMinLength", required = true) String requiredStringWithMinLength,@Size(max = 32) @ApiParam(value = "", required = true) @RequestHeader(value = "requiredStringWithMaxLength", required = true) String requiredStringWithMaxLength,@Size(min = 32, max = 32) @ApiParam(value = "", required = true) @RequestHeader(value = "requiredStringWithLength", required = true) String requiredStringWithLength,@Pattern(regexp = "^([0-9a-fA-F]{32})$") @ApiParam(value = "", required = true) @RequestHeader(value = "requiredStringWithPattern", required = true) String requiredStringWithPattern,@Size(min = 32) @ApiParam(value = "") @RequestHeader(value = "optionalStringWithMinLength", required = false) String optionalStringWithMinLength,@Size(max = 32) @ApiParam(value = "") @RequestHeader(value = "optionalStringWithMaxLength", required = false) String optionalStringWithMaxLength,@Size(min = 32, max = 32) @ApiParam(value = "") @RequestHeader(value = "optionalStringWithLength", required = false) String optionalStringWithLength,@Pattern(regexp = "^([0-9a-fA-F]{32})$") @ApiParam(value = "") @RequestHeader(value = "optionalStringWithPattern", required = false) String optionalStringWithPattern) {
+ return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
+
+ }
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/TestHeadersValidationApiController.java b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/TestHeadersValidationApiController.java
new file mode 100644
index 000000000000..ff7e66a13728
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/api/TestHeadersValidationApiController.java
@@ -0,0 +1,24 @@
+package org.openapitools.api;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.request.NativeWebRequest;
+import java.util.Optional;
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+@Controller
+@RequestMapping("${openapi.testForIssue7125.base-path:}")
+public class TestHeadersValidationApiController implements TestHeadersValidationApi {
+
+ private final NativeWebRequest request;
+
+ @org.springframework.beans.factory.annotation.Autowired
+ public TestHeadersValidationApiController(NativeWebRequest request) {
+ this.request = request;
+ }
+
+ @Override
+ public Optional getRequest() {
+ return Optional.ofNullable(request);
+ }
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/configuration/HomeController.java b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/configuration/HomeController.java
new file mode 100644
index 000000000000..25727830541b
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/configuration/HomeController.java
@@ -0,0 +1,19 @@
+package org.openapitools.configuration;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+
+/**
+ * Home redirection to OpenAPI api documentation
+ */
+@Controller
+public class HomeController {
+
+ @RequestMapping("/")
+ public String index() {
+ return "redirect:swagger-ui.html";
+ }
+
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java
new file mode 100644
index 000000000000..90e156a6e7b9
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/java/org/openapitools/configuration/OpenAPIDocumentationConfig.java
@@ -0,0 +1,70 @@
+package org.openapitools.configuration;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import org.springframework.web.util.UriComponentsBuilder;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.paths.Paths;
+import springfox.documentation.spring.web.paths.RelativePathProvider;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import javax.servlet.ServletContext;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+@Configuration
+@EnableSwagger2
+public class OpenAPIDocumentationConfig {
+
+ ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("Test for Issue 7125")
+ .description("desc")
+ .license("")
+ .licenseUrl("http://unlicense.org")
+ .termsOfServiceUrl("")
+ .version("1.0.0")
+ .contact(new Contact("","", ""))
+ .build();
+ }
+
+ @Bean
+ public Docket customImplementation(ServletContext servletContext, @Value("${openapi.testForIssue7125.base-path:}") String basePath) {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("org.openapitools.api"))
+ .build()
+ .pathProvider(new BasePathAwareRelativePathProvider(servletContext, basePath))
+ .directModelSubstitute(java.time.LocalDate.class, java.sql.Date.class)
+ .directModelSubstitute(java.time.OffsetDateTime.class, java.util.Date.class)
+ .apiInfo(apiInfo());
+ }
+
+ class BasePathAwareRelativePathProvider extends RelativePathProvider {
+ private String basePath;
+
+ public BasePathAwareRelativePathProvider(ServletContext servletContext, String basePath) {
+ super(servletContext);
+ this.basePath = basePath;
+ }
+
+ @Override
+ protected String applicationPath() {
+ return Paths.removeAdjacentForwardSlashes(UriComponentsBuilder.fromPath(super.applicationPath()).path(basePath).build().toString());
+ }
+
+ @Override
+ public String getOperationPath(String operationPath) {
+ UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/");
+ return Paths.removeAdjacentForwardSlashes(
+ uriComponentsBuilder.path(operationPath.replaceFirst("^" + basePath, "")).build().toString());
+ }
+ }
+
+}
diff --git a/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/resources/application.properties b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/resources/application.properties
new file mode 100644
index 000000000000..b80025e1aa33
--- /dev/null
+++ b/samples/server/petstore/spring-mvc-headers-validation-without-optional/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+springfox.documentation.swagger.v2.path=/api-docs
+server.port=8080
+spring.jackson.date-format=org.openapitools.RFC3339DateFormat
+spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false