diff --git a/CHANGELOG.md b/CHANGELOG.md
index 511317afd..bde9b2ffe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.6.14] - 2022-12-16
+
+### Added
+
+- #1965 - Prevents premature initialisation of factory-beans
+- #2003 - Resolve property descriptions for arrays
+
+### Changed
+
+- Upgrade spring-boot to 2.7.6
+
+### Fixed
+
+- #1957 - AdditionalModelsConverter Schema params rewriting
+- #1962 - override-with-generic-response shouldn't shallow copy
+- #1985 - IllegalStateException: Duplicate key when two endpoints at the same URL with same header exist
+- #1992 - Java enumeration and Spring Converter no longer generates enum drop-down.
+- #2001 - Enum Collection parameter missing type info in Spring Data Rest search method
+
## [1.6.13] - 2022-11-20
### Added
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index abb9e2846..95b91f24b 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,4 +1,4 @@
-= Contributor Code of Conduct
+## Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open
and welcoming community, we pledge to respect all people who contribute through reporting
@@ -34,6 +34,6 @@ This Code of Conduct applies both within project spaces and in public spaces whe
individual is representing the project or its community.
This Code of Conduct is adapted from the
-https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
-https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/] and https://github.com/spring-projects/spring-boot/blob/master/CODE_OF_CONDUCT.adoc[spring-boot
-Contributor Code of Conduct]
+[Contributor Covenant](https://contributor-covenant.org), version 1.3.0, available at
+[contributor-covenant.org/version/1/3/0/](https://contributor-covenant.org/version/1/3/0/) and [spring-boot
+Contributor Code of Conduct](https://github.com/spring-projects/spring-boot/blob/master/CODE_OF_CONDUCT.adoc)
diff --git a/README.md b/README.md
index bc44c7a0d..6884eb746 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,8 @@ This library supports:
* Swagger-ui
* Oauth 2
+For *spring-boot v3* support, make sure you use [springdoc-openapi v2](https://springdoc.org/v2)
+
The following video introduces the Library:
* [https://youtu.be/utRxyPfFlDw](https://youtu.be/utRxyPfFlDw)
@@ -78,8 +80,8 @@ Pivotal)
* Automatically deploys swagger-ui to a Spring Boot 2.x application
* Documentation will be available in HTML format, using the
official [swagger-ui jars](https://github.com/swagger-api/swagger-ui.git).
-* The Swagger UI page should then be available at http://server:
- port/context-path/swagger-ui.html and the OpenAPI description will be available at the
+* The Swagger UI page should then be available at
+http://server:port/context-path/swagger-ui.html and the OpenAPI description will be available at the
following url for json format: http://server:port/context-path/v3/api-docs
* `server`: The server name or IP
* `port`: The server port
@@ -123,8 +125,7 @@ springdoc.swagger-ui.path=/swagger-ui.html
## Integration of the library in a Spring Boot 2.x.x project without the swagger-ui:
-* Documentation will be available at the following url for json format: http://server:
- port/context-path/v3/api-docs
+* Documentation will be available at the following url for json format: http://server:port/context-path/v3/api-docs
* `server`: The server name or IP
* `port`: The server port
* `context-path`: The context path of the application
@@ -218,7 +219,7 @@ its [contributors](https://github.com/springdoc/springdoc-openapi/graphs/contrib
-Thanks you all for your support!
+Thank you all for your support!
## Additional Support
diff --git a/SECURITY.md b/SECURITY.md
index 0099d9342..a92ff7b6e 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -8,7 +8,7 @@
## Reporting a Vulnerability
-If you think you have found a security vulnerability in Spring Boot please *DO NOT*
+If you think you have found a security vulnerability in springdoc-openapi please *DO NOT*
disclose it publicly until we've had a chance to fix it. Please don't report security
vulnerabilities using GitHub issues, instead head over to support@springdoc.org and
learn how to disclose them responsibly.
diff --git a/pom.xml b/pom.xml
index 2642716e6..ed611b0dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
org.springdoc
springdoc-openapi
- 1.6.13
+ 1.6.14
pom
Spring openapi documentation
Spring openapi documentation
@@ -11,7 +11,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.7.5
+ 2.7.6
@@ -36,7 +36,7 @@
scm:git:git@github.com:springdoc/springdoc-openapi.git
scm:git:git@github.com:springdoc/springdoc-openapi.git
- v1.6.13
+ v1.6.14
diff --git a/springdoc-openapi-common/pom.xml b/springdoc-openapi-common/pom.xml
index 8a73325df..de2cd69ce 100644
--- a/springdoc-openapi-common/pom.xml
+++ b/springdoc-openapi-common/pom.xml
@@ -3,7 +3,7 @@
org.springdoc
springdoc-openapi
- 1.6.13
+ 1.6.14
springdoc-openapi-common
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java
index 6cb33ab86..a81fca353 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java
@@ -1050,7 +1050,15 @@ private void fillParametersList(Operation operation, Map queryPa
if (parametersList == null)
parametersList = new ArrayList<>();
Collection headersMap = AbstractRequestService.getHeaders(methodAttributes, new LinkedHashMap<>());
- parametersList.addAll(headersMap);
+ headersMap.forEach(parameter -> {
+ Optional existingParam;
+ if (!CollectionUtils.isEmpty(operation.getParameters())){
+ existingParam = operation.getParameters().stream().filter(p -> parameter.getName().equals(p.getName())).findAny();
+ if (!existingParam.isPresent())
+ operation.addParametersItem(parameter);
+ }
+ });
+
if (!CollectionUtils.isEmpty(queryParams)) {
for (Map.Entry entry : queryParams.entrySet()) {
io.swagger.v3.oas.models.parameters.Parameter parameter = new io.swagger.v3.oas.models.parameters.Parameter();
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterService.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterService.java
index 2ec295e4a..c4192f5c7 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterService.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterService.java
@@ -78,6 +78,7 @@
/**
* The type Generic parameter builder.
+ *
* @author bnasslahsen, coutin
*/
@SuppressWarnings("rawtypes")
@@ -355,8 +356,11 @@ Schema calculateSchema(Components components, ParameterInfo parameterInfo, Reque
Type type = ReturnTypeParser.getType(methodParameter);
if (type instanceof Class && optionalWebConversionServiceProvider.isPresent()) {
WebConversionServiceProvider webConversionServiceProvider = optionalWebConversionServiceProvider.get();
- if (!MethodParameterPojoExtractor.isSwaggerPrimitiveType((Class) type) && methodParameter.getParameterType().getAnnotation(io.swagger.v3.oas.annotations.media.Schema.class) == null)
- type = webConversionServiceProvider.getSpringConvertedType(methodParameter.getParameterType());
+ if (!MethodParameterPojoExtractor.isSwaggerPrimitiveType((Class) type) && methodParameter.getParameterType().getAnnotation(io.swagger.v3.oas.annotations.media.Schema.class) == null) {
+ Class> springConvertedType = webConversionServiceProvider.getSpringConvertedType(methodParameter.getParameterType());
+ if (!(String.class.equals(springConvertedType) && ((Class>) type).isEnum()))
+ type = springConvertedType;
+ }
}
schemaN = SpringDocAnnotationsUtils.extractSchema(components, type, jsonView, methodParameter.getParameterAnnotations());
}
@@ -569,6 +573,7 @@ public Optional getOptionalWebConversionServicePro
/**
* Resolve the given annotation-specified value,
* potentially containing placeholders and expressions.
+ *
* @param value the value
* @return the object
*/
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java
index 26c8c0f3b..b39a5dc82 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java
@@ -29,6 +29,7 @@
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@@ -41,6 +42,8 @@
import java.util.stream.Stream;
import com.fasterxml.jackson.annotation.JsonView;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.core.util.AnnotationsUtils;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.Operation;
@@ -50,7 +53,10 @@
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springdoc.core.providers.JavadocProvider;
+import org.springdoc.core.providers.ObjectMapperProvider;
import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType;
@@ -74,6 +80,7 @@
/**
* The type Generic response builder.
+ *
* @author bnasslahsen
*/
public class GenericResponseService {
@@ -118,6 +125,11 @@ public class GenericResponseService {
*/
private final List controllerAdviceInfos = new ArrayList<>();
+ /**
+ * The constant LOGGER.
+ */
+ private static final Logger LOGGER = LoggerFactory.getLogger(GenericResponseService.class);
+
/**
* Instantiates a new Generic response builder.
*
@@ -242,9 +254,9 @@ private Map filterAndEnrichGenericMapResponseByDeclarations
JavadocProvider javadocProvider = operationService.getJavadocProvider();
for (Map.Entry genericResponse : genericMapResponse.entrySet()) {
Map extensions = genericResponse.getValue().getExtensions();
- Set> genericExceptions = (Set>) extensions.get(EXTENSION_EXCEPTION_CLASSES);
+ Collection genericExceptions = (Collection) extensions.get(EXTENSION_EXCEPTION_CLASSES);
for (Class> declaredException : handlerMethod.getMethod().getExceptionTypes()) {
- if (genericExceptions.contains(declaredException)) {
+ if (genericExceptions.contains(declaredException.getName())) {
Map javadocThrows = javadocProvider.getMethodJavadocThrows(handlerMethod.getMethod());
String description = javadocThrows.get(declaredException.getName());
if (description == null)
@@ -675,7 +687,16 @@ private synchronized Map getGenericMapResponse(Class> bea
});
}
- return genericApiResponseMap;
+ LinkedHashMap genericApiResponsesClone;
+ try {
+ ObjectMapper objectMapper = ObjectMapperProvider.createJson(springDocConfigProperties);
+ genericApiResponsesClone = objectMapper.readValue(objectMapper.writeValueAsString(genericApiResponseMap), ApiResponses.class);
+ return genericApiResponsesClone;
+ }
+ catch (JsonProcessingException e) {
+ LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage());
+ return genericApiResponseMap;
+ }
}
/**
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/MethodAttributes.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/MethodAttributes.java
index ab7dffaa4..0741eb1d3 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/MethodAttributes.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/MethodAttributes.java
@@ -31,6 +31,7 @@
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.util.CollectionUtils;
@@ -385,9 +386,16 @@ public Map getHeaders() {
private void setHeaders(String[] headers) {
if (ArrayUtils.isNotEmpty(headers))
for (String header : headers) {
- String[] keyValueHeader = header.split("=");
- String headerValue = keyValueHeader.length > 1 ? keyValueHeader[1] : "";
- this.headers.put(keyValueHeader[0], headerValue);
+ if (!header.contains("!=")) {
+ String[] keyValueHeader = header.split("=");
+ String headerValue = keyValueHeader.length > 1 ? keyValueHeader[1] : "";
+ this.headers.put(keyValueHeader[0], headerValue);
+ }
+ else {
+ String[] keyValueHeader = header.split("!=");
+ if (!this.headers.containsKey(keyValueHeader[0]))
+ this.headers.put(keyValueHeader[0], StringUtils.EMPTY);
+ }
}
}
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/MultipleOpenApiGroupsCondition.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/MultipleOpenApiGroupsCondition.java
index 0210f6db8..fa5ec7853 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/MultipleOpenApiGroupsCondition.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/MultipleOpenApiGroupsCondition.java
@@ -22,8 +22,6 @@
package org.springdoc.core;
-import java.util.Collection;
-
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/PropertyResolverUtils.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/PropertyResolverUtils.java
index 97c4bcc5c..a1b6db47b 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/PropertyResolverUtils.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/PropertyResolverUtils.java
@@ -34,6 +34,7 @@
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.servers.Server;
import org.apache.commons.lang3.StringUtils;
@@ -174,6 +175,10 @@ public Schema resolveProperties(Schema> schema, Locale locale) {
if (!CollectionUtils.isEmpty(properties)) {
LinkedHashMap resolvedSchemas = properties.entrySet().stream().map(es -> {
es.setValue(resolveProperties(es.getValue(), locale));
+ if(es.getValue() instanceof ArraySchema){
+ ArraySchema arraySchema = (ArraySchema) es.getValue();
+ resolveProperties(arraySchema.getItems(), locale);
+ }
return es;
}).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e2,
LinkedHashMap::new));
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocUtils.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocUtils.java
index 0a05f9542..b657e0cba 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocUtils.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocUtils.java
@@ -33,6 +33,7 @@
/**
* The type Spring doc utils.
+ *
* @author bnasslahsen
*/
public class SpringDocUtils {
@@ -323,5 +324,27 @@ public SpringDocUtils setModelAndViewClass(Class> clazz) {
AbstractOpenApiResource.setModelAndViewClass(clazz);
return this;
}
+
+ /**
+ * Remove from schema map spring doc utils.
+ *
+ * @param clazzs the clazzs
+ * @return the spring doc utils
+ */
+ public SpringDocUtils removeFromSchemaMap(Class> clazzs) {
+ AdditionalModelsConverter.removeFromSchemaMap(clazzs);
+ return this;
+ }
+
+ /**
+ * Remove from schema class spring doc utils.
+ *
+ * @param clazzs the clazzs
+ * @return the spring doc utils
+ */
+ public SpringDocUtils removeFromSchemaClass(Class> clazzs) {
+ AdditionalModelsConverter.removeFromClassMap(clazzs);
+ return this;
+ }
}
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocBeanFactoryConfigurer.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocBeanFactoryConfigurer.java
index ae1e6ed6c..63a304a8d 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocBeanFactoryConfigurer.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocBeanFactoryConfigurer.java
@@ -58,9 +58,9 @@ public class SpringdocBeanFactoryConfigurer implements EnvironmentAware, BeanFac
* @param beanFactory the bean factory
*/
public static void initBeanFactoryPostProcessor(ConfigurableListableBeanFactory beanFactory) {
- for (String beanName : beanFactory.getBeanNamesForType(OpenAPIService.class))
+ for (String beanName : beanFactory.getBeanNamesForType(OpenAPIService.class, true, false))
beanFactory.getBeanDefinition(beanName).setScope(SCOPE_PROTOTYPE);
- for (String beanName : beanFactory.getBeanNamesForType(OpenAPI.class))
+ for (String beanName : beanFactory.getBeanNamesForType(OpenAPI.class, true, false))
beanFactory.getBeanDefinition(beanName).setScope(SCOPE_PROTOTYPE);
}
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java
index 617a22ee1..a2e8fbc18 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java
@@ -26,15 +26,20 @@
import java.util.Iterator;
import java.util.Map;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import io.swagger.v3.core.converter.AnnotatedType;
import io.swagger.v3.core.converter.ModelConverter;
import io.swagger.v3.core.converter.ModelConverterContext;
import io.swagger.v3.oas.models.media.Schema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springdoc.core.providers.ObjectMapperProvider;
/**
* The type Additional models converter.
+ *
* @author bnasslahsen
*/
public class AdditionalModelsConverter implements ModelConverter {
@@ -42,18 +47,23 @@ public class AdditionalModelsConverter implements ModelConverter {
/**
* The constant modelToClassMap.
*/
- private static final Map modelToClassMap = new HashMap<>();
+ private static Map modelToClassMap = new HashMap<>();
/**
* The constant modelToSchemaMap.
*/
- private static final Map modelToSchemaMap = new HashMap<>();
+ private static Map modelToSchemaMap = new HashMap<>();
/**
* The constant paramObjectReplacementMap.
*/
private static final Map paramObjectReplacementMap = new HashMap<>();
+ /**
+ * The constant LOGGER.
+ */
+ private static final Logger LOGGER = LoggerFactory.getLogger(AdditionalModelsConverter.class);
+
/**
* The Spring doc object mapper.
*/
@@ -130,12 +140,36 @@ public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterato
JavaType javaType = springDocObjectMapper.jsonMapper().constructType(type.getType());
if (javaType != null) {
Class> cls = javaType.getRawClass();
- if (modelToSchemaMap.containsKey(cls))
- return modelToSchemaMap.get(cls);
+ if (modelToSchemaMap.containsKey(cls)) {
+ try {
+ return springDocObjectMapper.jsonMapper()
+ .readValue(springDocObjectMapper.jsonMapper().writeValueAsString(modelToSchemaMap.get(cls)), new TypeReference() {});
+ }
+ catch (JsonProcessingException e) {
+ LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage());
+ }
+ }
if (modelToClassMap.containsKey(cls))
type = new AnnotatedType(modelToClassMap.get(cls)).resolveAsRef(true);
}
return (chain.hasNext()) ? chain.next().resolve(type, context, chain) : null;
}
+ /**
+ * Remove from schema map.
+ *
+ * @param clazz the clazz
+ */
+ public static void removeFromSchemaMap(Class clazz) {
+ modelToSchemaMap.remove(clazz);
+ }
+
+ /**
+ * Remove from class map.
+ *
+ * @param clazz the clazz
+ */
+ public static void removeFromClassMap(Class clazz) {
+ modelToClassMap.remove(clazz);
+ }
}
\ No newline at end of file
diff --git a/springdoc-openapi-data-rest/pom.xml b/springdoc-openapi-data-rest/pom.xml
index e45500021..88277af6e 100644
--- a/springdoc-openapi-data-rest/pom.xml
+++ b/springdoc-openapi-data-rest/pom.xml
@@ -4,7 +4,7 @@
springdoc-openapi
org.springdoc
- 1.6.13
+ 1.6.14
springdoc-openapi-data-rest
diff --git a/springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestOperationService.java b/springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestOperationService.java
index 9998cc832..8576fe1a3 100644
--- a/springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestOperationService.java
+++ b/springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestOperationService.java
@@ -24,6 +24,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.util.Arrays;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
@@ -39,6 +40,7 @@
import org.springdoc.core.SpringDocAnnotationsUtils;
import org.springframework.core.MethodParameter;
+import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.mapping.MethodResourceMapping;
@@ -54,6 +56,7 @@
/**
* The type Data rest operation builder.
+ *
* @author bnasslahsen
*/
public class DataRestOperationService {
@@ -202,17 +205,8 @@ private Operation buildSearchOperation(HandlerMethod handlerMethod, DataRestRepo
String pName = parameterMetadatum.getName();
ResourceDescription description = parameterMetadatum.getDescription();
if (description instanceof TypedResourceDescription) {
- TypedResourceDescription typedResourceDescription = (TypedResourceDescription) description;
- Field fieldType = FieldUtils.getField(TypedResourceDescription.class, "type", true);
- Class> type;
- try {
- type = (Class>) fieldType.get(typedResourceDescription);
- }
- catch (IllegalAccessException e) {
- LOGGER.warn(e.getMessage());
- type = String.class;
- }
- Schema> schema = SpringDocAnnotationsUtils.resolveSchemaFromType(type, openAPI.getComponents(), null, null);
+ Type type = getParameterType(pName,method,description);
+ Schema> schema = SpringDocAnnotationsUtils.extractSchema(openAPI.getComponents(), type, null, null);
Parameter parameter = getParameterFromAnnotations(openAPI, methodAttributes, method, pName);
if (parameter == null)
parameter = new Parameter().name(pName).in(ParameterIn.QUERY.toString()).schema(schema);
@@ -231,6 +225,39 @@ private Operation buildSearchOperation(HandlerMethod handlerMethod, DataRestRepo
return operation;
}
+ /**
+ * Gets parameter type.
+ *
+ * @param pName the p name
+ * @param method the method
+ * @param description the description
+ * @return the parameter type
+ */
+ private Type getParameterType(String pName, Method method, ResourceDescription description) {
+ Type type = null;
+ java.lang.reflect.Parameter[] parameters = method.getParameters();
+ for (int i = 0; i < parameters.length; i++) {
+ java.lang.reflect.Parameter parameter = parameters[i];
+ if (pName.equals(parameter.getName()) || pName.equals(parameter.getAnnotation(Param.class).value())) {
+ ResolvableType resolvableType = ResolvableType.forMethodParameter(method, i);
+ type = resolvableType.getType();
+ break;
+ }
+ }
+ if (type == null) {
+ TypedResourceDescription typedResourceDescription = (TypedResourceDescription) description;
+ Field fieldType = FieldUtils.getField(TypedResourceDescription.class, "type", true);
+ try {
+ type = (Type) fieldType.get(typedResourceDescription);
+ }
+ catch (IllegalAccessException e) {
+ LOGGER.warn(e.getMessage());
+ type = String.class;
+ }
+ }
+ return type;
+ }
+
/**
* Update parameter from annotations parameter.
*
@@ -279,6 +306,7 @@ private Operation initOperation(HandlerMethod handlerMethod, Class> domainType
/**
* Add operation description.
+ *
* @param operation the operation
* @param requestMethod the request method
* @param entity the entity
diff --git a/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/EnumFieldHolder.java b/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/EnumFieldHolder.java
new file mode 100644
index 000000000..1354beb6f
--- /dev/null
+++ b/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/EnumFieldHolder.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * * Copyright 2019-2022 the original author or authors.
+ * *
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * https://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ *
+ */
+
+package test.org.springdoc.api.app36;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class EnumFieldHolder {
+
+ public enum EnumField {
+
+ FOO, BAR;
+
+ }
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ private EnumField enumField;
+
+ public Long getId() {
+ return id;
+ }
+
+ public EnumField getEnumField() {
+ return enumField;
+ }
+
+ public void setEnumField(EnumField enumField) {
+ this.enumField = enumField;
+ }
+
+}
diff --git a/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/EnumFieldHolderRepository.java b/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/EnumFieldHolderRepository.java
new file mode 100644
index 000000000..88a2b518d
--- /dev/null
+++ b/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/EnumFieldHolderRepository.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * * Copyright 2019-2022 the original author or authors.
+ * *
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * https://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ *
+ */
+
+package test.org.springdoc.api.app36;
+
+import java.util.List;
+
+import org.springframework.data.repository.Repository;
+import org.springframework.data.repository.query.Param;
+import org.springframework.data.rest.core.annotation.RepositoryRestResource;
+import org.springframework.data.util.Streamable;
+
+@RepositoryRestResource
+public interface EnumFieldHolderRepository extends Repository {
+
+ Streamable findAllByEnumField(@Param("enumField") EnumFieldHolder.EnumField enumField);
+
+ Streamable findAllByEnumFieldIn(@Param("enumFields") List enumFields);
+
+}
diff --git a/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/SpringDocApp36Test.java b/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/SpringDocApp36Test.java
new file mode 100644
index 000000000..4bef9476f
--- /dev/null
+++ b/springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app36/SpringDocApp36Test.java
@@ -0,0 +1,32 @@
+/*
+ *
+ * * Copyright 2019-2022 the original author or authors.
+ * *
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * https://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ *
+ */
+
+package test.org.springdoc.api.app36;
+
+import test.org.springdoc.api.AbstractSpringDocTest;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+public class SpringDocApp36Test extends AbstractSpringDocTest {
+
+ @SpringBootApplication
+ static class SpringDocTestApp {
+
+ }
+
+}
diff --git a/springdoc-openapi-data-rest/src/test/resources/results/app36.json b/springdoc-openapi-data-rest/src/test/resources/results/app36.json
new file mode 100644
index 000000000..3aabae473
--- /dev/null
+++ b/springdoc-openapi-data-rest/src/test/resources/results/app36.json
@@ -0,0 +1,167 @@
+{
+ "openapi": "3.0.1",
+ "info": {
+ "title": "OpenAPI definition",
+ "version": "v0"
+ },
+ "servers": [
+ {
+ "url": "http://localhost",
+ "description": "Generated server url"
+ }
+ ],
+ "paths": {
+ "/enumFieldHolders/search/findAllByEnumField": {
+ "get": {
+ "tags": [
+ "enum-field-holder-search-controller"
+ ],
+ "operationId": "executeSearch-enumfieldholder-get",
+ "parameters": [
+ {
+ "name": "enumField",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "FOO",
+ "BAR"
+ ]
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/hal+json": {
+ "schema": {
+ "$ref": "#/components/schemas/CollectionModelEntityModelEnumFieldHolder"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found"
+ }
+ }
+ }
+ },
+ "/enumFieldHolders/search/findAllByEnumFieldIn": {
+ "get": {
+ "tags": [
+ "enum-field-holder-search-controller"
+ ],
+ "operationId": "executeSearch-enumfieldholder-get_1",
+ "parameters": [
+ {
+ "name": "enumFields",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "FOO",
+ "BAR"
+ ]
+ }
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/hal+json": {
+ "schema": {
+ "$ref": "#/components/schemas/CollectionModelEntityModelEnumFieldHolder"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found"
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "CollectionModelEntityModelEnumFieldHolder": {
+ "type": "object",
+ "properties": {
+ "_embedded": {
+ "type": "object",
+ "properties": {
+ "enumFieldHolders": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/EntityModelEnumFieldHolder"
+ }
+ }
+ }
+ },
+ "_links": {
+ "$ref": "#/components/schemas/Links"
+ }
+ }
+ },
+ "EntityModelEnumFieldHolder": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "enumField": {
+ "type": "string",
+ "enum": [
+ "FOO",
+ "BAR"
+ ]
+ },
+ "_links": {
+ "$ref": "#/components/schemas/Links"
+ }
+ }
+ },
+ "Link": {
+ "type": "object",
+ "properties": {
+ "deprecation": {
+ "type": "string"
+ },
+ "href": {
+ "type": "string"
+ },
+ "hreflang": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "profile": {
+ "type": "string"
+ },
+ "templated": {
+ "type": "boolean"
+ },
+ "title": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "Links": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/Link"
+ }
+ }
+ }
+ }
+}
diff --git a/springdoc-openapi-groovy/pom.xml b/springdoc-openapi-groovy/pom.xml
index e7470a05e..ef1ebec50 100644
--- a/springdoc-openapi-groovy/pom.xml
+++ b/springdoc-openapi-groovy/pom.xml
@@ -4,7 +4,7 @@
springdoc-openapi
org.springdoc
- 1.6.13
+ 1.6.14
springdoc-openapi-groovy
diff --git a/springdoc-openapi-hateoas/pom.xml b/springdoc-openapi-hateoas/pom.xml
index 0d417bf83..c3d827bcc 100644
--- a/springdoc-openapi-hateoas/pom.xml
+++ b/springdoc-openapi-hateoas/pom.xml
@@ -4,7 +4,7 @@
springdoc-openapi
org.springdoc
- 1.6.13
+ 1.6.14
springdoc-openapi-hateoas
diff --git a/springdoc-openapi-javadoc/pom.xml b/springdoc-openapi-javadoc/pom.xml
index df56e2718..fa6c32152 100644
--- a/springdoc-openapi-javadoc/pom.xml
+++ b/springdoc-openapi-javadoc/pom.xml
@@ -3,7 +3,7 @@
springdoc-openapi
org.springdoc
- 1.6.13
+ 1.6.14
4.0.0
diff --git a/springdoc-openapi-javadoc/src/test/resources/results/app162.json b/springdoc-openapi-javadoc/src/test/resources/results/app162.json
index 885ee8568..bd5968cda 100644
--- a/springdoc-openapi-javadoc/src/test/resources/results/app162.json
+++ b/springdoc-openapi-javadoc/src/test/resources/results/app162.json
@@ -38,8 +38,8 @@
}
],
"responses": {
- "400": {
- "description": "the @throws NonUniqueResultException javadoc for the #findStartsBy(String) method",
+ "404": {
+ "description": "the @throws NoResultException javadoc for the #find(String) method",
"content": {
"*/*": {
"schema": {
@@ -48,11 +48,11 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NonUniqueResultException"
+ "test.org.springdoc.api.app162.exception.NoResultException"
]
},
- "404": {
- "description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
+ "400": {
+ "description": "the return javadoc for the #handleNonUniqueResultException(NonUniqueResultException) method",
"content": {
"*/*": {
"schema": {
@@ -61,7 +61,7 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NoResultException"
+ "test.org.springdoc.api.app162.exception.NonUniqueResultException"
]
},
"200": {
@@ -105,8 +105,8 @@
"required": true
},
"responses": {
- "400": {
- "description": "the @throws NonUniqueResultException javadoc for the #findStartsBy(String) method",
+ "404": {
+ "description": "the return javadoc for the #handleNotFoundException(NoResultException) method",
"content": {
"*/*": {
"schema": {
@@ -115,11 +115,11 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NonUniqueResultException"
+ "test.org.springdoc.api.app162.exception.NoResultException"
]
},
- "404": {
- "description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
+ "400": {
+ "description": "the return javadoc for the #handleNonUniqueResultException(NonUniqueResultException) method",
"content": {
"*/*": {
"schema": {
@@ -128,7 +128,7 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NoResultException"
+ "test.org.springdoc.api.app162.exception.NonUniqueResultException"
]
},
"200": {
@@ -153,8 +153,8 @@
"description": "This is the list method's javadoc.\n The method's signature: #list()",
"operationId": "list",
"responses": {
- "400": {
- "description": "the @throws NonUniqueResultException javadoc for the #findStartsBy(String) method",
+ "404": {
+ "description": "the return javadoc for the #handleNotFoundException(NoResultException) method",
"content": {
"*/*": {
"schema": {
@@ -163,11 +163,11 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NonUniqueResultException"
+ "test.org.springdoc.api.app162.exception.NoResultException"
]
},
- "404": {
- "description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
+ "400": {
+ "description": "the return javadoc for the #handleNonUniqueResultException(NonUniqueResultException) method",
"content": {
"*/*": {
"schema": {
@@ -176,7 +176,7 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NoResultException"
+ "test.org.springdoc.api.app162.exception.NonUniqueResultException"
]
},
"200": {
@@ -213,8 +213,8 @@
"required": true
},
"responses": {
- "400": {
- "description": "the @throws NonUniqueResultException javadoc for the #findStartsBy(String) method",
+ "404": {
+ "description": "the return javadoc for the #handleNotFoundException(NoResultException) method",
"content": {
"*/*": {
"schema": {
@@ -223,11 +223,11 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NonUniqueResultException"
+ "test.org.springdoc.api.app162.exception.NoResultException"
]
},
- "404": {
- "description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
+ "400": {
+ "description": "the return javadoc for the #handleNonUniqueResultException(NonUniqueResultException) method",
"content": {
"*/*": {
"schema": {
@@ -236,7 +236,7 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NoResultException"
+ "test.org.springdoc.api.app162.exception.NonUniqueResultException"
]
},
"201": {
@@ -272,8 +272,8 @@
}
],
"responses": {
- "400": {
- "description": "the @throws NonUniqueResultException javadoc for the #findStartsBy(String) method",
+ "404": {
+ "description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
"content": {
"*/*": {
"schema": {
@@ -282,11 +282,11 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NonUniqueResultException"
+ "test.org.springdoc.api.app162.exception.NoResultException"
]
},
- "404": {
- "description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
+ "400": {
+ "description": "the @throws NonUniqueResultException javadoc for the #findStartsBy(String) method",
"content": {
"*/*": {
"schema": {
@@ -295,7 +295,7 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app162.exception.NoResultException"
+ "test.org.springdoc.api.app162.exception.NonUniqueResultException"
]
},
"200": {
diff --git a/springdoc-openapi-javadoc/src/test/resources/results/app163.json b/springdoc-openapi-javadoc/src/test/resources/results/app163.json
index 913041c3a..da02ff9bc 100644
--- a/springdoc-openapi-javadoc/src/test/resources/results/app163.json
+++ b/springdoc-openapi-javadoc/src/test/resources/results/app163.json
@@ -48,8 +48,8 @@
"required": true
},
"responses": {
- "400": {
- "description": "the @throws NonUniqueResultException javadoc for the #findStartsBy(String) method",
+ "404": {
+ "description": "the return javadoc for the #handleNotFoundException(NoResultException) method",
"content": {
"*/*": {
"schema": {
@@ -58,11 +58,11 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app163.exception.NonUniqueResultException"
+ "test.org.springdoc.api.app163.exception.NoResultException"
]
},
- "404": {
- "description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
+ "400": {
+ "description": "the return javadoc for the #handleNonUniqueResultException(NonUniqueResultException) method",
"content": {
"*/*": {
"schema": {
@@ -71,7 +71,7 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app163.exception.NoResultException"
+ "test.org.springdoc.api.app163.exception.NonUniqueResultException"
]
},
"200": {
@@ -107,8 +107,8 @@
"required": true
},
"responses": {
- "400": {
- "description": "the @throws NonUniqueResultException javadoc for the #findStartsBy(String) method",
+ "404": {
+ "description": "the return javadoc for the #handleNotFoundException(NoResultException) method",
"content": {
"*/*": {
"schema": {
@@ -117,11 +117,11 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app163.exception.NonUniqueResultException"
+ "test.org.springdoc.api.app163.exception.NoResultException"
]
},
- "404": {
- "description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
+ "400": {
+ "description": "the return javadoc for the #handleNonUniqueResultException(NonUniqueResultException) method",
"content": {
"*/*": {
"schema": {
@@ -130,7 +130,7 @@
}
},
"x-exception-class": [
- "test.org.springdoc.api.app163.exception.NoResultException"
+ "test.org.springdoc.api.app163.exception.NonUniqueResultException"
]
},
"default": {
@@ -166,9 +166,6 @@
}
],
"responses": {
- "400": {
- "description": "API Response 400 for #findStartsBy(prefix)"
- },
"404": {
"description": "the @throws NoResultException javadoc for the #findStartsBy(String) method",
"content": {
@@ -182,6 +179,9 @@
"test.org.springdoc.api.app163.exception.NoResultException"
]
},
+ "400": {
+ "description": "API Response 400 for #findStartsBy(prefix)"
+ },
"200": {
"description": "API Response 200 for #findStartsBy(prefix)",
"content": {
diff --git a/springdoc-openapi-kotlin/pom.xml b/springdoc-openapi-kotlin/pom.xml
index dee6479ad..2790cb410 100644
--- a/springdoc-openapi-kotlin/pom.xml
+++ b/springdoc-openapi-kotlin/pom.xml
@@ -3,7 +3,7 @@
org.springdoc
springdoc-openapi
- 1.6.13
+ 1.6.14
5.3.6
diff --git a/springdoc-openapi-native/pom.xml b/springdoc-openapi-native/pom.xml
index c9975210b..5fb01b5fe 100644
--- a/springdoc-openapi-native/pom.xml
+++ b/springdoc-openapi-native/pom.xml
@@ -3,7 +3,7 @@
springdoc-openapi
org.springdoc
- 1.6.13
+ 1.6.14
4.0.0
diff --git a/springdoc-openapi-security/pom.xml b/springdoc-openapi-security/pom.xml
index 0d61eae9f..e52614115 100644
--- a/springdoc-openapi-security/pom.xml
+++ b/springdoc-openapi-security/pom.xml
@@ -4,7 +4,7 @@
springdoc-openapi
org.springdoc
- 1.6.13
+ 1.6.14
springdoc-openapi-security
diff --git a/springdoc-openapi-ui/pom.xml b/springdoc-openapi-ui/pom.xml
index 548eb9f34..b758353c8 100644
--- a/springdoc-openapi-ui/pom.xml
+++ b/springdoc-openapi-ui/pom.xml
@@ -3,7 +3,7 @@
org.springdoc
springdoc-openapi
- 1.6.13
+ 1.6.14
springdoc-openapi-ui
diff --git a/springdoc-openapi-webflux-core/pom.xml b/springdoc-openapi-webflux-core/pom.xml
index 72237f186..1b755fb74 100644
--- a/springdoc-openapi-webflux-core/pom.xml
+++ b/springdoc-openapi-webflux-core/pom.xml
@@ -3,7 +3,7 @@
org.springdoc
springdoc-openapi
- 1.6.13
+ 1.6.14
springdoc-openapi-webflux-core
diff --git a/springdoc-openapi-webflux-ui/pom.xml b/springdoc-openapi-webflux-ui/pom.xml
index 7ae3267d0..294cb4143 100644
--- a/springdoc-openapi-webflux-ui/pom.xml
+++ b/springdoc-openapi-webflux-ui/pom.xml
@@ -3,7 +3,7 @@
org.springdoc
springdoc-openapi
- 1.6.13
+ 1.6.14
springdoc-openapi-webflux-ui
diff --git a/springdoc-openapi-webmvc-core/pom.xml b/springdoc-openapi-webmvc-core/pom.xml
index 9192e5917..173705224 100644
--- a/springdoc-openapi-webmvc-core/pom.xml
+++ b/springdoc-openapi-webmvc-core/pom.xml
@@ -3,7 +3,7 @@
org.springdoc
springdoc-openapi
- 1.6.13
+ 1.6.14
springdoc-openapi-webmvc-core
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app114/SpringDocApp114Test.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app114/SpringDocApp114Test.java
index 47b6bb07c..5144735c1 100644
--- a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app114/SpringDocApp114Test.java
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app114/SpringDocApp114Test.java
@@ -22,6 +22,8 @@
package test.org.springdoc.api.v30.app114;
+import java.math.BigDecimal;
+
import javax.money.MonetaryAmount;
import org.springdoc.core.SpringDocUtils;
@@ -33,7 +35,9 @@
public class SpringDocApp114Test extends AbstractSpringDocV30Test {
static {
- SpringDocUtils.getConfig().replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class);
+ SpringDocUtils.getConfig()
+ .removeFromSchemaMap(BigDecimal.class)
+ .replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class);
}
@SpringBootApplication
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app164/SampleResponseClass.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app164/SampleResponseClass.java
index ecc647772..e72141e1f 100644
--- a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app164/SampleResponseClass.java
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app164/SampleResponseClass.java
@@ -22,6 +22,11 @@
package test.org.springdoc.api.v30.app164;
+import java.util.List;
+
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Schema;
+
public class SampleResponseClass {
private String idAsFirstParameter;
@@ -32,6 +37,18 @@ public class SampleResponseClass {
private boolean booleanValueAsFourthParameter;
+ @ArraySchema( arraySchema = @Schema( description = "${blahDescription.value}" ),
+ schema = @Schema( description = "${blahDescription.value}" ) )
+ private List listBlah;
+
+ public List getListBlah() {
+ return listBlah;
+ }
+
+ public void setListBlah(List listBlah) {
+ this.listBlah = listBlah;
+ }
+
public String getIdAsFirstParameter() {
return idAsFirstParameter;
}
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/HelloController.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/HelloController.java
new file mode 100644
index 000000000..6b7b19591
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/HelloController.java
@@ -0,0 +1,15 @@
+package test.org.springdoc.api.v30.app198;
+
+import java.math.BigDecimal;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController("/")
+public class HelloController {
+
+ @GetMapping
+ public Response test() {
+ return new Response(BigDecimal.ONE, BigDecimal.ONE, BigDecimal.ONE);
+ }
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/Response.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/Response.java
new file mode 100644
index 000000000..feb9159be
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/Response.java
@@ -0,0 +1,49 @@
+package test.org.springdoc.api.v30.app198;
+
+import java.math.BigDecimal;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+/**
+ * @author bnasslahsen
+ */
+public class Response {
+
+ public Response(BigDecimal val1, BigDecimal val2, BigDecimal val3) {
+ this.val1 = val1;
+ this.val2 = val2;
+ this.val3 = val3;
+ }
+
+ @Schema(deprecated = true)
+ @Deprecated
+ private BigDecimal val1;
+
+ private BigDecimal val2;
+
+ private BigDecimal val3;
+
+ public BigDecimal getVal1() {
+ return val1;
+ }
+
+ public void setVal1(BigDecimal val1) {
+ this.val1 = val1;
+ }
+
+ public BigDecimal getVal2() {
+ return val2;
+ }
+
+ public void setVal2(BigDecimal val2) {
+ this.val2 = val2;
+ }
+
+ public BigDecimal getVal3() {
+ return val3;
+ }
+
+ public void setVal3(BigDecimal val3) {
+ this.val3 = val3;
+ }
+}
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/SpringDocApp198Test.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/SpringDocApp198Test.java
new file mode 100644
index 000000000..c968c9cf1
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app198/SpringDocApp198Test.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * *
+ * * *
+ * * * * Copyright 2019-2022 the original author or authors.
+ * * * *
+ * * * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * * * you may not use this file except in compliance with the License.
+ * * * * You may obtain a copy of the License at
+ * * * *
+ * * * * https://www.apache.org/licenses/LICENSE-2.0
+ * * * *
+ * * * * Unless required by applicable law or agreed to in writing, software
+ * * * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * * * See the License for the specific language governing permissions and
+ * * * * limitations under the License.
+ * * *
+ * *
+ *
+ */
+
+package test.org.springdoc.api.v30.app198;
+
+import java.math.BigDecimal;
+
+import io.swagger.v3.oas.models.media.Schema;
+import org.springdoc.core.SpringDocUtils;
+import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+public class SpringDocApp198Test extends AbstractSpringDocV30Test {
+
+ static {
+ SpringDocUtils.getConfig().replaceWithSchema(
+ BigDecimal.class,
+ new Schema().type("string").format("decimal")
+ );
+ }
+
+ @SpringBootApplication
+ static class SpringDocTestApp {}
+
+}
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/CustomExceptionHandler.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/CustomExceptionHandler.java
new file mode 100644
index 000000000..87d700197
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/CustomExceptionHandler.java
@@ -0,0 +1,23 @@
+package test.org.springdoc.api.v30.app199;
+
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
+
+@ControllerAdvice
+public class CustomExceptionHandler {
+
+ static public class MyInternalException extends Exception {}
+
+ @ResponseStatus( value = INTERNAL_SERVER_ERROR )
+ @ExceptionHandler( MyInternalException.class )
+ @ResponseBody
+ public ErrorDto handleMyInternalException( final MyInternalException ex ) {
+ return new ErrorDto( ex.getMessage() );
+ }
+
+
+}
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/ErrorDto.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/ErrorDto.java
new file mode 100644
index 000000000..20b4a0e73
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/ErrorDto.java
@@ -0,0 +1,12 @@
+package test.org.springdoc.api.v30.app199;
+
+public class ErrorDto {
+ private String message;
+
+ public ErrorDto( final String message ) {
+ this.message = message;
+ }
+
+ public String getMessage() { return message; }
+ public void setMessage( final String message ) { this.message = message; }
+}
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/HelloController.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/HelloController.java
new file mode 100644
index 000000000..6054b7dcc
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/HelloController.java
@@ -0,0 +1,106 @@
+/*
+ *
+ * *
+ * * *
+ * * * * Copyright 2019-2022 the original author or authors.
+ * * * *
+ * * * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * * * you may not use this file except in compliance with the License.
+ * * * * You may obtain a copy of the License at
+ * * * *
+ * * * * https://www.apache.org/licenses/LICENSE-2.0
+ * * * *
+ * * * * Unless required by applicable law or agreed to in writing, software
+ * * * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * * * See the License for the specific language governing permissions and
+ * * * * limitations under the License.
+ * * *
+ * *
+ *
+ */
+
+package test.org.springdoc.api.v30.app199;
+
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.examples.Example;
+import org.springdoc.core.customizers.OperationCustomizer;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.method.HandlerMethod;
+
+import static org.springframework.http.MediaType.ALL_VALUE;
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
+
+@RestController
+public class HelloController {
+
+ @Autowired
+ ObjectMapper defaultObjectMapper;
+
+ @GetMapping(
+ value = "/first",
+ produces = APPLICATION_JSON_VALUE
+ )
+ public void first() {}
+
+ @GetMapping(
+ value = "/second",
+ produces = APPLICATION_JSON_VALUE
+ )
+ public void second() {}
+
+ @Bean
+ public OperationCustomizer operationCustomizer()
+ {
+ return ( Operation operation, HandlerMethod handlerMethod ) ->
+ {
+ final io.swagger.v3.oas.models.media.MediaType mediaType = operation
+ .getResponses()
+ .get( "500" )
+ .getContent()
+ .get( ALL_VALUE );
+
+ mediaType.setExamples( mediaType.getExamples() != null
+ ? mediaType.getExamples()
+ : new LinkedHashMap<>() );
+
+ final Map examples = mediaType.getExamples();
+
+ switch ( handlerMethod.getMethod().getName() ) {
+
+ case "first" :
+ examples.put(
+ "First case example",
+ new Example().value(
+ defaultObjectMapper.valueToTree(
+ new ErrorDto( "An ErrorDto sample specific to /first endpoint" )
+ )
+ )
+ );
+ break;
+
+ case "second" :
+ examples.put(
+ "Second case example",
+ new Example().value(
+ defaultObjectMapper.valueToTree(
+ new ErrorDto( "An ErrorDto sample specific to /second endpoint" )
+ )
+ )
+ );
+ break;
+ }
+
+ return operation;
+ };
+ }
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/SpringDocApp199Test.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/SpringDocApp199Test.java
new file mode 100644
index 000000000..4e526e1d6
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app199/SpringDocApp199Test.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * *
+ * * *
+ * * * * Copyright 2019-2022 the original author or authors.
+ * * * *
+ * * * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * * * you may not use this file except in compliance with the License.
+ * * * * You may obtain a copy of the License at
+ * * * *
+ * * * * https://www.apache.org/licenses/LICENSE-2.0
+ * * * *
+ * * * * Unless required by applicable law or agreed to in writing, software
+ * * * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * * * See the License for the specific language governing permissions and
+ * * * * limitations under the License.
+ * * *
+ * *
+ *
+ */
+
+package test.org.springdoc.api.v30.app199;
+
+import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+public class SpringDocApp199Test extends AbstractSpringDocV30Test {
+
+ @SpringBootApplication
+ static class SpringDocTestApp {}
+
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBar.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBar.java
new file mode 100644
index 000000000..a333aa533
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBar.java
@@ -0,0 +1,39 @@
+package test.org.springdoc.api.v30.app200;
+
+
+import javax.annotation.Generated;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+public enum FooBar {
+ FOO("foo"),
+ BAR("bar");
+
+ private String value;
+
+ FooBar(String value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ @JsonCreator
+ public static FooBar fromValue(String value) {
+ for (FooBar b : FooBar.values()) {
+ if (b.value.equals(value)) {
+ return b;
+ }
+ }
+ throw new IllegalArgumentException("Unexpected value '" + value + "'");
+ }
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBarController.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBarController.java
new file mode 100644
index 000000000..d979a032c
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBarController.java
@@ -0,0 +1,14 @@
+package test.org.springdoc.api.v30.app200;
+
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class FooBarController {
+ @GetMapping(value = "/example/{fooBar}")
+ public String getFooBar(@PathVariable FooBar fooBar) {
+ return fooBar.name();
+ }
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBarConverter.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBarConverter.java
new file mode 100644
index 000000000..123558637
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/FooBarConverter.java
@@ -0,0 +1,15 @@
+package test.org.springdoc.api.v30.app200;
+
+
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+@Component
+public class FooBarConverter implements Converter {
+
+ @Override
+ public FooBar convert(String source) {
+ return FooBar.fromValue(source);
+ }
+
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/SpringDocApp200Test.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/SpringDocApp200Test.java
new file mode 100644
index 000000000..c2055b1d6
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app200/SpringDocApp200Test.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * *
+ * * *
+ * * * * Copyright 2019-2022 the original author or authors.
+ * * * *
+ * * * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * * * you may not use this file except in compliance with the License.
+ * * * * You may obtain a copy of the License at
+ * * * *
+ * * * * https://www.apache.org/licenses/LICENSE-2.0
+ * * * *
+ * * * * Unless required by applicable law or agreed to in writing, software
+ * * * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * * * See the License for the specific language governing permissions and
+ * * * * limitations under the License.
+ * * *
+ * *
+ *
+ */
+
+package test.org.springdoc.api.v30.app200;
+
+import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+public class SpringDocApp200Test extends AbstractSpringDocV30Test {
+
+ @SpringBootApplication
+ static class SpringDocTestApp {}
+
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/application-test.properties b/springdoc-openapi-webmvc-core/src/test/resources/application-test.properties
index b88c99251..a2ac8faaf 100644
--- a/springdoc-openapi-webmvc-core/src/test/resources/application-test.properties
+++ b/springdoc-openapi-webmvc-core/src/test/resources/application-test.properties
@@ -1,3 +1,4 @@
spring.main.banner-mode=off
logging.level.root=OFF
-spring.main.lazy-initialization=true
\ No newline at end of file
+spring.main.lazy-initialization=true
+blahDescription.value=test
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app164.json b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app164.json
index c6720a02b..2300c41b9 100644
--- a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app164.json
+++ b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app164.json
@@ -48,9 +48,17 @@
},
"booleanValueAsFourthParameter": {
"type": "boolean"
+ },
+ "listBlah": {
+ "type": "array",
+ "description": "test",
+ "items": {
+ "type": "string",
+ "description": "test"
+ }
}
}
}
}
}
-}
\ No newline at end of file
+}
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app198.json b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app198.json
new file mode 100644
index 000000000..7a0d6620f
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app198.json
@@ -0,0 +1,57 @@
+{
+ "openapi": "3.0.1",
+ "info": {
+ "title": "OpenAPI definition",
+ "version": "v0"
+ },
+ "servers": [
+ {
+ "url": "http://localhost",
+ "description": "Generated server url"
+ }
+ ],
+ "paths": {
+ "/": {
+ "get": {
+ "tags": [
+ "hello-controller"
+ ],
+ "operationId": "test",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/Response"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Response": {
+ "type": "object",
+ "properties": {
+ "val1": {
+ "type": "string",
+ "format": "decimal",
+ "deprecated": true
+ },
+ "val2": {
+ "type": "string",
+ "format": "decimal"
+ },
+ "val3": {
+ "type": "string",
+ "format": "decimal"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app199.json b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app199.json
new file mode 100644
index 000000000..7471940f0
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app199.json
@@ -0,0 +1,87 @@
+{
+ "openapi": "3.0.1",
+ "info": {
+ "title": "OpenAPI definition",
+ "version": "v0"
+ },
+ "servers": [
+ {
+ "url": "http://localhost",
+ "description": "Generated server url"
+ }
+ ],
+ "paths": {
+ "/second": {
+ "get": {
+ "tags": [
+ "hello-controller"
+ ],
+ "operationId": "second",
+ "responses": {
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorDto"
+ },
+ "examples": {
+ "Second case example": {
+ "value": {
+ "message": "An ErrorDto sample specific to /second endpoint"
+ }
+ }
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK"
+ }
+ }
+ }
+ },
+ "/first": {
+ "get": {
+ "tags": [
+ "hello-controller"
+ ],
+ "operationId": "first",
+ "responses": {
+ "500": {
+ "description": "Internal Server Error",
+ "content": {
+ "*/*": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorDto"
+ },
+ "examples": {
+ "First case example": {
+ "value": {
+ "message": "An ErrorDto sample specific to /first endpoint"
+ }
+ }
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK"
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "ErrorDto": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app200.json b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app200.json
new file mode 100644
index 000000000..b64c8dc8b
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app200.json
@@ -0,0 +1,50 @@
+{
+ "openapi": "3.0.1",
+ "info": {
+ "title": "OpenAPI definition",
+ "version": "v0"
+ },
+ "servers": [
+ {
+ "url": "http://localhost",
+ "description": "Generated server url"
+ }
+ ],
+ "paths": {
+ "/example/{fooBar}": {
+ "get": {
+ "tags": [
+ "foo-bar-controller"
+ ],
+ "operationId": "getFooBar",
+ "parameters": [
+ {
+ "name": "fooBar",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "enum": [
+ "foo",
+ "bar"
+ ]
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "*/*": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {}
+}