Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rest-template: allow array parameters in path using collectionFormat #2177

Merged
merged 2 commits into from
Feb 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ public class ApiClient {
return StringUtils.collectionToDelimitedString(collection, separator);
}
}

private boolean debugging = false;

private HttpHeaders defaultHeaders = new HttpHeaders();

private String basePath = "{{basePath}}";

private RestTemplate restTemplate;
Expand All @@ -99,20 +99,20 @@ public class ApiClient {

private HttpStatus statusCode;
private MultiValueMap<String, String> responseHeaders;

private DateFormat dateFormat;

public ApiClient() {
this.restTemplate = buildRestTemplate();
init();
}

@Autowired
public ApiClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
init();
}

protected void init() {
// Use RFC3339 format for date and datetime.
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
Expand All @@ -132,7 +132,7 @@ public class ApiClient {
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
}

/**
* Get the current base path
* @return String the base path
Expand Down Expand Up @@ -281,7 +281,7 @@ public class ApiClient {
defaultHeaders.add(name, value);
return this;
}

public void setDebugging(boolean debugging) {
List<ClientHttpRequestInterceptor> currentInterceptors = this.restTemplate.getInterceptors();
if(debugging) {
Expand Down Expand Up @@ -339,7 +339,7 @@ public class ApiClient {
{{/threetenbp}}
return this;
}

/**
* Parse the given string into Date object.
*/
Expand Down Expand Up @@ -382,6 +382,28 @@ public class ApiClient {
}
}

/**
* Formats the specified collection path parameter to a string value.
*
* @param collectionFormat The collection format of the parameter.
* @param value The value of the parameter.
* @return String representation of the parameter
*/
public String collectionPathParameterToString(CollectionFormat collectionFormat, Collection<? extends CharSequence> values) {
// create the value based on the collection format
if (CollectionFormat.MULTI.equals(collectionFormat)) {
// not valid for path params
return parameterToString(values);
}

// collectionFormat is assumed to be "csv" by default
if(collectionFormat == null) {
collectionFormat = CollectionFormat.CSV;
}

return collectionFormat.collectionToString(values);
}

/**
* Converts a parameter to a {@link MultiValueMap} for use in REST requests
* @param collectionFormat The format to convert to
Expand Down Expand Up @@ -531,7 +553,7 @@ public class ApiClient {
*/
public <T> T invokeAPI(String path, HttpMethod method, MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams, MultiValueMap<String, Object> formParams, List<MediaType> accept, MediaType contentType, String[] authNames, ParameterizedTypeReference<T> returnType) throws RestClientException {
updateParamsForAuth(authNames, queryParams, headerParams);

final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(path);
if (queryParams != null) {
//encode the query parameters in case they contain unsafe characters
Expand All @@ -548,29 +570,29 @@ public class ApiClient {
}
builder.queryParams(queryParams);
}

URI uri;
try {
uri = new URI(builder.build().toUriString());
} catch(URISyntaxException ex) {
throw new RestClientException("Could not build URL: " + builder.toUriString(), ex);
}

final BodyBuilder requestBuilder = RequestEntity.method(method, uri);
if(accept != null) {
requestBuilder.accept(accept.toArray(new MediaType[accept.size()]));
}
if(contentType != null) {
requestBuilder.contentType(contentType);
}

addHeadersToRequest(headerParams, requestBuilder);
addHeadersToRequest(defaultHeaders, requestBuilder);

RequestEntity<Object> requestEntity = requestBuilder.body(selectBody(body, formParams, contentType));

ResponseEntity<T> responseEntity = restTemplate.exchange(requestEntity, returnType);

statusCode = responseEntity.getStatusCode();
responseHeaders = responseEntity.getHeaders();

Expand All @@ -586,7 +608,7 @@ public class ApiClient {
throw new RestClientException("API returned " + statusCode + " and it wasn't handled by the RestTemplate error handler");
}
}

/**
* Add headers to the request that is being built
* @param headers The headers to add
Expand Down Expand Up @@ -649,7 +671,7 @@ public class ApiClient {
auth.applyToParams(queryParams, headerParams);
}
}

private class ApiClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private final Log log = LogFactory.getLog(ApiClientHttpRequestInterceptor.class);

Expand Down Expand Up @@ -688,7 +710,7 @@ public class ApiClient {
builder.setLength(builder.length() - 1); // Get rid of trailing comma
return builder.toString();
}

private String bodyToString(InputStream body) throws IOException {
StringBuilder builder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(body, StandardCharsets.UTF_8));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,20 @@ public class {{classname}} {
{{/required}}{{/allParams}}{{#hasPathParams}}
// create path and map variables
final Map<String, Object> uriVariables = new HashMap<String, Object>();{{#pathParams}}
uriVariables.put("{{baseName}}", {{{paramName}}});{{/pathParams}}{{/hasPathParams}}
uriVariables.put("{{baseName}}", {{#collectionFormat}}apiClient.collectionPathParameterToString(ApiClient.CollectionFormat.valueOf("{{{collectionFormat}}}".toUpperCase()), {{{paramName}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}});{{/pathParams}}{{/hasPathParams}}
String {{localVariablePrefix}}path = UriComponentsBuilder.fromPath("{{{path}}}"){{#hasPathParams}}.buildAndExpand(uriVariables){{/hasPathParams}}{{^hasPathParams}}.build(){{/hasPathParams}}.toUriString();

final MultiValueMap<String, String> {{localVariablePrefix}}queryParams = new LinkedMultiValueMap<String, String>();
final HttpHeaders {{localVariablePrefix}}headerParams = new HttpHeaders();
final MultiValueMap<String, Object> {{localVariablePrefix}}formParams = new LinkedMultiValueMap<String, Object>();{{#hasQueryParams}}

{{#queryParams}}{{localVariablePrefix}}queryParams.putAll({{localVariablePrefix}}apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{collectionFormat}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));{{#hasMore}}
{{/hasMore}}{{/queryParams}}{{/hasQueryParams}}{{#hasHeaderParams}}

{{#headerParams}}if ({{paramName}} != null)
{{localVariablePrefix}}headerParams.add("{{baseName}}", {{localVariablePrefix}}apiClient.parameterToString({{paramName}}));{{#hasMore}}
{{/hasMore}}{{/headerParams}}{{/hasHeaderParams}}{{#hasFormParams}}

{{#formParams}}if ({{paramName}} != null)
{{localVariablePrefix}}formParams.add("{{baseName}}", {{#isFile}}new FileSystemResource({{paramName}}){{/isFile}}{{^isFile}}{{paramName}}{{/isFile}});{{#hasMore}}
{{/hasMore}}{{/formParams}}{{/hasFormParams}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ private String collectionToString(Collection<? extends CharSequence> collection)
return StringUtils.collectionToDelimitedString(collection, separator);
}
}

private boolean debugging = false;

private HttpHeaders defaultHeaders = new HttpHeaders();

private String basePath = "http://petstore.swagger.io:80/v2";

private RestTemplate restTemplate;
Expand All @@ -91,20 +91,20 @@ private String collectionToString(Collection<? extends CharSequence> collection)

private HttpStatus statusCode;
private MultiValueMap<String, String> responseHeaders;

private DateFormat dateFormat;

public ApiClient() {
this.restTemplate = buildRestTemplate();
init();
}

@Autowired
public ApiClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
init();
}

protected void init() {
// Use RFC3339 format for date and datetime.
// See http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
Expand All @@ -125,7 +125,7 @@ protected void init() {
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
}

/**
* Get the current base path
* @return String the base path
Expand Down Expand Up @@ -272,7 +272,7 @@ public ApiClient addDefaultHeader(String name, String value) {
defaultHeaders.add(name, value);
return this;
}

public void setDebugging(boolean debugging) {
List<ClientHttpRequestInterceptor> currentInterceptors = this.restTemplate.getInterceptors();
if(debugging) {
Expand Down Expand Up @@ -328,7 +328,7 @@ public ApiClient setDateFormat(DateFormat dateFormat) {
}
return this;
}

/**
* Parse the given string into Date object.
*/
Expand Down Expand Up @@ -371,6 +371,28 @@ public String parameterToString(Object param) {
}
}

/**
* Formats the specified collection path parameter to a string value.
*
* @param collectionFormat The collection format of the parameter.
* @param value The value of the parameter.
* @return String representation of the parameter
*/
public String collectionPathParameterToString(CollectionFormat collectionFormat, Collection<? extends CharSequence> values) {
// create the value based on the collection format
if (CollectionFormat.MULTI.equals(collectionFormat)) {
// not valid for path params
return parameterToString(values);
}

// collectionFormat is assumed to be "csv" by default
if(collectionFormat == null) {
collectionFormat = CollectionFormat.CSV;
}

return collectionFormat.collectionToString(values);
}

/**
* Converts a parameter to a {@link MultiValueMap} for use in REST requests
* @param collectionFormat The format to convert to
Expand Down Expand Up @@ -520,7 +542,7 @@ protected Object selectBody(Object obj, MultiValueMap<String, Object> formParams
*/
public <T> T invokeAPI(String path, HttpMethod method, MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams, MultiValueMap<String, Object> formParams, List<MediaType> accept, MediaType contentType, String[] authNames, ParameterizedTypeReference<T> returnType) throws RestClientException {
updateParamsForAuth(authNames, queryParams, headerParams);

final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(path);
if (queryParams != null) {
//encode the query parameters in case they contain unsafe characters
Expand All @@ -537,29 +559,29 @@ public <T> T invokeAPI(String path, HttpMethod method, MultiValueMap<String, Str
}
builder.queryParams(queryParams);
}

URI uri;
try {
uri = new URI(builder.build().toUriString());
} catch(URISyntaxException ex) {
throw new RestClientException("Could not build URL: " + builder.toUriString(), ex);
}

final BodyBuilder requestBuilder = RequestEntity.method(method, uri);
if(accept != null) {
requestBuilder.accept(accept.toArray(new MediaType[accept.size()]));
}
if(contentType != null) {
requestBuilder.contentType(contentType);
}

addHeadersToRequest(headerParams, requestBuilder);
addHeadersToRequest(defaultHeaders, requestBuilder);

RequestEntity<Object> requestEntity = requestBuilder.body(selectBody(body, formParams, contentType));

ResponseEntity<T> responseEntity = restTemplate.exchange(requestEntity, returnType);

statusCode = responseEntity.getStatusCode();
responseHeaders = responseEntity.getHeaders();

Expand All @@ -575,7 +597,7 @@ public <T> T invokeAPI(String path, HttpMethod method, MultiValueMap<String, Str
throw new RestClientException("API returned " + statusCode + " and it wasn't handled by the RestTemplate error handler");
}
}

/**
* Add headers to the request that is being built
* @param headers The headers to add
Expand Down Expand Up @@ -636,7 +658,7 @@ private void updateParamsForAuth(String[] authNames, MultiValueMap<String, Strin
auth.applyToParams(queryParams, headerParams);
}
}

private class ApiClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private final Log log = LogFactory.getLog(ApiClientHttpRequestInterceptor.class);

Expand Down Expand Up @@ -675,7 +697,7 @@ private String headersToString(HttpHeaders headers) {
builder.setLength(builder.length() - 1); // Get rid of trailing comma
return builder.toString();
}

private String bodyToString(InputStream body) throws IOException {
StringBuilder builder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(body, StandardCharsets.UTF_8));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public Client call123testSpecialTags(Client body) throws RestClientException {
}

String path = UriComponentsBuilder.fromPath("/another-fake/dummy").build().toUriString();

final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
final HttpHeaders headerParams = new HttpHeaders();
final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();
Expand Down
Loading