diff --git a/.github/workflows/samples-jdk17.yaml b/.github/workflows/samples-jdk17.yaml
index 0a550c28f96d..755b25011f11 100644
--- a/.github/workflows/samples-jdk17.yaml
+++ b/.github/workflows/samples-jdk17.yaml
@@ -10,6 +10,7 @@ on:
- samples/client/petstore/spring-http-interface/**
- samples/client/petstore/spring-http-interface-reactive-noResponseEntity/**
- samples/client/petstore/spring-http-interface-noResponseEntity/**
+ - samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/**
- samples/client/petstore/java/webclient-jakarta/**
- samples/client/petstore/java/microprofile-rest-client-outer-enum/**
# servers
@@ -27,6 +28,7 @@ on:
- samples/client/petstore/spring-http-interface/**
- samples/client/petstore/spring-http-interface-reactive-noResponseEntity/**
- samples/client/petstore/spring-http-interface-noResponseEntity/**
+ - samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/**
- samples/client/petstore/java/webclient-jakarta/**
- samples/client/petstore/java/microprofile-rest-client-outer-enum/**
# servers
@@ -50,6 +52,7 @@ jobs:
- samples/client/petstore/spring-http-interface
- samples/client/petstore/spring-http-interface-reactive-noResponseEntity
- samples/client/petstore/spring-http-interface-noResponseEntity
+ - samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator
- samples/client/petstore/java/webclient-jakarta
- samples/client/petstore/java/microprofile-rest-client-outer-enum
# servers
diff --git a/bin/configs/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration.yaml b/bin/configs/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration.yaml
new file mode 100644
index 000000000000..980957a029af
--- /dev/null
+++ b/bin/configs/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration.yaml
@@ -0,0 +1,17 @@
+generatorName: spring
+library: spring-http-interface
+outputDir: samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator
+inputSpec: modules/openapi-generator/src/test/resources/3_0/spring/petstore-with-fake-endpoints-models-for-testing.yaml
+templateDir: modules/openapi-generator/src/main/resources/JavaSpring
+additionalProperties:
+ artifactId: spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator
+ snapshotVersion: "true"
+ hideGenerationTimestamp: "true"
+ # documentation provider should be ignored
+ documentationProvider: "springdoc"
+ # annotation provider should be ignored
+ annotationLibrary: "swagger2"
+ # validation should be ignored
+ useBeanValidation: "true"
+ performBeanValidation: "true"
+ useHttpServiceProxyFactoryInterfacesConfigurator: "true"
diff --git a/docs/generators/java-camel.md b/docs/generators/java-camel.md
index f2714febe563..046fa7b77332 100644
--- a/docs/generators/java-camel.md
+++ b/docs/generators/java-camel.md
@@ -100,6 +100,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true|
|useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
+|useHttpServiceProxyFactoryInterfacesConfigurator|Generate HttpInterfacesAbstractConfigurator based on an HttpServiceProxyFactory instance (as opposed to a WebClient instance, when disabled) for generating Spring HTTP interfaces.| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useOptional|Use Optional container for optional parameters| |false|
diff --git a/docs/generators/spring.md b/docs/generators/spring.md
index 954b786ebd13..03b67aa1c1d1 100644
--- a/docs/generators/spring.md
+++ b/docs/generators/spring.md
@@ -93,6 +93,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useBeanValidation|Use BeanValidation API annotations| |true|
|useEnumCaseInsensitive|Use `equalsIgnoreCase` when String for enum comparison| |false|
|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
+|useHttpServiceProxyFactoryInterfacesConfigurator|Generate HttpInterfacesAbstractConfigurator based on an HttpServiceProxyFactory instance (as opposed to a WebClient instance, when disabled) for generating Spring HTTP interfaces.| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useOptional|Use Optional container for optional parameters| |false|
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
index 5b28553854b2..0724a10f1a73 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
@@ -83,6 +83,8 @@ public class SpringCodegen extends AbstractJavaCodegen
public static final String SPRING_BOOT = "spring-boot";
public static final String SPRING_CLOUD_LIBRARY = "spring-cloud";
public static final String SPRING_HTTP_INTERFACE = "spring-http-interface";
+ public static final String USE_HTTP_SERVICE_PROXY_FACTORY_INTERFACES_CONFIGURATOR = "useHttpServiceProxyFactoryInterfacesConfigurator";
+ public static final String HTTP_INTERFACES_CONFIGURATOR_DEPENDENCY = "httpInterfacesConfiguratorDependency";
public static final String API_FIRST = "apiFirst";
public static final String SPRING_CONTROLLER = "useSpringController";
public static final String HATEOAS = "hateoas";
@@ -152,6 +154,7 @@ public enum RequestMappingMode {
protected RequestMappingMode requestMappingMode = RequestMappingMode.controller;
@Getter @Setter
protected boolean optionalAcceptNullable = true;
+ @Setter boolean useHttpServiceProxyFactoryInterfacesConfigurator = false;
public SpringCodegen() {
super();
@@ -260,6 +263,10 @@ public SpringCodegen() {
"Use `ofNullable` instead of just `of` to accept null values when using Optional.",
optionalAcceptNullable));
+ cliOptions.add(CliOption.newString(USE_HTTP_SERVICE_PROXY_FACTORY_INTERFACES_CONFIGURATOR,
+ "Generate HttpInterfacesAbstractConfigurator based on an HttpServiceProxyFactory instance (as opposed to a WebClient instance, when disabled) for generating Spring HTTP interfaces.")
+ .defaultValue("false")
+ );
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
"Spring-Cloud-Feign client with Spring-Boot auto-configured settings.");
@@ -438,7 +445,9 @@ public void processOpts() {
useJakartaEe = true;
applyJakartaPackage();
}
+
convertPropertyToStringAndWriteBack(RESOURCE_FOLDER, this::setResourceFolder);
+ convertPropertyToBooleanAndWriteBack(USE_HTTP_SERVICE_PROXY_FACTORY_INTERFACES_CONFIGURATOR, this::setUseHttpServiceProxyFactoryInterfacesConfigurator);
typeMapping.put("file", "org.springframework.core.io.Resource");
importMapping.put("Nullable", "org.springframework.lang.Nullable");
@@ -524,9 +533,19 @@ public void processOpts() {
}
}
} else if (SPRING_HTTP_INTERFACE.equals(library)) {
- supportingFiles.add(new SupportingFile("httpInterfacesConfiguration.mustache",
+ String httpInterfacesAbstractConfiguratorFile = useHttpServiceProxyFactoryInterfacesConfigurator ?
+ "httpServiceProxyFactoryInterfacesConfigurator.mustache" :
+ "httpInterfacesConfiguration.mustache";
+
+ supportingFiles.add(new SupportingFile(httpInterfacesAbstractConfiguratorFile,
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator), "HttpInterfacesAbstractConfigurator.java"));
writePropertyBack(USE_BEANVALIDATION, false);
+
+ writePropertyBack(HTTP_INTERFACES_CONFIGURATOR_DEPENDENCY,
+ useHttpServiceProxyFactoryInterfacesConfigurator ?
+ "HttpServiceProxyFactory" :
+ "WebClient"
+ );
}
}
diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/README.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/README.mustache
index 6cc33662560b..fcda3ead154d 100644
--- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/README.mustache
+++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/README.mustache
@@ -9,13 +9,13 @@ By using the [OpenAPI-Spec](https://openapis.org), you can easily generate an AP
This is an example of building API stub interfaces in Java using the Spring framework.
The stubs generated can be used in your existing Spring application for HTTP integration with other REST services
-To use auto-generated interfaces you have to create your own configuration which extends default abstract configurator & provide `WebClient` instance via constructor
+To use auto-generated interfaces you have to create your own configuration which extends default abstract configurator & provide `{{httpInterfacesConfiguratorDependency}}` instance via constructor
```java
@Configuration
public class MyConfiguration extends {{configPackage}}.HttpInterfacesAbstractConfigurator {
- public MyConfiguration(WebClient myWebClient) { // separately created WebClient instance
- super(myWebClient);
+ public MyConfiguration({{httpInterfacesConfiguratorDependency}} my{{httpInterfacesConfiguratorDependency}}) { // separately created {{httpInterfacesConfiguratorDependency}} instance
+ super(my{{httpInterfacesConfiguratorDependency}});
}
}
```
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpServiceProxyFactoryInterfacesConfigurator.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpServiceProxyFactoryInterfacesConfigurator.mustache
new file mode 100644
index 000000000000..66db22175959
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-http-interface/httpServiceProxyFactoryInterfacesConfigurator.mustache
@@ -0,0 +1,35 @@
+/**
+* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
+* https://openapi-generator.tech
+* Do not edit the class manually.
+*/
+package {{configPackage}};
+
+{{#apiInfo}}
+ {{#apis}}
+import {{apiPackage}}.{{classname}};
+ {{/apis}}
+{{/apiInfo}}
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.service.invoker.HttpServiceProxyFactory;
+
+public abstract class HttpInterfacesAbstractConfigurator {
+
+ private final HttpServiceProxyFactory factory;
+
+ public HttpInterfacesAbstractConfigurator(final HttpServiceProxyFactory factory) {
+ this.factory = factory;
+ }
+
+{{#apiInfo}}
+{{#apis}}
+ @Bean(name = "{{configPackage}}.HttpInterfacesAbstractConfigurator.{{classVarName}}")
+ {{classname}} {{classVarName}}HttpProxy() {
+ return factory.createClient({{classname}}.class);
+ }
+
+{{/apis}}
+{{/apiInfo}}
+
+}
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.openapi-generator-ignore b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.openapi-generator-ignore
new file mode 100644
index 000000000000..7484ee590a38
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.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/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.openapi-generator/FILES b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.openapi-generator/FILES
new file mode 100644
index 000000000000..f91496ca5b57
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.openapi-generator/FILES
@@ -0,0 +1,59 @@
+README.md
+pom.xml
+src/main/java/org/openapitools/api/AnotherFakeApi.java
+src/main/java/org/openapitools/api/FakeApi.java
+src/main/java/org/openapitools/api/FakeClassnameTags123Api.java
+src/main/java/org/openapitools/api/PetApi.java
+src/main/java/org/openapitools/api/StoreApi.java
+src/main/java/org/openapitools/api/UserApi.java
+src/main/java/org/openapitools/configuration/HttpInterfacesAbstractConfigurator.java
+src/main/java/org/openapitools/model/AdditionalPropertiesAnyType.java
+src/main/java/org/openapitools/model/AdditionalPropertiesArray.java
+src/main/java/org/openapitools/model/AdditionalPropertiesBoolean.java
+src/main/java/org/openapitools/model/AdditionalPropertiesClass.java
+src/main/java/org/openapitools/model/AdditionalPropertiesInteger.java
+src/main/java/org/openapitools/model/AdditionalPropertiesNumber.java
+src/main/java/org/openapitools/model/AdditionalPropertiesObject.java
+src/main/java/org/openapitools/model/AdditionalPropertiesString.java
+src/main/java/org/openapitools/model/Animal.java
+src/main/java/org/openapitools/model/ArrayOfArrayOfNumberOnly.java
+src/main/java/org/openapitools/model/ArrayOfNumberOnly.java
+src/main/java/org/openapitools/model/ArrayTest.java
+src/main/java/org/openapitools/model/BigCat.java
+src/main/java/org/openapitools/model/Capitalization.java
+src/main/java/org/openapitools/model/Cat.java
+src/main/java/org/openapitools/model/Category.java
+src/main/java/org/openapitools/model/ChildWithNullable.java
+src/main/java/org/openapitools/model/ClassModel.java
+src/main/java/org/openapitools/model/Client.java
+src/main/java/org/openapitools/model/ContainerDefaultValue.java
+src/main/java/org/openapitools/model/Dog.java
+src/main/java/org/openapitools/model/EnumArrays.java
+src/main/java/org/openapitools/model/EnumClass.java
+src/main/java/org/openapitools/model/EnumTest.java
+src/main/java/org/openapitools/model/File.java
+src/main/java/org/openapitools/model/FileSchemaTestClass.java
+src/main/java/org/openapitools/model/FormatTest.java
+src/main/java/org/openapitools/model/HasOnlyReadOnly.java
+src/main/java/org/openapitools/model/MapTest.java
+src/main/java/org/openapitools/model/MixedPropertiesAndAdditionalPropertiesClass.java
+src/main/java/org/openapitools/model/Model200Response.java
+src/main/java/org/openapitools/model/ModelApiResponse.java
+src/main/java/org/openapitools/model/ModelList.java
+src/main/java/org/openapitools/model/ModelReturn.java
+src/main/java/org/openapitools/model/Name.java
+src/main/java/org/openapitools/model/NullableMapProperty.java
+src/main/java/org/openapitools/model/NumberOnly.java
+src/main/java/org/openapitools/model/Order.java
+src/main/java/org/openapitools/model/OuterComposite.java
+src/main/java/org/openapitools/model/OuterEnum.java
+src/main/java/org/openapitools/model/ParentWithNullable.java
+src/main/java/org/openapitools/model/Pet.java
+src/main/java/org/openapitools/model/ReadOnlyFirst.java
+src/main/java/org/openapitools/model/ResponseObjectWithDifferentFieldNames.java
+src/main/java/org/openapitools/model/SpecialModelName.java
+src/main/java/org/openapitools/model/Tag.java
+src/main/java/org/openapitools/model/TypeHolderDefault.java
+src/main/java/org/openapitools/model/TypeHolderExample.java
+src/main/java/org/openapitools/model/User.java
+src/main/java/org/openapitools/model/XmlItem.java
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.openapi-generator/VERSION b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.openapi-generator/VERSION
new file mode 100644
index 000000000000..96cfbb19ae28
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.13.0-SNAPSHOT
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/README.md b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/README.md
new file mode 100644
index 000000000000..c5e3b37f7190
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/README.md
@@ -0,0 +1,21 @@
+# OpenAPI generated API stub
+
+[Spring Framework 6 HTTP Interface](https://docs.spring.io/spring-framework/docs/6.0.0/reference/html/integration.html#rest-http-interface)
+
+
+## Overview
+This code was generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
+By using the [OpenAPI-Spec](https://openapis.org), you can easily generate an API stub.
+This is an example of building API stub interfaces in Java using the Spring framework.
+
+The stubs generated can be used in your existing Spring application for HTTP integration with other REST services
+To use auto-generated interfaces you have to create your own configuration which extends default abstract configurator & provide `HttpServiceProxyFactory` instance via constructor
+```java
+@Configuration
+public class MyConfiguration extends org.openapitools.configuration.HttpInterfacesAbstractConfigurator {
+
+ public MyConfiguration(HttpServiceProxyFactory myHttpServiceProxyFactory) { // separately created HttpServiceProxyFactory instance
+ super(myHttpServiceProxyFactory);
+ }
+}
+```
\ No newline at end of file
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/pom.xml b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/pom.xml
new file mode 100644
index 000000000000..41a35cd35de8
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/pom.xml
@@ -0,0 +1,76 @@
+
+ 4.0.0
+ org.openapitools
+ spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator
+ jar
+ spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator
+ 1.0.0-SNAPSHOT
+
+ 17
+ UTF-8
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.1.3
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ ${java.version}
+ ${java.version}
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+
+ com.google.code.findbugs
+ jsr305
+ 3.0.2
+
+
+ jakarta.validation
+ jakarta.validation-api
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ org.openapitools
+ jackson-databind-nullable
+ 0.2.6
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/AnotherFakeApi.java b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/AnotherFakeApi.java
new file mode 100644
index 000000000000..df1db0383f5c
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/AnotherFakeApi.java
@@ -0,0 +1,40 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.13.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import org.openapitools.model.Client;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.service.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import jakarta.annotation.Generated;
+
+
+@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.13.0-SNAPSHOT")
+public interface AnotherFakeApi {
+
+ /**
+ * PATCH /another-fake/dummy : To test special tags
+ * To test special tags and operation ID starting with number
+ *
+ * @param client client model (required)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "PATCH",
+ value = "/another-fake/dummy",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity call123testSpecialTags(
+ @RequestBody Client client
+ );
+
+}
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/FakeApi.java b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/FakeApi.java
new file mode 100644
index 000000000000..cf5f4be0383a
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/FakeApi.java
@@ -0,0 +1,377 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.13.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import java.math.BigDecimal;
+import org.openapitools.model.ChildWithNullable;
+import org.openapitools.model.Client;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.openapitools.model.FileSchemaTestClass;
+import java.time.LocalDate;
+import java.util.Map;
+import java.time.OffsetDateTime;
+import org.openapitools.model.OuterComposite;
+import org.openapitools.model.User;
+import org.openapitools.model.XmlItem;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.service.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import jakarta.annotation.Generated;
+
+
+@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.13.0-SNAPSHOT")
+public interface FakeApi {
+
+ /**
+ * POST /fake/create_xml_item : creates an XmlItem
+ * this route creates an XmlItem
+ *
+ * @param xmlItem XmlItem Body (required)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake/create_xml_item",
+ accept = { "application/json" },
+ contentType = "application/xml"
+ )
+ ResponseEntity createXmlItem(
+ @RequestBody XmlItem xmlItem
+ );
+
+
+ /**
+ * POST /fake/outer/boolean
+ * Test serialization of outer boolean types
+ *
+ * @param body Input boolean as post body (optional)
+ * @return Output boolean (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake/outer/boolean",
+ accept = { "*/*" },
+ contentType = "application/json"
+ )
+ ResponseEntity fakeOuterBooleanSerialize(
+ @RequestBody(required = false) Boolean body
+ );
+
+
+ /**
+ * POST /fake/outer/composite
+ * Test serialization of object with outer number type
+ *
+ * @param outerComposite Input composite as post body (optional)
+ * @return Output composite (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake/outer/composite",
+ accept = { "*/*" },
+ contentType = "application/json"
+ )
+ ResponseEntity fakeOuterCompositeSerialize(
+ @RequestBody(required = false) OuterComposite outerComposite
+ );
+
+
+ /**
+ * POST /fake/outer/number
+ * Test serialization of outer number types
+ *
+ * @param body Input number as post body (optional)
+ * @return Output number (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake/outer/number",
+ accept = { "*/*" },
+ contentType = "application/json"
+ )
+ ResponseEntity fakeOuterNumberSerialize(
+ @RequestBody(required = false) BigDecimal body
+ );
+
+
+ /**
+ * POST /fake/outer/string
+ * Test serialization of outer string types
+ *
+ * @param body Input string as post body (optional)
+ * @return Output string (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake/outer/string",
+ accept = { "*/*" },
+ contentType = "application/json"
+ )
+ ResponseEntity fakeOuterStringSerialize(
+ @RequestBody(required = false) String body
+ );
+
+
+ /**
+ * PUT /fake/body-with-file-schema
+ * For this test, the body for this request much reference a schema named `File`.
+ *
+ * @param fileSchemaTestClass (required)
+ * @return Success (status code 200)
+ */
+ @HttpExchange(
+ method = "PUT",
+ value = "/fake/body-with-file-schema",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity testBodyWithFileSchema(
+ @RequestBody FileSchemaTestClass fileSchemaTestClass
+ );
+
+
+ /**
+ * PUT /fake/body-with-query-params
+ *
+ * @param query (required)
+ * @param user (required)
+ * @return Success (status code 200)
+ */
+ @HttpExchange(
+ method = "PUT",
+ value = "/fake/body-with-query-params",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity testBodyWithQueryParams(
+ @RequestParam(value = "query", required = true) String query,
+ @RequestBody User user
+ );
+
+
+ /**
+ * PATCH /fake : To test \"client\" model
+ * To test \"client\" model
+ *
+ * @param client client model (required)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "PATCH",
+ value = "/fake",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity testClientModel(
+ @RequestBody Client client
+ );
+
+
+ /**
+ * POST /fake : Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
+ * Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
+ *
+ * @param number None (required)
+ * @param _double None (required)
+ * @param patternWithoutDelimiter None (required)
+ * @param _byte None (required)
+ * @param integer None (optional)
+ * @param int32 None (optional)
+ * @param int64 None (optional)
+ * @param _float None (optional)
+ * @param string None (optional)
+ * @param binary None (optional)
+ * @param date None (optional)
+ * @param dateTime None (optional)
+ * @param password None (optional)
+ * @param paramCallback None (optional)
+ * @return Invalid username supplied (status code 400)
+ * or User not found (status code 404)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake",
+ accept = { "application/json" },
+ contentType = "application/x-www-form-urlencoded"
+ )
+ ResponseEntity testEndpointParameters(
+ @RequestParam(value = "number", required = true) BigDecimal number,
+ @RequestParam(value = "double", required = true) Double _double,
+ @RequestParam(value = "pattern_without_delimiter", required = true) String patternWithoutDelimiter,
+ @RequestParam(value = "byte", required = true) byte[] _byte,
+ @RequestParam(value = "integer", required = false) Integer integer,
+ @RequestParam(value = "int32", required = false) Integer int32,
+ @RequestParam(value = "int64", required = false) Long int64,
+ @RequestParam(value = "float", required = false) Float _float,
+ @RequestParam(value = "string", required = false) String string,
+ @RequestPart(value = "binary", required = false) MultipartFile binary,
+ @RequestParam(value = "date", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date,
+ @RequestParam(value = "dateTime", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime dateTime,
+ @RequestParam(value = "password", required = false) String password,
+ @RequestParam(value = "callback", required = false) String paramCallback
+ );
+
+
+ /**
+ * GET /fake : To test enum parameters
+ * To test enum parameters
+ *
+ * @param enumHeaderStringArray Header parameter enum test (string array) (optional)
+ * @param enumHeaderString Header parameter enum test (string) (optional, default to -efg)
+ * @param enumQueryStringArray Query parameter enum test (string array) (optional)
+ * @param enumQueryString Query parameter enum test (string) (optional, default to -efg)
+ * @param enumQueryInteger Query parameter enum test (double) (optional)
+ * @param enumQueryDouble Query parameter enum test (double) (optional)
+ * @param enumFormStringArray Form parameter enum test (string array) (optional, default to $)
+ * @param enumFormString Form parameter enum test (string) (optional, default to -efg)
+ * @return Invalid request (status code 400)
+ * or Not found (status code 404)
+ */
+ @HttpExchange(
+ method = "GET",
+ value = "/fake",
+ accept = { "application/json" },
+ contentType = "application/x-www-form-urlencoded"
+ )
+ ResponseEntity testEnumParameters(
+ @RequestHeader(value = "enum_header_string_array", required = false) List enumHeaderStringArray,
+ @RequestHeader(value = "enum_header_string", required = false, defaultValue = "-efg") String enumHeaderString,
+ @RequestParam(value = "enum_query_string_array", required = false) List enumQueryStringArray,
+ @RequestParam(value = "enum_query_string", required = false, defaultValue = "-efg") String enumQueryString,
+ @RequestParam(value = "enum_query_integer", required = false) Integer enumQueryInteger,
+ @RequestParam(value = "enum_query_double", required = false) Double enumQueryDouble,
+ @RequestPart(value = "enum_form_string_array", required = false) List enumFormStringArray,
+ @RequestParam(value = "enum_form_string", required = false) String enumFormString
+ );
+
+
+ /**
+ * DELETE /fake : Fake endpoint to test group parameters (optional)
+ * Fake endpoint to test group parameters (optional)
+ *
+ * @param requiredStringGroup Required String in group parameters (required)
+ * @param requiredBooleanGroup Required Boolean in group parameters (required)
+ * @param requiredInt64Group Required Integer in group parameters (required)
+ * @param stringGroup String in group parameters (optional)
+ * @param booleanGroup Boolean in group parameters (optional)
+ * @param int64Group Integer in group parameters (optional)
+ * @return Something wrong (status code 400)
+ */
+ @HttpExchange(
+ method = "DELETE",
+ value = "/fake",
+ accept = { "application/json" }
+ )
+ ResponseEntity testGroupParameters(
+ @RequestParam(value = "required_string_group", required = true) Integer requiredStringGroup,
+ @RequestHeader(value = "required_boolean_group", required = true) Boolean requiredBooleanGroup,
+ @RequestParam(value = "required_int64_group", required = true) Long requiredInt64Group,
+ @RequestParam(value = "string_group", required = false) Integer stringGroup,
+ @RequestHeader(value = "boolean_group", required = false) Boolean booleanGroup,
+ @RequestParam(value = "int64_group", required = false) Long int64Group
+ );
+
+
+ /**
+ * POST /fake/inline-additionalProperties : test inline additionalProperties
+ *
+ *
+ * @param requestBody request body (required)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake/inline-additionalProperties",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity testInlineAdditionalProperties(
+ @RequestBody Map requestBody
+ );
+
+
+ /**
+ * GET /fake/jsonFormData : test json serialization of form data
+ *
+ *
+ * @param param field1 (required)
+ * @param param2 field2 (required)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "GET",
+ value = "/fake/jsonFormData",
+ accept = { "application/json" },
+ contentType = "application/x-www-form-urlencoded"
+ )
+ ResponseEntity testJsonFormData(
+ @RequestParam(value = "param", required = true) String param,
+ @RequestParam(value = "param2", required = true) String param2
+ );
+
+
+ /**
+ * POST /fake/nullable : test nullable parent property
+ *
+ *
+ * @param childWithNullable request body (required)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake/nullable",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity testNullable(
+ @RequestBody ChildWithNullable childWithNullable
+ );
+
+
+ /**
+ * PUT /fake/test-query-parameters
+ * To test the collection format in query parameters
+ *
+ * @param pipe (required)
+ * @param http (required)
+ * @param url (required)
+ * @param context (required)
+ * @return Success (status code 200)
+ */
+ @HttpExchange(
+ method = "PUT",
+ value = "/fake/test-query-parameters",
+ accept = { "application/json" }
+ )
+ ResponseEntity testQueryParameterCollectionFormat(
+ @RequestParam(value = "pipe", required = true) List pipe,
+ @RequestParam(value = "http", required = true) List http,
+ @RequestParam(value = "url", required = true) List url,
+ @RequestParam(value = "context", required = true) List context
+ );
+
+
+ /**
+ * GET /fake/response-with-example
+ * This endpoint defines an example value for its response schema.
+ *
+ * @return Success (status code 200)
+ */
+ @HttpExchange(
+ method = "GET",
+ value = "/fake/response-with-example",
+ accept = { "application/json" }
+ )
+ ResponseEntity testWithResultExample(
+
+ );
+
+}
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/FakeClassnameTags123Api.java b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/FakeClassnameTags123Api.java
new file mode 100644
index 000000000000..be032b822c68
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/FakeClassnameTags123Api.java
@@ -0,0 +1,40 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.13.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import org.openapitools.model.Client;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.service.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import jakarta.annotation.Generated;
+
+
+@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.13.0-SNAPSHOT")
+public interface FakeClassnameTags123Api {
+
+ /**
+ * PATCH /fake_classname_test : To test class name in snake case
+ * To test class name in snake case
+ *
+ * @param client client model (required)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "PATCH",
+ value = "/fake_classname_test",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity testClassname(
+ @RequestBody Client client
+ );
+
+}
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/PetApi.java b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/PetApi.java
new file mode 100644
index 000000000000..3e3315dc807a
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/PetApi.java
@@ -0,0 +1,224 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.13.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import org.openapitools.model.ModelApiResponse;
+import org.openapitools.model.Pet;
+import org.openapitools.model.ResponseObjectWithDifferentFieldNames;
+import java.util.Set;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.service.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import jakarta.annotation.Generated;
+
+
+@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.13.0-SNAPSHOT")
+public interface PetApi {
+
+ /**
+ * POST /pet : Add a new pet to the store
+ *
+ *
+ * @param pet Pet object that needs to be added to the store (required)
+ * @return successful operation (status code 200)
+ * or Invalid input (status code 405)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/pet",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity addPet(
+ @RequestBody Pet pet
+ );
+
+
+ /**
+ * DELETE /pet/{petId} : Deletes a pet
+ *
+ *
+ * @param petId Pet id to delete (required)
+ * @param apiKey (optional)
+ * @return successful operation (status code 200)
+ * or Invalid pet value (status code 400)
+ */
+ @HttpExchange(
+ method = "DELETE",
+ value = "/pet/{petId}",
+ accept = { "application/json" }
+ )
+ ResponseEntity deletePet(
+ @PathVariable("petId") Long petId,
+ @RequestHeader(value = "api_key", required = false) String apiKey
+ );
+
+
+ /**
+ * GET /pet/findByStatus : Finds Pets by status
+ * Multiple status values can be provided with comma separated strings
+ *
+ * @param status Status values that need to be considered for filter (required)
+ * @return successful operation (status code 200)
+ * or Invalid status value (status code 400)
+ */
+ @HttpExchange(
+ method = "GET",
+ value = "/pet/findByStatus",
+ accept = { "application/json", "application/xml" }
+ )
+ ResponseEntity> findPetsByStatus(
+ @RequestParam(value = "status", required = true) List status
+ );
+
+
+ /**
+ * GET /pet/findByTags : Finds Pets by tags
+ * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+ *
+ * @param tags Tags to filter by (required)
+ * @return successful operation (status code 200)
+ * or Invalid tag value (status code 400)
+ * @deprecated
+ */
+ @Deprecated
+ @HttpExchange(
+ method = "GET",
+ value = "/pet/findByTags",
+ accept = { "application/json", "application/xml" }
+ )
+ ResponseEntity> findPetsByTags(
+ @RequestParam(value = "tags", required = true) Set tags
+ );
+
+
+ /**
+ * GET /pet/{petId} : Find pet by ID
+ * Returns a single pet
+ *
+ * @param petId ID of pet to return (required)
+ * @return successful operation (status code 200)
+ * or Invalid ID supplied (status code 400)
+ * or Pet not found (status code 404)
+ */
+ @HttpExchange(
+ method = "GET",
+ value = "/pet/{petId}",
+ accept = { "application/json", "application/xml" }
+ )
+ ResponseEntity getPetById(
+ @PathVariable("petId") Long petId
+ );
+
+
+ /**
+ * GET /fake/{petId}/response-object-different-names
+ *
+ * @param petId ID of pet to update (required)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "GET",
+ value = "/fake/{petId}/response-object-different-names",
+ accept = { "application/json" }
+ )
+ ResponseEntity responseObjectDifferentNames(
+ @PathVariable("petId") Long petId
+ );
+
+
+ /**
+ * PUT /pet : Update an existing pet
+ *
+ *
+ * @param pet Pet object that needs to be added to the store (required)
+ * @return successful operation (status code 200)
+ * or Invalid ID supplied (status code 400)
+ * or Pet not found (status code 404)
+ * or Validation exception (status code 405)
+ */
+ @HttpExchange(
+ method = "PUT",
+ value = "/pet",
+ accept = { "application/json" },
+ contentType = "application/json"
+ )
+ ResponseEntity updatePet(
+ @RequestBody Pet pet
+ );
+
+
+ /**
+ * POST /pet/{petId} : Updates a pet in the store with form data
+ *
+ *
+ * @param petId ID of pet that needs to be updated (required)
+ * @param name Updated name of the pet (optional)
+ * @param status Updated status of the pet (optional)
+ * @return Invalid input (status code 405)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/pet/{petId}",
+ accept = { "application/json" },
+ contentType = "application/x-www-form-urlencoded"
+ )
+ ResponseEntity updatePetWithForm(
+ @PathVariable("petId") Long petId,
+ @RequestParam(value = "name", required = false) String name,
+ @RequestParam(value = "status", required = false) String status
+ );
+
+
+ /**
+ * POST /pet/{petId}/uploadImage : uploads an image
+ *
+ *
+ * @param petId ID of pet to update (required)
+ * @param additionalMetadata Additional data to pass to server (optional)
+ * @param file file to upload (optional)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/pet/{petId}/uploadImage",
+ accept = { "application/json" },
+ contentType = "multipart/form-data"
+ )
+ ResponseEntity uploadFile(
+ @PathVariable("petId") Long petId,
+ @RequestParam(value = "additionalMetadata", required = false) String additionalMetadata,
+ @RequestPart(value = "file", required = false) MultipartFile file
+ );
+
+
+ /**
+ * POST /fake/{petId}/uploadImageWithRequiredFile : uploads an image (required)
+ *
+ *
+ * @param petId ID of pet to update (required)
+ * @param requiredFile file to upload (required)
+ * @param additionalMetadata Additional data to pass to server (optional)
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "POST",
+ value = "/fake/{petId}/uploadImageWithRequiredFile",
+ accept = { "application/json" },
+ contentType = "multipart/form-data"
+ )
+ ResponseEntity uploadFileWithRequiredFile(
+ @PathVariable("petId") Long petId,
+ @RequestPart(value = "requiredFile", required = true) MultipartFile requiredFile,
+ @RequestParam(value = "additionalMetadata", required = false) String additionalMetadata
+ );
+
+}
diff --git a/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/StoreApi.java b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/StoreApi.java
new file mode 100644
index 000000000000..6216578c548d
--- /dev/null
+++ b/samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/StoreApi.java
@@ -0,0 +1,95 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (7.13.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import java.util.Map;
+import org.openapitools.model.Order;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.service.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import jakarta.annotation.Generated;
+
+
+@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.13.0-SNAPSHOT")
+public interface StoreApi {
+
+ /**
+ * DELETE /store/order/{order_id} : Delete purchase order by ID
+ * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
+ *
+ * @param orderId ID of the order that needs to be deleted (required)
+ * @return Invalid ID supplied (status code 400)
+ * or Order not found (status code 404)
+ */
+ @HttpExchange(
+ method = "DELETE",
+ value = "/store/order/{order_id}",
+ accept = { "application/json" }
+ )
+ ResponseEntity deleteOrder(
+ @PathVariable("order_id") String orderId
+ );
+
+
+ /**
+ * GET /store/inventory : Returns pet inventories by status
+ * Returns a map of status codes to quantities
+ *
+ * @return successful operation (status code 200)
+ */
+ @HttpExchange(
+ method = "GET",
+ value = "/store/inventory",
+ accept = { "application/json" }
+ )
+ ResponseEntity