[Java][resttemplate] Support URL queryParams Comma encoding (#10958)

* Java Encode comma (with unit tests)

* fix PMD warnings
This commit is contained in:
Berlin Cho 2021-11-25 16:12:55 +08:00 committed by GitHub
parent 5bd0452893
commit 8e303150ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 143 additions and 42 deletions

View File

@ -34,6 +34,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.DefaultUriBuilderFactory;
{{#threetenbp}} {{#threetenbp}}
import org.threeten.bp.*; import org.threeten.bp.*;
import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule; import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule;
@ -622,6 +623,12 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @return path with placeholders replaced by variables * @return path with placeholders replaced by variables
*/ */
public String expandPath(String pathTemplate, Map<String, Object> variables) { public String expandPath(String pathTemplate, Map<String, Object> variables) {
// disable default URL encoding
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory();
uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(uriBuilderFactory);
return restTemplate.getUriTemplateHandler().expand(pathTemplate, variables).toString(); return restTemplate.getUriTemplateHandler().expand(pathTemplate, variables).toString();
} }
@ -632,28 +639,34 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* @param uriParams The path parameters * @param uriParams The path parameters
* return templatized query string * return templatized query string
*/ */
private String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) { public String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) {
StringBuilder queryBuilder = new StringBuilder(); StringBuilder queryBuilder = new StringBuilder();
queryParams.forEach((name, values) -> { queryParams.forEach((name, values) -> {
try {
final String encodedName = URLEncoder.encode(name.toString(), "UTF-8");
if (CollectionUtils.isEmpty(values)) { if (CollectionUtils.isEmpty(values)) {
if (queryBuilder.length() != 0) { if (queryBuilder.length() != 0) {
queryBuilder.append('&'); queryBuilder.append('&');
} }
queryBuilder.append(name); queryBuilder.append(encodedName);
} else { } else {
int valueItemCounter = 0; int valueItemCounter = 0;
for (Object value : values) { for (Object value : values) {
if (queryBuilder.length() != 0) { if (queryBuilder.length() != 0) {
queryBuilder.append('&'); queryBuilder.append('&');
} }
queryBuilder.append(name); queryBuilder.append(encodedName);
if (value != null) { if (value != null) {
String templatizedKey = name + valueItemCounter++; String templatizedKey = encodedName + valueItemCounter++;
uriParams.put(templatizedKey, value.toString()); final String encodedValue = URLEncoder.encode(value.toString(), "UTF-8");
uriParams.put(templatizedKey, encodedValue);
queryBuilder.append('=').append("{").append(templatizedKey).append("}"); queryBuilder.append('=').append("{").append(templatizedKey).append("}");
} }
} }
} }
} catch (UnsupportedEncodingException e) {
}
}); });
return queryBuilder.toString(); return queryBuilder.toString();

View File

@ -30,6 +30,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.threeten.bp.*; import org.threeten.bp.*;
import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule; import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
@ -578,6 +579,12 @@ public class ApiClient extends JavaTimeFormatter {
* @return path with placeholders replaced by variables * @return path with placeholders replaced by variables
*/ */
public String expandPath(String pathTemplate, Map<String, Object> variables) { public String expandPath(String pathTemplate, Map<String, Object> variables) {
// disable default URL encoding
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory();
uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(uriBuilderFactory);
return restTemplate.getUriTemplateHandler().expand(pathTemplate, variables).toString(); return restTemplate.getUriTemplateHandler().expand(pathTemplate, variables).toString();
} }
@ -588,28 +595,34 @@ public class ApiClient extends JavaTimeFormatter {
* @param uriParams The path parameters * @param uriParams The path parameters
* return templatized query string * return templatized query string
*/ */
private String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) { public String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) {
StringBuilder queryBuilder = new StringBuilder(); StringBuilder queryBuilder = new StringBuilder();
queryParams.forEach((name, values) -> { queryParams.forEach((name, values) -> {
try {
final String encodedName = URLEncoder.encode(name.toString(), "UTF-8");
if (CollectionUtils.isEmpty(values)) { if (CollectionUtils.isEmpty(values)) {
if (queryBuilder.length() != 0) { if (queryBuilder.length() != 0) {
queryBuilder.append('&'); queryBuilder.append('&');
} }
queryBuilder.append(name); queryBuilder.append(encodedName);
} else { } else {
int valueItemCounter = 0; int valueItemCounter = 0;
for (Object value : values) { for (Object value : values) {
if (queryBuilder.length() != 0) { if (queryBuilder.length() != 0) {
queryBuilder.append('&'); queryBuilder.append('&');
} }
queryBuilder.append(name); queryBuilder.append(encodedName);
if (value != null) { if (value != null) {
String templatizedKey = name + valueItemCounter++; String templatizedKey = encodedName + valueItemCounter++;
uriParams.put(templatizedKey, value.toString()); final String encodedValue = URLEncoder.encode(value.toString(), "UTF-8");
uriParams.put(templatizedKey, encodedValue);
queryBuilder.append('=').append("{").append(templatizedKey).append("}"); queryBuilder.append('=').append("{").append(templatizedKey).append("}");
} }
} }
} }
} catch (UnsupportedEncodingException e) {
}
}); });
return queryBuilder.toString(); return queryBuilder.toString();

View File

@ -0,0 +1,31 @@
package org.openapitools.client;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.util.*;
import org.junit.*;
import org.springframework.util.MultiValueMap;
import org.springframework.util.LinkedMultiValueMap;
public class ApiClientTest {
ApiClient apiClient;
@Before
public void setup() {
apiClient = new ApiClient();
}
/**
* Test uri encoding when params contains comma
*/
@Test
public void testUriEncoderWithComma() {
Map<String,Object> uriParams = new HashMap<>();
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
queryParams.add("key", "val,comma");
apiClient.generateQueryUri(queryParams, uriParams);
assertEquals("/key=val%2Ccomma", apiClient.expandPath("/key={key0}", uriParams));
}
}

View File

@ -25,6 +25,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.threeten.bp.*; import org.threeten.bp.*;
import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule; import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
@ -573,6 +574,12 @@ public class ApiClient extends JavaTimeFormatter {
* @return path with placeholders replaced by variables * @return path with placeholders replaced by variables
*/ */
public String expandPath(String pathTemplate, Map<String, Object> variables) { public String expandPath(String pathTemplate, Map<String, Object> variables) {
// disable default URL encoding
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory();
uriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(uriBuilderFactory);
return restTemplate.getUriTemplateHandler().expand(pathTemplate, variables).toString(); return restTemplate.getUriTemplateHandler().expand(pathTemplate, variables).toString();
} }
@ -583,28 +590,34 @@ public class ApiClient extends JavaTimeFormatter {
* @param uriParams The path parameters * @param uriParams The path parameters
* return templatized query string * return templatized query string
*/ */
private String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) { public String generateQueryUri(MultiValueMap<String, String> queryParams, Map<String, Object> uriParams) {
StringBuilder queryBuilder = new StringBuilder(); StringBuilder queryBuilder = new StringBuilder();
queryParams.forEach((name, values) -> { queryParams.forEach((name, values) -> {
try {
final String encodedName = URLEncoder.encode(name.toString(), "UTF-8");
if (CollectionUtils.isEmpty(values)) { if (CollectionUtils.isEmpty(values)) {
if (queryBuilder.length() != 0) { if (queryBuilder.length() != 0) {
queryBuilder.append('&'); queryBuilder.append('&');
} }
queryBuilder.append(name); queryBuilder.append(encodedName);
} else { } else {
int valueItemCounter = 0; int valueItemCounter = 0;
for (Object value : values) { for (Object value : values) {
if (queryBuilder.length() != 0) { if (queryBuilder.length() != 0) {
queryBuilder.append('&'); queryBuilder.append('&');
} }
queryBuilder.append(name); queryBuilder.append(encodedName);
if (value != null) { if (value != null) {
String templatizedKey = name + valueItemCounter++; String templatizedKey = encodedName + valueItemCounter++;
uriParams.put(templatizedKey, value.toString()); final String encodedValue = URLEncoder.encode(value.toString(), "UTF-8");
uriParams.put(templatizedKey, encodedValue);
queryBuilder.append('=').append("{").append(templatizedKey).append("}"); queryBuilder.append('=').append("{").append(templatizedKey).append("}");
} }
} }
} }
} catch (UnsupportedEncodingException e) {
}
}); });
return queryBuilder.toString(); return queryBuilder.toString();

View File

@ -0,0 +1,31 @@
package org.openapitools.client;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.util.*;
import org.junit.*;
import org.springframework.util.MultiValueMap;
import org.springframework.util.LinkedMultiValueMap;
public class ApiClientTest {
ApiClient apiClient;
@Before
public void setup() {
apiClient = new ApiClient();
}
/**
* Test uri encoding when params contains comma
*/
@Test
public void testUriEncoderWithComma() {
Map<String,Object> uriParams = new HashMap<>();
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
queryParams.add("key", "val,comma");
apiClient.generateQueryUri(queryParams, uriParams);
assertEquals("/key=val%2Ccomma", apiClient.expandPath("/key={key0}", uriParams));
}
}