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 client 2.0 updates #4724

Merged
merged 3 commits into from
Feb 18, 2021
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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down 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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down 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);
Verdent marked this conversation as resolved.
Show resolved Hide resolved
}
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