diff --git a/.gitignore b/.gitignore
index 8760dc40baa..4c4be24a662 100644
--- a/.gitignore
+++ b/.gitignore
@@ -78,6 +78,7 @@ samples/client/petstore/java/default/build/
samples/client/petstore/scala/build/
samples/client/petstore/java/resttemplate/hello.txt
samples/client/petstore/java/retrofit2/hello.txt
+samples/client/petstore/java/feign/hello.txt
#PHP
samples/client/petstore/php/SwaggerClient-php/composer.lock
diff --git a/bin/spring-all-pestore.sh b/bin/spring-all-pestore.sh
index 77d67ec37d7..8424569ce76 100755
--- a/bin/spring-all-pestore.sh
+++ b/bin/spring-all-pestore.sh
@@ -9,3 +9,4 @@
./bin/spring-mvc-petstore-server.sh
./bin/springboot-petstore-server-beanvalidation.sh
./bin/springboot-petstore-server-implicitHeaders.sh
+./bin/springboot-petstore-server-useOptional.sh
diff --git a/bin/springboot-petstore-server-useOptional.json b/bin/springboot-petstore-server-useOptional.json
new file mode 100644
index 00000000000..5a0c80d6b9c
--- /dev/null
+++ b/bin/springboot-petstore-server-useOptional.json
@@ -0,0 +1,4 @@
+{
+ "artifactId": "spring-boot-useoptional",
+ "useOptional": true
+}
diff --git a/bin/springboot-petstore-server-useOptional.sh b/bin/springboot-petstore-server-useOptional.sh
new file mode 100755
index 00000000000..5b53bfbecf6
--- /dev/null
+++ b/bin/springboot-petstore-server-useOptional.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+SCRIPT="$0"
+
+while [ -h "$SCRIPT" ] ; do
+ ls=`ls -ld "$SCRIPT"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SCRIPT="$link"
+ else
+ SCRIPT=`dirname "$SCRIPT"`/"$link"
+ fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+ APP_DIR=`dirname "$SCRIPT"`/..
+ APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+ mvn clean package
+fi
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
+ags="$@ generate -t modules/swagger-codegen/src/main/resources/JavaSpring -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l spring -c bin/springboot-petstore-server-useOptional.json -o samples/server/petstore/springboot-useoptional -DhideGenerationTimestamp=true"
+
+echo "Removing files and folders under samples/server/petstore/springboot-useoptional/src/main"
+rm -rf samples/server/petstore/springboot-useoptional/src/main
+find samples/server/petstore/springboot-useoptional -maxdepth 1 -type f ! -name "README.md" -exec rm {} +
+java $JAVA_OPTS -jar $executable $ags
diff --git a/circle.yml b/circle.yml
index a4e71cc09d1..1fb626bce55 100644
--- a/circle.yml
+++ b/circle.yml
@@ -32,14 +32,18 @@ dependencies:
test:
override:
- # test with jdk8
+ ## test with jdk8
- java -version
- mvn -q clean verify -Psamples
- # test with jdk7
+ # skip the rest if previous mvn task fails
+ - if [ $? -ne 0 ]; then exit 1; fi
+ ## test with jdk7
- sudo update-java-alternatives -s java-1.7.0-openjdk-amd64
- java -version
- mvn -q clean verify -Psamples
- # docker: build generator image and push to Docker Hub
+ # skip the rest if previous mvn task fails
+ - if [ $? -ne 0 ]; then exit 1; fi
+ ## docker: build generator image and push to Docker Hub
- if [ $DOCKER_HUB_USERNAME ]; then docker login --email=$DOCKER_HUB_EMAIL --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD && docker build --rm=false -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/swagger-generator && if [ ! -z "$CIRCLE_TAG" ]; then docker tag $DOCKER_GENERATOR_IMAGE_NAME:latest $DOCKER_GENERATOR_IMAGE_NAME:$CIRCLE_TAG; fi && if [ ! -z "$CIRCLE_TAG" ] || [ "$CIRCLE_BRANCH" = "master" ]; then docker push $DOCKER_GENERATOR_IMAGE_NAME; fi; fi
- # docker: build cli image and push to Docker Hub
+ ## docker: build cli image and push to Docker Hub
- if [ $DOCKER_HUB_USERNAME ]; then docker login --email=$DOCKER_HUB_EMAIL --username=$DOCKER_HUB_USERNAME --password=$DOCKER_HUB_PASSWORD && docker build --rm=false -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/swagger-codegen-cli && if [ ! -z "$CIRCLE_TAG" ]; then docker tag $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest $DOCKER_CODEGEN_CLI_IMAGE_NAME:$CIRCLE_TAG; fi && if [ ! -z "$CIRCLE_TAG" ] || [ "$CIRCLE_BRANCH" = "master" ]; then docker push $DOCKER_CODEGEN_CLI_IMAGE_NAME; fi; fi
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SpringCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SpringCodegen.java
index 35d2f25fbf9..0670e1bb097 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SpringCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SpringCodegen.java
@@ -4,6 +4,7 @@ import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import io.swagger.codegen.*;
import io.swagger.codegen.languages.features.BeanValidationFeatures;
+import io.swagger.codegen.languages.features.OptionalFeatures;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
@@ -15,7 +16,8 @@ import java.util.*;
import java.util.regex.Matcher;
-public class SpringCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
+public class SpringCodegen extends AbstractJavaCodegen
+ implements BeanValidationFeatures, OptionalFeatures {
public static final String DEFAULT_LIBRARY = "spring-boot";
public static final String TITLE = "title";
public static final String CONFIG_PACKAGE = "configPackage";
@@ -43,6 +45,7 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation
protected boolean useTags = false;
protected boolean useBeanValidation = true;
protected boolean implicitHeaders = false;
+ protected boolean useOptional = false;
public SpringCodegen() {
super();
@@ -72,6 +75,8 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation
cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames"));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations"));
cliOptions.add(CliOption.newBoolean(IMPLICIT_HEADERS, "Use of @ApiImplicitParams for headers."));
+ cliOptions.add(CliOption.newBoolean(USE_OPTIONAL,
+ "Use Optional container for optional parameters"));
supportedLibraries.put(DEFAULT_LIBRARY, "Spring-boot Server application using the SpringFox integration.");
supportedLibraries.put(SPRING_MVC_LIBRARY, "Spring-MVC Server application using the SpringFox integration.");
@@ -154,17 +159,24 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation
this.setUseBeanValidation(convertPropertyToBoolean(USE_BEANVALIDATION));
}
+ if (additionalProperties.containsKey(USE_OPTIONAL)) {
+ this.setUseOptional(convertPropertyToBoolean(USE_OPTIONAL));
+ }
+
if (useBeanValidation) {
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
}
-
if (additionalProperties.containsKey(IMPLICIT_HEADERS)) {
this.setImplicitHeaders(Boolean.valueOf(additionalProperties.get(IMPLICIT_HEADERS).toString()));
}
typeMapping.put("file", "Resource");
importMapping.put("Resource", "org.springframework.core.io.Resource");
+
+ if (useOptional) {
+ writePropertyBack(USE_OPTIONAL, useOptional);
+ }
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
@@ -613,4 +625,8 @@ public class SpringCodegen extends AbstractJavaCodegen implements BeanValidation
this.useBeanValidation = useBeanValidation;
}
+ @Override
+ public void setUseOptional(boolean useOptional) {
+ this.useOptional = useOptional;
+ }
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/features/OptionalFeatures.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/features/OptionalFeatures.java
new file mode 100644
index 00000000000..5b83739c565
--- /dev/null
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/features/OptionalFeatures.java
@@ -0,0 +1,10 @@
+package io.swagger.codegen.languages.features;
+
+public interface OptionalFeatures {
+
+ // Language supports generating Optional Types
+ String USE_OPTIONAL = "useOptional";
+
+ void setUseOptional(boolean useOptional);
+
+}
diff --git a/modules/swagger-codegen/src/main/resources/JavaSpring/api.mustache b/modules/swagger-codegen/src/main/resources/JavaSpring/api.mustache
index bcdd35ecf1d..9b1acf30d1b 100644
--- a/modules/swagger-codegen/src/main/resources/JavaSpring/api.mustache
+++ b/modules/swagger-codegen/src/main/resources/JavaSpring/api.mustache
@@ -23,6 +23,9 @@ import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
+{{#useOptional}}
+import java.util.Optional;
+{{/useOptional}}
{{#async}}
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
{{/async}}
diff --git a/modules/swagger-codegen/src/main/resources/JavaSpring/apiController.mustache b/modules/swagger-codegen/src/main/resources/JavaSpring/apiController.mustache
index b952cd6f51e..cb76830b77a 100644
--- a/modules/swagger-codegen/src/main/resources/JavaSpring/apiController.mustache
+++ b/modules/swagger-codegen/src/main/resources/JavaSpring/apiController.mustache
@@ -19,6 +19,9 @@ import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
+{{#useOptional}}
+import java.util.Optional;
+{{/useOptional}}
{{#async}}
import java.util.concurrent.Callable;
{{/async}}{{/jdk8-no-delegate}}
diff --git a/modules/swagger-codegen/src/main/resources/JavaSpring/headerParams.mustache b/modules/swagger-codegen/src/main/resources/JavaSpring/headerParams.mustache
index 535f2e6f2b3..89645c9436a 100644
--- a/modules/swagger-codegen/src/main/resources/JavaSpring/headerParams.mustache
+++ b/modules/swagger-codegen/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}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @RequestHeader(value="{{baseName}}", required={{#required}}true{{/required}}{{^required}}false{{/required}}) {{{dataType}}} {{paramName}}{{/isHeaderParam}}
\ No newline at end of file
+{{#isHeaderParam}}@ApiParam(value = "{{{description}}}" {{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @RequestHeader(value="{{baseName}}", required={{#required}}true{{/required}}{{^required}}false{{/required}}) {{>optionalDataType}} {{paramName}}{{/isHeaderParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/JavaSpring/optionalDataType.mustache b/modules/swagger-codegen/src/main/resources/JavaSpring/optionalDataType.mustache
new file mode 100644
index 00000000000..976950e27e8
--- /dev/null
+++ b/modules/swagger-codegen/src/main/resources/JavaSpring/optionalDataType.mustache
@@ -0,0 +1 @@
+{{#useOptional}}{{#required}}{{{dataType}}}{{/required}}{{^required}}Optional<{{{dataType}}}>{{/required}}{{/useOptional}}{{^useOptional}}{{{dataType}}}{{/useOptional}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/JavaSpring/pathParams.mustache b/modules/swagger-codegen/src/main/resources/JavaSpring/pathParams.mustache
index d577abfb25a..62342d01bfa 100644
--- a/modules/swagger-codegen/src/main/resources/JavaSpring/pathParams.mustache
+++ b/modules/swagger-codegen/src/main/resources/JavaSpring/pathParams.mustache
@@ -1 +1 @@
-{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}} {{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @PathVariable("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}}
\ No newline at end of file
+{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{/allowableValues}} {{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) @PathVariable("{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isPathParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/main/resources/JavaSpring/queryParams.mustache b/modules/swagger-codegen/src/main/resources/JavaSpring/queryParams.mustache
index 97ba247a1ee..222831b72f4 100644
--- a/modules/swagger-codegen/src/main/resources/JavaSpring/queryParams.mustache
+++ b/modules/swagger-codegen/src/main/resources/JavaSpring/queryParams.mustache
@@ -1 +1 @@
-{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}) @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/isQueryParam}}
\ No newline at end of file
+{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}) @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{>optionalDataType}} {{paramName}}{{/isQueryParam}}
\ No newline at end of file
diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/SpringOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/SpringOptionsProvider.java
index 6387d49f144..ca5c83689fb 100644
--- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/SpringOptionsProvider.java
+++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/SpringOptionsProvider.java
@@ -20,6 +20,7 @@ public class SpringOptionsProvider extends JavaOptionsProvider {
public static final String USE_TAGS = "useTags";
public static final String USE_BEANVALIDATION = "false";
public static final String IMPLICIT_HEADERS = "false";
+ public static final String USE_OPTIONAL = "false";
@Override
public String getLanguage() {
@@ -42,6 +43,7 @@ public class SpringOptionsProvider extends JavaOptionsProvider {
options.put(SpringCodegen.USE_TAGS, USE_TAGS);
options.put(SpringCodegen.USE_BEANVALIDATION, USE_BEANVALIDATION);
options.put(SpringCodegen.IMPLICIT_HEADERS, IMPLICIT_HEADERS);
+ options.put(SpringCodegen.USE_OPTIONAL, USE_OPTIONAL);
return options;
}
diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/spring/SpringOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/spring/SpringOptionsTest.java
index 606f1947f9e..a809725ae7a 100644
--- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/spring/SpringOptionsTest.java
+++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/spring/SpringOptionsTest.java
@@ -4,7 +4,6 @@ import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.java.JavaClientOptionsTest;
import io.swagger.codegen.languages.SpringCodegen;
import io.swagger.codegen.options.SpringOptionsProvider;
-
import mockit.Expectations;
import mockit.Tested;
@@ -74,6 +73,9 @@ public class SpringOptionsTest extends JavaClientOptionsTest {
times = 1;
clientCodegen.setImplicitHeaders(Boolean.valueOf(SpringOptionsProvider.IMPLICIT_HEADERS));
times = 1;
+ clientCodegen.setUseOptional(
+ Boolean.valueOf(SpringOptionsProvider.USE_OPTIONAL));
+ times = 1;
}};
}
-}
\ No newline at end of file
+}
diff --git a/pom.xml.circleci b/pom.xml.circleci
index 8672fde85d6..4ab45ec4c1c 100644
--- a/pom.xml.circleci
+++ b/pom.xml.circleci
@@ -710,6 +710,18 @@
samples/server/petstore/spring-mvc
+
+ springboot-useoptional
+
+
+ env
+ java
+
+
+
+ samples/server/petstore/springboot-useoptional
+
+
springboot-beanvalidation
@@ -821,6 +833,7 @@
samples/client/petstore/spring-cloud
samples/server/petstore/springboot
samples/server/petstore/springboot-beanvalidation
+ samples/server/petstore/springboot-useoptional
samples/server/petstore/jaxrs-cxf
samples/server/petstore/jaxrs-cxf-annotated-base-path
samples/server/petstore/jaxrs-cxf-cdi
diff --git a/samples/server/petstore/spring-mvc-j8-async/src/main/java/io/swagger/model/FormatTest.java b/samples/server/petstore/spring-mvc-j8-async/src/main/java/io/swagger/model/FormatTest.java
index b5d0c2e2505..411c1ca63b9 100644
--- a/samples/server/petstore/spring-mvc-j8-async/src/main/java/io/swagger/model/FormatTest.java
+++ b/samples/server/petstore/spring-mvc-j8-async/src/main/java/io/swagger/model/FormatTest.java
@@ -220,7 +220,7 @@ public class FormatTest {
@ApiModelProperty(required = true, value = "")
@NotNull
-
+ @Pattern(regexp="^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
public byte[] getByte() {
return _byte;
}
diff --git a/samples/server/petstore/spring-mvc/src/main/java/io/swagger/model/FormatTest.java b/samples/server/petstore/spring-mvc/src/main/java/io/swagger/model/FormatTest.java
index 5ef3ec92155..d88a4882efc 100644
--- a/samples/server/petstore/spring-mvc/src/main/java/io/swagger/model/FormatTest.java
+++ b/samples/server/petstore/spring-mvc/src/main/java/io/swagger/model/FormatTest.java
@@ -220,7 +220,7 @@ public class FormatTest {
@ApiModelProperty(required = true, value = "")
@NotNull
-
+ @Pattern(regexp="^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
public byte[] getByte() {
return _byte;
}
diff --git a/samples/server/petstore/springboot-beanvalidation/src/main/java/io/swagger/model/FormatTest.java b/samples/server/petstore/springboot-beanvalidation/src/main/java/io/swagger/model/FormatTest.java
index 5ef3ec92155..d88a4882efc 100644
--- a/samples/server/petstore/springboot-beanvalidation/src/main/java/io/swagger/model/FormatTest.java
+++ b/samples/server/petstore/springboot-beanvalidation/src/main/java/io/swagger/model/FormatTest.java
@@ -220,7 +220,7 @@ public class FormatTest {
@ApiModelProperty(required = true, value = "")
@NotNull
-
+ @Pattern(regexp="^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
public byte[] getByte() {
return _byte;
}
diff --git a/samples/server/petstore/springboot-delegate-j8/src/main/java/io/swagger/model/FormatTest.java b/samples/server/petstore/springboot-delegate-j8/src/main/java/io/swagger/model/FormatTest.java
index b5d0c2e2505..411c1ca63b9 100644
--- a/samples/server/petstore/springboot-delegate-j8/src/main/java/io/swagger/model/FormatTest.java
+++ b/samples/server/petstore/springboot-delegate-j8/src/main/java/io/swagger/model/FormatTest.java
@@ -220,7 +220,7 @@ public class FormatTest {
@ApiModelProperty(required = true, value = "")
@NotNull
-
+ @Pattern(regexp="^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
public byte[] getByte() {
return _byte;
}
diff --git a/samples/server/petstore/springboot-delegate/src/main/java/io/swagger/model/FormatTest.java b/samples/server/petstore/springboot-delegate/src/main/java/io/swagger/model/FormatTest.java
index 5ef3ec92155..d88a4882efc 100644
--- a/samples/server/petstore/springboot-delegate/src/main/java/io/swagger/model/FormatTest.java
+++ b/samples/server/petstore/springboot-delegate/src/main/java/io/swagger/model/FormatTest.java
@@ -220,7 +220,7 @@ public class FormatTest {
@ApiModelProperty(required = true, value = "")
@NotNull
-
+ @Pattern(regexp="^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
public byte[] getByte() {
return _byte;
}
diff --git a/samples/server/petstore/springboot-implicitHeaders/src/main/java/io/swagger/model/FormatTest.java b/samples/server/petstore/springboot-implicitHeaders/src/main/java/io/swagger/model/FormatTest.java
index 5ef3ec92155..d88a4882efc 100644
--- a/samples/server/petstore/springboot-implicitHeaders/src/main/java/io/swagger/model/FormatTest.java
+++ b/samples/server/petstore/springboot-implicitHeaders/src/main/java/io/swagger/model/FormatTest.java
@@ -220,7 +220,7 @@ public class FormatTest {
@ApiModelProperty(required = true, value = "")
@NotNull
-
+ @Pattern(regexp="^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
public byte[] getByte() {
return _byte;
}
diff --git a/samples/server/petstore/springboot-useoptional/.swagger-codegen-ignore b/samples/server/petstore/springboot-useoptional/.swagger-codegen-ignore
new file mode 100644
index 00000000000..c5fa491b4c5
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/.swagger-codegen-ignore
@@ -0,0 +1,23 @@
+# Swagger Codegen Ignore
+# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
+
+# 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 Swagger Codgen 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/springboot-useoptional/.swagger-codegen/VERSION b/samples/server/petstore/springboot-useoptional/.swagger-codegen/VERSION
new file mode 100644
index 00000000000..7fea99011a6
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/.swagger-codegen/VERSION
@@ -0,0 +1 @@
+2.2.3-SNAPSHOT
\ No newline at end of file
diff --git a/samples/server/petstore/springboot-useoptional/README.md b/samples/server/petstore/springboot-useoptional/README.md
new file mode 100644
index 00000000000..a2e8a9f7b84
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/README.md
@@ -0,0 +1,18 @@
+# Swagger generated server
+
+Spring Boot Server
+
+
+## Overview
+This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project.
+By using the [OpenAPI-Spec](https://github.com/swagger-api/swagger-core), you can easily generate a server stub.
+This is an example of building a swagger-enabled server in Java using the SpringBoot framework.
+
+The underlying library integrating swagger to SpringBoot is [springfox](https://github.com/springfox/springfox)
+
+Start your server as an 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/springboot-useoptional/pom.xml b/samples/server/petstore/springboot-useoptional/pom.xml
new file mode 100644
index 00000000000..b7a0f8dd770
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/pom.xml
@@ -0,0 +1,73 @@
+
+ 4.0.0
+ io.swagger
+ spring-boot-useoptional
+ jar
+ spring-boot-useoptional
+ 1.0.0
+
+ 1.7
+ ${java.version}
+ ${java.version}
+ 2.6.1
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.4.7.RELEASE
+
+
+ src/main/java
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox-version}
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${springfox-version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-joda
+
+
+ joda-time
+ joda-time
+
+
+
+ javax.validation
+ validation-api
+ 1.1.0.Final
+ provided
+
+
+
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/RFC3339DateFormat.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/RFC3339DateFormat.java
new file mode 100644
index 00000000000..0c3d276d2d4
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/RFC3339DateFormat.java
@@ -0,0 +1,20 @@
+package io.swagger;
+
+import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+import com.fasterxml.jackson.databind.util.ISO8601Utils;
+
+import java.text.FieldPosition;
+import java.util.Date;
+
+
+public class RFC3339DateFormat extends ISO8601DateFormat {
+
+ // Same as ISO8601DateFormat but serializing milliseconds.
+ @Override
+ public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
+ String value = ISO8601Utils.format(date, true);
+ toAppendTo.append(value);
+ return toAppendTo;
+ }
+
+}
\ No newline at end of file
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/Swagger2SpringBoot.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/Swagger2SpringBoot.java
new file mode 100644
index 00000000000..75d822f027e
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/Swagger2SpringBoot.java
@@ -0,0 +1,36 @@
+package io.swagger;
+
+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.ComponentScan;
+
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@SpringBootApplication
+@EnableSwagger2
+@ComponentScan(basePackages = "io.swagger")
+public class Swagger2SpringBoot 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(Swagger2SpringBoot.class).run(args);
+ }
+
+ class ExitException extends RuntimeException implements ExitCodeGenerator {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public int getExitCode() {
+ return 10;
+ }
+
+ }
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiException.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiException.java
new file mode 100644
index 00000000000..97e535d3c21
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiException.java
@@ -0,0 +1,10 @@
+package io.swagger.api;
+
+
+public class ApiException extends Exception{
+ private int code;
+ public ApiException (int code, String msg) {
+ super(msg);
+ this.code = code;
+ }
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiOriginFilter.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiOriginFilter.java
new file mode 100644
index 00000000000..62646761f5a
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiOriginFilter.java
@@ -0,0 +1,27 @@
+package io.swagger.api;
+
+import java.io.IOException;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletResponse;
+
+
+public class ApiOriginFilter implements javax.servlet.Filter {
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
+ HttpServletResponse res = (HttpServletResponse) response;
+ res.addHeader("Access-Control-Allow-Origin", "*");
+ res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
+ res.addHeader("Access-Control-Allow-Headers", "Content-Type");
+ chain.doFilter(request, response);
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiResponseMessage.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiResponseMessage.java
new file mode 100644
index 00000000000..162678c57e3
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/ApiResponseMessage.java
@@ -0,0 +1,69 @@
+package io.swagger.api;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+
+@javax.xml.bind.annotation.XmlRootElement
+public class ApiResponseMessage {
+ public static final int ERROR = 1;
+ public static final int WARNING = 2;
+ public static final int INFO = 3;
+ public static final int OK = 4;
+ public static final int TOO_BUSY = 5;
+
+ int code;
+ String type;
+ String message;
+
+ public ApiResponseMessage(){}
+
+ public ApiResponseMessage(int code, String message){
+ this.code = code;
+ switch(code){
+ case ERROR:
+ setType("error");
+ break;
+ case WARNING:
+ setType("warning");
+ break;
+ case INFO:
+ setType("info");
+ break;
+ case OK:
+ setType("ok");
+ break;
+ case TOO_BUSY:
+ setType("too busy");
+ break;
+ default:
+ setType("unknown");
+ break;
+ }
+ this.message = message;
+ }
+
+ @XmlTransient
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/FakeApi.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/FakeApi.java
new file mode 100644
index 00000000000..bc294e8627c
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/FakeApi.java
@@ -0,0 +1,105 @@
+/**
+ * NOTE: This class is auto generated by the swagger code generator program (2.2.3-SNAPSHOT).
+ * https://github.com/swagger-api/swagger-codegen
+ * Do not edit the class manually.
+ */
+package io.swagger.api;
+
+import java.math.BigDecimal;
+import io.swagger.model.Client;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import io.swagger.model.OuterComposite;
+
+import io.swagger.annotations.*;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Optional;
+import javax.validation.constraints.*;
+import javax.validation.Valid;
+
+@Api(value = "fake", description = "the fake API")
+public interface FakeApi {
+
+ @ApiOperation(value = "", notes = "Test serialization of outer boolean types", response = Boolean.class, tags={ "fake", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "Output boolean", response = Boolean.class) })
+
+ @RequestMapping(value = "/fake/outer/boolean",
+ method = RequestMethod.POST)
+ ResponseEntity fakeOuterBooleanSerialize(@ApiParam(value = "Input boolean as post body" ) @Valid @RequestBody Boolean body);
+
+
+ @ApiOperation(value = "", notes = "Test serialization of object with outer number type", response = OuterComposite.class, tags={ "fake", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "Output composite", response = OuterComposite.class) })
+
+ @RequestMapping(value = "/fake/outer/composite",
+ method = RequestMethod.POST)
+ ResponseEntity fakeOuterCompositeSerialize(@ApiParam(value = "Input composite as post body" ) @Valid @RequestBody OuterComposite body);
+
+
+ @ApiOperation(value = "", notes = "Test serialization of outer number types", response = BigDecimal.class, tags={ "fake", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "Output number", response = BigDecimal.class) })
+
+ @RequestMapping(value = "/fake/outer/number",
+ method = RequestMethod.POST)
+ ResponseEntity fakeOuterNumberSerialize(@ApiParam(value = "Input number as post body" ) @Valid @RequestBody BigDecimal body);
+
+
+ @ApiOperation(value = "", notes = "Test serialization of outer string types", response = String.class, tags={ "fake", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "Output string", response = String.class) })
+
+ @RequestMapping(value = "/fake/outer/string",
+ method = RequestMethod.POST)
+ ResponseEntity fakeOuterStringSerialize(@ApiParam(value = "Input string as post body" ) @Valid @RequestBody String body);
+
+
+ @ApiOperation(value = "To test \"client\" model", notes = "To test \"client\" model", response = Client.class, tags={ "fake", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "successful operation", response = Client.class) })
+
+ @RequestMapping(value = "/fake",
+ produces = { "application/json" },
+ consumes = { "application/json" },
+ method = RequestMethod.PATCH)
+ ResponseEntity testClientModel(@ApiParam(value = "client model" ,required=true ) @Valid @RequestBody Client body);
+
+
+ @ApiOperation(value = "Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 ", notes = "Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 ", response = Void.class, authorizations = {
+ @Authorization(value = "http_basic_test")
+ }, tags={ "fake", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid username supplied", response = Void.class),
+ @ApiResponse(code = 404, message = "User not found", response = Void.class) })
+
+ @RequestMapping(value = "/fake",
+ produces = { "application/xml; charset=utf-8", "application/json; charset=utf-8" },
+ consumes = { "application/xml; charset=utf-8", "application/json; charset=utf-8" },
+ method = RequestMethod.POST)
+ ResponseEntity testEndpointParameters(@ApiParam(value = "None", required=true) @RequestPart(value="number", required=true) BigDecimal number,@ApiParam(value = "None", required=true) @RequestPart(value="double", required=true) Double _double,@ApiParam(value = "None", required=true) @RequestPart(value="pattern_without_delimiter", required=true) String patternWithoutDelimiter,@ApiParam(value = "None", required=true) @RequestPart(value="byte", required=true) byte[] _byte,@ApiParam(value = "None") @RequestPart(value="integer", required=false) Integer integer,@ApiParam(value = "None") @RequestPart(value="int32", required=false) Integer int32,@ApiParam(value = "None") @RequestPart(value="int64", required=false) Long int64,@ApiParam(value = "None") @RequestPart(value="float", required=false) Float _float,@ApiParam(value = "None") @RequestPart(value="string", required=false) String string,@ApiParam(value = "None") @RequestPart(value="binary", required=false) byte[] binary,@ApiParam(value = "None") @RequestPart(value="date", required=false) LocalDate date,@ApiParam(value = "None") @RequestPart(value="dateTime", required=false) DateTime dateTime,@ApiParam(value = "None") @RequestPart(value="password", required=false) String password,@ApiParam(value = "None") @RequestPart(value="callback", required=false) String paramCallback);
+
+
+ @ApiOperation(value = "To test enum parameters", notes = "To test enum parameters", response = Void.class, tags={ "fake", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid request", response = Void.class),
+ @ApiResponse(code = 404, message = "Not found", response = Void.class) })
+
+ @RequestMapping(value = "/fake",
+ produces = { "*/*" },
+ consumes = { "*/*" },
+ method = RequestMethod.GET)
+ ResponseEntity testEnumParameters(@ApiParam(value = "Form parameter enum test (string array)", allowableValues=">, $") @RequestPart(value="enum_form_string_array", required=false) List enumFormStringArray,@ApiParam(value = "Form parameter enum test (string)", allowableValues="_abc, -efg, (xyz)", defaultValue="-efg") @RequestPart(value="enum_form_string", required=false) String enumFormString,@ApiParam(value = "Header parameter enum test (string array)" , allowableValues=">, $") @RequestHeader(value="enum_header_string_array", required=false) Optional> enumHeaderStringArray,@ApiParam(value = "Header parameter enum test (string)" , allowableValues="_abc, -efg, (xyz)", defaultValue="-efg") @RequestHeader(value="enum_header_string", required=false) Optional enumHeaderString,@ApiParam(value = "Query parameter enum test (string array)", allowableValues = ">, $") @RequestParam(value = "enum_query_string_array", required = false) Optional> enumQueryStringArray,@ApiParam(value = "Query parameter enum test (string)", allowableValues = "_abc, -efg, (xyz)", defaultValue = "-efg") @RequestParam(value = "enum_query_string", required = false, defaultValue="-efg") Optional enumQueryString,@ApiParam(value = "Query parameter enum test (double)", allowableValues = "1, -2") @RequestParam(value = "enum_query_integer", required = false) Optional enumQueryInteger,@ApiParam(value = "Query parameter enum test (double)", allowableValues="1.1, -1.2") @RequestPart(value="enum_query_double", required=false) Double enumQueryDouble);
+
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/FakeApiController.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/FakeApiController.java
new file mode 100644
index 00000000000..0fd5a81fbb3
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/FakeApiController.java
@@ -0,0 +1,87 @@
+package io.swagger.api;
+
+import java.math.BigDecimal;
+import io.swagger.model.Client;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import io.swagger.model.OuterComposite;
+
+import io.swagger.annotations.*;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.validation.constraints.*;
+import javax.validation.Valid;
+
+@Controller
+public class FakeApiController implements FakeApi {
+
+
+
+ public ResponseEntity fakeOuterBooleanSerialize(@ApiParam(value = "Input boolean as post body" ) @Valid @RequestBody Boolean body) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity fakeOuterCompositeSerialize(@ApiParam(value = "Input composite as post body" ) @Valid @RequestBody OuterComposite body) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity fakeOuterNumberSerialize(@ApiParam(value = "Input number as post body" ) @Valid @RequestBody BigDecimal body) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity fakeOuterStringSerialize(@ApiParam(value = "Input string as post body" ) @Valid @RequestBody String body) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity testClientModel(@ApiParam(value = "client model" ,required=true ) @Valid @RequestBody Client body) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity testEndpointParameters(@ApiParam(value = "None", required=true) @RequestPart(value="number", required=true) BigDecimal number,
+ @ApiParam(value = "None", required=true) @RequestPart(value="double", required=true) Double _double,
+ @ApiParam(value = "None", required=true) @RequestPart(value="pattern_without_delimiter", required=true) String patternWithoutDelimiter,
+ @ApiParam(value = "None", required=true) @RequestPart(value="byte", required=true) byte[] _byte,
+ @ApiParam(value = "None") @RequestPart(value="integer", required=false) Integer integer,
+ @ApiParam(value = "None") @RequestPart(value="int32", required=false) Integer int32,
+ @ApiParam(value = "None") @RequestPart(value="int64", required=false) Long int64,
+ @ApiParam(value = "None") @RequestPart(value="float", required=false) Float _float,
+ @ApiParam(value = "None") @RequestPart(value="string", required=false) String string,
+ @ApiParam(value = "None") @RequestPart(value="binary", required=false) byte[] binary,
+ @ApiParam(value = "None") @RequestPart(value="date", required=false) LocalDate date,
+ @ApiParam(value = "None") @RequestPart(value="dateTime", required=false) DateTime dateTime,
+ @ApiParam(value = "None") @RequestPart(value="password", required=false) String password,
+ @ApiParam(value = "None") @RequestPart(value="callback", required=false) String paramCallback) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity testEnumParameters(@ApiParam(value = "Form parameter enum test (string array)", allowableValues=">, $") @RequestPart(value="enum_form_string_array", required=false) List enumFormStringArray,
+ @ApiParam(value = "Form parameter enum test (string)", allowableValues="_abc, -efg, (xyz)", defaultValue="-efg") @RequestPart(value="enum_form_string", required=false) String enumFormString,
+ @ApiParam(value = "Header parameter enum test (string array)" , allowableValues=">, $") @RequestHeader(value="enum_header_string_array", required=false) Optional> enumHeaderStringArray,
+ @ApiParam(value = "Header parameter enum test (string)" , allowableValues="_abc, -efg, (xyz)", defaultValue="-efg") @RequestHeader(value="enum_header_string", required=false) Optional enumHeaderString,
+ @ApiParam(value = "Query parameter enum test (string array)", allowableValues = ">, $") @RequestParam(value = "enum_query_string_array", required = false) Optional> enumQueryStringArray,
+ @ApiParam(value = "Query parameter enum test (string)", allowableValues = "_abc, -efg, (xyz)", defaultValue = "-efg") @RequestParam(value = "enum_query_string", required = false, defaultValue="-efg") Optional enumQueryString,
+ @ApiParam(value = "Query parameter enum test (double)", allowableValues = "1, -2") @RequestParam(value = "enum_query_integer", required = false) Optional enumQueryInteger,
+ @ApiParam(value = "Query parameter enum test (double)", allowableValues="1.1, -1.2") @RequestPart(value="enum_query_double", required=false) Double enumQueryDouble) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/NotFoundException.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/NotFoundException.java
new file mode 100644
index 00000000000..b28b67ea4b2
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/NotFoundException.java
@@ -0,0 +1,10 @@
+package io.swagger.api;
+
+
+public class NotFoundException extends ApiException {
+ private int code;
+ public NotFoundException (int code, String msg) {
+ super(code, msg);
+ this.code = code;
+ }
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/PetApi.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/PetApi.java
new file mode 100644
index 00000000000..e20c099c8a8
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/PetApi.java
@@ -0,0 +1,157 @@
+/**
+ * NOTE: This class is auto generated by the swagger code generator program (2.2.3-SNAPSHOT).
+ * https://github.com/swagger-api/swagger-codegen
+ * Do not edit the class manually.
+ */
+package io.swagger.api;
+
+import io.swagger.model.ModelApiResponse;
+import io.swagger.model.Pet;
+import org.springframework.core.io.Resource;
+
+import io.swagger.annotations.*;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Optional;
+import javax.validation.constraints.*;
+import javax.validation.Valid;
+
+@Api(value = "pet", description = "the pet API")
+public interface PetApi {
+
+ @ApiOperation(value = "Add a new pet to the store", notes = "", response = Void.class, authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }, tags={ "pet", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 405, message = "Invalid input", response = Void.class) })
+
+ @RequestMapping(value = "/pet",
+ produces = { "application/xml", "application/json" },
+ consumes = { "application/json", "application/xml" },
+ method = RequestMethod.POST)
+ ResponseEntity addPet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @Valid @RequestBody Pet body);
+
+
+ @ApiOperation(value = "Deletes a pet", notes = "", response = Void.class, authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }, tags={ "pet", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid pet value", response = Void.class) })
+
+ @RequestMapping(value = "/pet/{petId}",
+ produces = { "application/xml", "application/json" },
+ method = RequestMethod.DELETE)
+ ResponseEntity deletePet(@ApiParam(value = "Pet id to delete",required=true ) @PathVariable("petId") Long petId,@ApiParam(value = "" ) @RequestHeader(value="api_key", required=false) Optional apiKey);
+
+
+ @ApiOperation(value = "Finds Pets by status", notes = "Multiple status values can be provided with comma separated strings", response = Pet.class, responseContainer = "List", authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }, tags={ "pet", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
+ @ApiResponse(code = 400, message = "Invalid status value", response = Void.class) })
+
+ @RequestMapping(value = "/pet/findByStatus",
+ produces = { "application/xml", "application/json" },
+ method = RequestMethod.GET)
+ ResponseEntity> findPetsByStatus( @NotNull@ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold") @RequestParam(value = "status", required = true) List status);
+
+
+ @ApiOperation(value = "Finds Pets by tags", notes = "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", response = Pet.class, responseContainer = "List", authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }, tags={ "pet", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
+ @ApiResponse(code = 400, message = "Invalid tag value", response = Void.class) })
+
+ @RequestMapping(value = "/pet/findByTags",
+ produces = { "application/xml", "application/json" },
+ method = RequestMethod.GET)
+ ResponseEntity> findPetsByTags( @NotNull@ApiParam(value = "Tags to filter by", required = true) @RequestParam(value = "tags", required = true) List tags);
+
+
+ @ApiOperation(value = "Find pet by ID", notes = "Returns a single pet", response = Pet.class, authorizations = {
+ @Authorization(value = "api_key")
+ }, tags={ "pet", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "successful operation", response = Pet.class),
+ @ApiResponse(code = 400, message = "Invalid ID supplied", response = Void.class),
+ @ApiResponse(code = 404, message = "Pet not found", response = Void.class) })
+
+ @RequestMapping(value = "/pet/{petId}",
+ produces = { "application/xml", "application/json" },
+ method = RequestMethod.GET)
+ ResponseEntity getPetById(@ApiParam(value = "ID of pet to return",required=true ) @PathVariable("petId") Long petId);
+
+
+ @ApiOperation(value = "Update an existing pet", notes = "", response = Void.class, authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }, tags={ "pet", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid ID supplied", response = Void.class),
+ @ApiResponse(code = 404, message = "Pet not found", response = Void.class),
+ @ApiResponse(code = 405, message = "Validation exception", response = Void.class) })
+
+ @RequestMapping(value = "/pet",
+ produces = { "application/xml", "application/json" },
+ consumes = { "application/json", "application/xml" },
+ method = RequestMethod.PUT)
+ ResponseEntity updatePet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @Valid @RequestBody Pet body);
+
+
+ @ApiOperation(value = "Updates a pet in the store with form data", notes = "", response = Void.class, authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }, tags={ "pet", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 405, message = "Invalid input", response = Void.class) })
+
+ @RequestMapping(value = "/pet/{petId}",
+ produces = { "application/xml", "application/json" },
+ consumes = { "application/x-www-form-urlencoded" },
+ method = RequestMethod.POST)
+ ResponseEntity updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated",required=true ) @PathVariable("petId") Long petId,@ApiParam(value = "Updated name of the pet") @RequestPart(value="name", required=false) String name,@ApiParam(value = "Updated status of the pet") @RequestPart(value="status", required=false) String status);
+
+
+ @ApiOperation(value = "uploads an image", notes = "", response = ModelApiResponse.class, authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }, tags={ "pet", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "successful operation", response = ModelApiResponse.class) })
+
+ @RequestMapping(value = "/pet/{petId}/uploadImage",
+ produces = { "application/json" },
+ consumes = { "multipart/form-data" },
+ method = RequestMethod.POST)
+ ResponseEntity uploadFile(@ApiParam(value = "ID of pet to update",required=true ) @PathVariable("petId") Long petId,@ApiParam(value = "Additional data to pass to server") @RequestPart(value="additionalMetadata", required=false) String additionalMetadata,@ApiParam(value = "file detail") @RequestPart("file") MultipartFile file);
+
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/PetApiController.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/PetApiController.java
new file mode 100644
index 00000000000..1d2e53e931b
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/PetApiController.java
@@ -0,0 +1,75 @@
+package io.swagger.api;
+
+import io.swagger.model.ModelApiResponse;
+import io.swagger.model.Pet;
+import org.springframework.core.io.Resource;
+
+import io.swagger.annotations.*;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Optional;
+
+import javax.validation.constraints.*;
+import javax.validation.Valid;
+
+@Controller
+public class PetApiController implements PetApi {
+
+
+
+ public ResponseEntity addPet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @Valid @RequestBody Pet body) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity deletePet(@ApiParam(value = "Pet id to delete",required=true ) @PathVariable("petId") Long petId,
+ @ApiParam(value = "" ) @RequestHeader(value="api_key", required=false) Optional apiKey) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity> findPetsByStatus( @NotNull@ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold") @RequestParam(value = "status", required = true) List status) {
+ // do some magic!
+ return new ResponseEntity>(HttpStatus.OK);
+ }
+
+ public ResponseEntity> findPetsByTags( @NotNull@ApiParam(value = "Tags to filter by", required = true) @RequestParam(value = "tags", required = true) List tags) {
+ // do some magic!
+ return new ResponseEntity>(HttpStatus.OK);
+ }
+
+ public ResponseEntity getPetById(@ApiParam(value = "ID of pet to return",required=true ) @PathVariable("petId") Long petId) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity updatePet(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @Valid @RequestBody Pet body) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity updatePetWithForm(@ApiParam(value = "ID of pet that needs to be updated",required=true ) @PathVariable("petId") Long petId,
+ @ApiParam(value = "Updated name of the pet") @RequestPart(value="name", required=false) String name,
+ @ApiParam(value = "Updated status of the pet") @RequestPart(value="status", required=false) String status) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ public ResponseEntity uploadFile(@ApiParam(value = "ID of pet to update",required=true ) @PathVariable("petId") Long petId,
+ @ApiParam(value = "Additional data to pass to server") @RequestPart(value="additionalMetadata", required=false) String additionalMetadata,
+ @ApiParam(value = "file detail") @RequestPart("file") MultipartFile file) {
+ // do some magic!
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+}
diff --git a/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/StoreApi.java b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/StoreApi.java
new file mode 100644
index 00000000000..380c4e6d1b4
--- /dev/null
+++ b/samples/server/petstore/springboot-useoptional/src/main/java/io/swagger/api/StoreApi.java
@@ -0,0 +1,75 @@
+/**
+ * NOTE: This class is auto generated by the swagger code generator program (2.2.3-SNAPSHOT).
+ * https://github.com/swagger-api/swagger-codegen
+ * Do not edit the class manually.
+ */
+package io.swagger.api;
+
+import java.util.Map;
+import io.swagger.model.Order;
+
+import io.swagger.annotations.*;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.Optional;
+import javax.validation.constraints.*;
+import javax.validation.Valid;
+
+@Api(value = "store", description = "the store API")
+public interface StoreApi {
+
+ @ApiOperation(value = "Delete purchase order by ID", notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", response = Void.class, tags={ "store", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 400, message = "Invalid ID supplied", response = Void.class),
+ @ApiResponse(code = 404, message = "Order not found", response = Void.class) })
+
+ @RequestMapping(value = "/store/order/{order_id}",
+ produces = { "application/xml", "application/json" },
+ method = RequestMethod.DELETE)
+ ResponseEntity deleteOrder(@ApiParam(value = "ID of the order that needs to be deleted",required=true ) @PathVariable("order_id") String orderId);
+
+
+ @ApiOperation(value = "Returns pet inventories by status", notes = "Returns a map of status codes to quantities", response = Integer.class, responseContainer = "Map", authorizations = {
+ @Authorization(value = "api_key")
+ }, tags={ "store", })
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "successful operation", response = Integer.class, responseContainer = "Map") })
+
+ @RequestMapping(value = "/store/inventory",
+ produces = { "application/json" },
+ method = RequestMethod.GET)
+ ResponseEntity