Skip to content

Commit

Permalink
Rest client 2.0 updates (#4724)
Browse files Browse the repository at this point in the history
* RestClient updates

Signed-off-by: David Kral <[email protected]>
  • Loading branch information
Verdent committed Feb 18, 2021
1 parent 741aad4 commit 48c4fb8
Show file tree
Hide file tree
Showing 12 changed files with 364 additions and 261 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -452,14 +452,14 @@ public final class ClientProperties {
public static final Long DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE = 65536L;

/**
* The property defines the desired format of query param when multiple
* values are sent for the same parameter.
* The property defines the desired format of query parameters.
*
* <p>
* The value MUST be an instance of
* {@link org.glassfish.jersey.uri.QueryParamStyle}.</p>
* The value MUST be an instance of {@link org.glassfish.jersey.uri.JerseyQueryParamStyle}.
* </p>
* <p>
* The default value is {@code null}.</p>
* If the property is not set, {@link org.glassfish.jersey.uri.JerseyQueryParamStyle#MULTI_PAIRS} is selected.
* </p>
*/
public static final String QUERY_PARAM_STYLE = "jersey.config.client.uri.query.param.style";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,9 @@ public JerseyWebTarget matrixParam(String name, Object... values) throws NullPoi
public JerseyWebTarget queryParam(String name, Object... values) throws NullPointerException {
checkNotClosed();
UriBuilder uriBuilder = getUriBuilder();
if (uriBuilder instanceof JerseyUriBuilder) {
((JerseyUriBuilder) uriBuilder).setQueryParamStyle((JerseyQueryParamStyle) this.getConfiguration()
.getProperty(ClientProperties.QUERY_PARAM_STYLE)
);
Object queryParamProperty = this.getConfiguration().getProperty(ClientProperties.QUERY_PARAM_STYLE);
if (queryParamProperty instanceof JerseyQueryParamStyle && uriBuilder instanceof JerseyUriBuilder) {
((JerseyUriBuilder) uriBuilder).setQueryParamStyle((JerseyQueryParamStyle) queryParamProperty);
}
return new JerseyWebTarget(JerseyWebTarget.setQueryParam(uriBuilder, name, values), this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ public enum JerseyQueryParamStyle {

/**
* Multiple parameter instances, e.g.:
* <code>foo=v1&amp;foot=v2&amp;foo=v3</code>
* <code>foo=v1&amp;foo=v2&amp;foo=v3</code>
*
* This is the default if no style is configured.
* This is the default query format.
*/
MULTI_PAIRS,

/** A single parameter instance with multiple, comma-separated values, e.g.:
/**
* A single parameter instance with multiple, comma-separated values, e.g.:
* <code>foo=v1,v2,v3</code>
*/
COMMA_SEPARATED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.ws.rs.Path;
import javax.ws.rs.core.MultivaluedMap;
Expand Down Expand Up @@ -79,6 +82,7 @@ public class JerseyUriBuilder extends UriBuilder {
public JerseyUriBuilder() {
path = new StringBuilder();
query = new StringBuilder();
queryParamStyle = JerseyQueryParamStyle.MULTI_PAIRS;
}

private JerseyUriBuilder(final JerseyUriBuilder that) {
Expand All @@ -93,6 +97,7 @@ private JerseyUriBuilder(final JerseyUriBuilder that) {
this.query = new StringBuilder(that.query);
this.queryParams = that.queryParams == null ? null : new MultivaluedStringMap(that.queryParams);
this.fragment = that.fragment;
this.queryParamStyle = that.queryParamStyle;
}

@SuppressWarnings("CloneDoesntCallSuperClone")
Expand Down Expand Up @@ -539,22 +544,32 @@ public JerseyUriBuilder queryParam(String name, final Object... values) {
}

name = encode(name, UriComponent.Type.QUERY_PARAM);
if (null == queryParamStyle) {
clientQueryParamMultiPairs(name, values);
} else switch (queryParamStyle) {
case ARRAY_PAIRS:
clientQueryParamArrayPairs(name, values);
break;
case COMMA_SEPARATED:
clientQueryParamCommaSeparated(name, values);
break;
default:
clientQueryParamMultiPairs(name, values);
break;

List<String> stringsValues = Stream.of(values)
.map(this::convertToString)
.map(value -> encode(value, UriComponent.Type.QUERY_PARAM))
.collect(Collectors.toList());

switch (queryParamStyle) {
case ARRAY_PAIRS:
clientQueryParamArrayPairs(name, stringsValues);
break;
case COMMA_SEPARATED:
clientQueryParamCommaSeparated(name, stringsValues);
break;
default:
clientQueryParamMultiPairs(name, stringsValues);
}
return this;
}

private String convertToString(Object value) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.QUERY_PARAM_NULL());
}
return value.toString();
}

/**
* Multiple parameter instances, e.g foo=v1&amp;foot=v2&amp;foo=v3 This is
* the default if no style is configured.
Expand All @@ -563,27 +578,17 @@ public JerseyUriBuilder queryParam(String name, final Object... values) {
* @param values
* @throws IllegalArgumentException
*/
private void clientQueryParamMultiPairs(String name, final Object... values) {
private void clientQueryParamMultiPairs(String name, List<String> values) {
if (queryParams == null) {
for (final Object value : values) {
for (final String value : values) {
if (query.length() > 0) {
query.append('&');
}
query.append(name);

if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.QUERY_PARAM_NULL());
}

query.append('=').append(encode(value.toString(), UriComponent.Type.QUERY_PARAM));
query.append(name).append('=').append(value);
}
} else {
for (final Object value : values) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.QUERY_PARAM_NULL());
}

queryParams.add(name, encode(value.toString(), UriComponent.Type.QUERY_PARAM));
for (final String value : values) {
queryParams.add(name, value);
}
}
}
Expand All @@ -596,40 +601,15 @@ private void clientQueryParamMultiPairs(String name, final Object... values) {
* @param values
* @throws IllegalArgumentException
*/
private void clientQueryParamCommaSeparated(String name, final Object... values) throws IllegalArgumentException {
StringBuilder sb = new StringBuilder();
private void clientQueryParamCommaSeparated(String name, List<String> values) throws IllegalArgumentException {
if (queryParams == null) {
if (query.length() > 0) {
query.append('&');
}
query.append(name);
int valuesCount = values.length - 1;
for (final Object value : values) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.QUERY_PARAM_NULL());
}
sb.append(encode(value.toString(), UriComponent.Type.QUERY_PARAM));
if (valuesCount > 0) {
sb.append(",");
--valuesCount;
}
}
query.append('=').append(sb.toString());
query.append(name).append('=').append(String.join(",", values));
} else {
int valuesCount = values.length - 1;
for (final Object value : values) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.QUERY_PARAM_NULL());
}
sb.append(encode(value.toString(), UriComponent.Type.QUERY_PARAM));
if (valuesCount > 0) {
sb.append(",");
--valuesCount;
}
}
queryParams.add(name, sb.toString());
queryParams.add(name, String.join(",", values));
}

}

/**
Expand All @@ -640,37 +620,24 @@ private void clientQueryParamCommaSeparated(String name, final Object... values)
* @param values
* @throws IllegalArgumentException
*/
private void clientQueryParamArrayPairs(String name, final Object... values) throws IllegalArgumentException {
private void clientQueryParamArrayPairs(String name, List<String> values) throws IllegalArgumentException {
if (queryParams == null) {
for (final Object value : values) {
for (final String value : values) {
if (query.length() > 0) {
query.append('&');
}
query.append(name).append("[]");

if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.QUERY_PARAM_NULL());
}

query.append('=').append(encode(value.toString(), UriComponent.Type.QUERY_PARAM));
query.append(name).append("[]").append('=').append(value);
}
} else {
for (final Object value : values) {
if (value == null) {
throw new IllegalArgumentException(LocalizationMessages.QUERY_PARAM_NULL());
}

queryParams.add(name + "[]", encode(value.toString(), UriComponent.Type.QUERY_PARAM));
for (final String value : values) {
queryParams.add(name + "[]", value);
}
}
}

public JerseyQueryParamStyle getQueryParamStyle() {
return queryParamStyle;
}

public void setQueryParamStyle(JerseyQueryParamStyle queryParamStyle) {
this.queryParamStyle = queryParamStyle;
public JerseyUriBuilder setQueryParamStyle(JerseyQueryParamStyle queryParamStyle) {
this.queryParamStyle = Objects.requireNonNull(queryParamStyle);
return this;
}

@Override
Expand Down Expand Up @@ -780,7 +747,7 @@ private JerseyUriBuilder resolveTemplates(final Map<String, Object> templateValu
path.append(newPath);

final String newQuery = UriTemplate.resolveTemplateValues(UriComponent.Type.QUERY_PARAM, query.toString(), encode,
templateValues);
templateValues);
query.setLength(0);
query.append(newQuery);

Expand Down Expand Up @@ -827,7 +794,7 @@ private void appendPath(String segments, final boolean isSegment) {
encodeMatrix();

segments = encode(segments,
(isSegment) ? UriComponent.Type.PATH_SEGMENT : UriComponent.Type.PATH);
(isSegment) ? UriComponent.Type.PATH_SEGMENT : UriComponent.Type.PATH);

final boolean pathEndsInSlash = path.length() > 0 && path.charAt(path.length() - 1) == '/';
final boolean segmentStartsWithSlash = segments.charAt(0) == '/';
Expand Down Expand Up @@ -998,6 +965,9 @@ private URI _build(final boolean encode, final boolean encodeSlashInPath, final

encodeMatrix();
encodeQuery();
if (queryParamStyle == JerseyQueryParamStyle.COMMA_SEPARATED) {
groupQueryParams();
}

final String uri = UriTemplate.createURI(
scheme, authority,
Expand All @@ -1006,6 +976,12 @@ private URI _build(final boolean encode, final boolean encodeSlashInPath, final
return createURI(uri);
}

private void groupQueryParams() {
MultivaluedMap<String, String> queryParams = UriComponent.decodeQuery(query.toString(), false, false);
query.setLength(0);
queryParams.forEach(this::clientQueryParamCommaSeparated);
}

private String create() {
return UriComponent.encodeTemplateNames(toTemplate());
}
Expand Down
Loading

0 comments on commit 48c4fb8

Please sign in to comment.