[BUG][java][resttemplate] Fix NPE when query param with value null is exploded (#17568)

* Fix NPE when query param with value null is exploded

* Polish

* Add test

* Update tests

* Add integration test
This commit is contained in:
Jorge Rodríguez Martín
2024-01-10 16:39:41 +01:00
committed by GitHub
parent d0e533d573
commit 61c40474af
17 changed files with 150 additions and 56 deletions

View File

@@ -126,10 +126,12 @@ public class {{classname}} {
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();{{#hasQueryParams}}
{{#queryParams}}{{#isExplode}}{{#hasVars}}{{#vars}} localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}.{{getter}}()));
{{/vars}}{{/hasVars}}{{^hasVars}} localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));
{{/hasVars}}{{/isExplode}}{{^isExplode}} localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));
{{/isExplode}}{{/queryParams}}{{/hasQueryParams}}{{#hasHeaderParams}}
{{#queryParams}}{{#isExplode}}{{#hasVars}}
if ({{paramName}} != null) {
{{#vars}} localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}.{{getter}}()));
{{/vars}}}{{/hasVars}}{{^hasVars}}localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));
{{/hasVars}}{{/isExplode}}{{^isExplode}}localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));
{{/isExplode}}{{/queryParams}}{{/hasQueryParams}}{{#hasHeaderParams}}
{{#headerParams}}if ({{paramName}} != null)
localVarHeaderParams.add("{{baseName}}", apiClient.parameterToString({{paramName}}));{{^-last}}

View File

@@ -2938,4 +2938,32 @@ public class JavaClientCodegenTest {
assertNotNull(apiFile);
JavaFileAssert.assertThat(apiFile).fileContains(expectedInnerEnumLines);
}
@Test
public void testQueryParamsExploded_whenQueryParamIsNull() throws IOException {
Map<String, Object> properties = new HashMap<>();
properties.put(CodegenConstants.API_PACKAGE, "xyz.abcdef.api");
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setLibrary(JavaClientCodegen.RESTTEMPLATE)
.setAdditionalProperties(properties)
.setInputSpec("src/test/resources/3_0/issue_17555.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
validateJavaSourceFiles(files);
Path petApi = Paths.get(output + "/src/main/java/xyz/abcdef/api/DepartmentApi.java");
TestUtils.assertFileContains(petApi, "if (filter != null) {");
}
}

View File

@@ -0,0 +1,51 @@
openapi: 3.0.0
info:
description: My description
version: 1.0.0
title: OpenAPI Petstore
license:
name: Apache-2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: department
description: Everything about your Department
paths:
/api/department/{departmentId}/teams:
get:
tags:
- Department
summary: Find Department Teams
operationId: findDepartmentTeams
description: Find Department Teams
parameters:
- $ref: '#/components/parameters/departmentIdParam'
- $ref: '#/components/parameters/teamQueryParam'
responses:
'200':
description: OK
components:
schemas:
TeamCriteriaDTO:
type: object
title: TeamCriteriaDTO
properties:
key:
type: string
name:
type: string
parameters:
departmentIdParam:
name: departmentId
in: path
description: ID of the department to search
required: true
schema:
type: string
teamQueryParam:
name: filter
in: query
description: Fetch teams query
required: false
allowEmptyValue: true
schema:
$ref: '#/components/schemas/TeamCriteriaDTO'

View File

@@ -227,13 +227,15 @@ public class QueryApi {
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();
if (queryObject != null) {
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "id", queryObject.getId()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "name", queryObject.getName()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "category", queryObject.getCategory()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "photoUrls", queryObject.getPhotoUrls()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "tags", queryObject.getTags()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "status", queryObject.getStatus()));
}
final String[] localVarAccepts = {
"text/plain"
@@ -320,8 +322,10 @@ public class QueryApi {
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "values", queryObject.getValues()));
if (queryObject != null) {
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "values", queryObject.getValues()));
}
final String[] localVarAccepts = {
"text/plain"
@@ -364,13 +368,15 @@ public class QueryApi {
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();
if (queryObject != null) {
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "id", queryObject.getId()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "name", queryObject.getName()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "category", queryObject.getCategory()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "photoUrls", queryObject.getPhotoUrls()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "tags", queryObject.getTags()));
localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "status", queryObject.getStatus()));
}
final String[] localVarAccepts = {
"text/plain"

View File

@@ -14,13 +14,15 @@
package org.openapitools.client;
import org.junit.Assert;
import org.openapitools.client.api.*;
import org.openapitools.client.model.*;
import org.junit.Test;
import org.junit.Ignore;
import org.openapitools.client.api.BodyApi;
import org.openapitools.client.api.QueryApi;
import org.openapitools.client.model.Category;
import org.openapitools.client.model.Pet;
import java.io.IOException;
import java.util.*;
import java.util.Arrays;
import static org.junit.Assert.assertNotNull;
/**
@@ -43,7 +45,7 @@ public class CustomTest {
photoUrls(Arrays.asList(new String[]{"http://a.com", "http://b.com"})).category(new Category().id(987L).name("new category"));
Pet p = bodyApi.testEchoBodyPet(pet);
Assert.assertNotNull(p);
assertNotNull(p);
Assert.assertEquals("Hello World", p.getName());
Assert.assertEquals(Long.valueOf(12345L), p.getId());
@@ -51,4 +53,9 @@ public class CustomTest {
Pet p2 = bodyApi.testEchoBodyPet(null);
Assert.assertNull(p2);
}
@Test
public void testQueryParamsExploded_whenQueryParamIsNull() {
assertNotNull(api.testQueryStyleFormExplodeTrueObject(null));
}
}