Skip to content

Commit 261956f

Browse files
committed
Improve UriBuilder Javadoc on query params
Add a note on encoding for query parameters specifically mentioning the "+" sign and a link to the reference docs. Also remove duplicate Javadoc in UriComponentsBuilder which is already inherited from UriBuilder.
1 parent a1b8b18 commit 261956f

File tree

3 files changed

+48
-145
lines changed

3 files changed

+48
-145
lines changed

spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ public int hashCode() {
588588
/**
589589
* Enumeration used to identify the allowed characters per URI component.
590590
* <p>Contains methods to indicate whether a given character is valid in a specific URI component.
591-
* @see <a href="https://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>
591+
* @see <a href="https://tools.ietf.org/html/rfc3986">RFC 3986</a>
592592
*/
593593
enum Type {
594594

spring-web/src/main/java/org/springframework/web/util/UriBuilder.java

+45-25
Original file line numberDiff line numberDiff line change
@@ -98,42 +98,51 @@ public interface UriBuilder {
9898
UriBuilder pathSegment(String... pathSegments) throws IllegalArgumentException;
9999

100100
/**
101-
* Append the given query to the existing query of this builder.
102-
* The given query may contain URI template variables.
103-
* <p><strong>Note:</strong> The presence of reserved characters can prevent
104-
* correct parsing of the URI string. For example if a query parameter
105-
* contains {@code '='} or {@code '&'} characters, the query string cannot
106-
* be parsed unambiguously. Such values should be substituted for URI
107-
* variables to enable correct parsing:
108-
* <pre class="code">
109-
* builder.query(&quot;filter={value}&quot;).uriString(&quot;hot&amp;cold&quot;);
110-
* </pre>
101+
* Parse the given query string into query parameters where parameters are
102+
* separated with {@code '&'} and their values, if any, with {@code '='}.
103+
* The query may contain URI template variables.
104+
* <p><strong>Note: </strong> please, review the Javadoc of
105+
* {@link #queryParam(String, Object...)} for further notes on the treatment
106+
* and encoding of individual query parameters.
111107
* @param query the query string
112108
*/
113109
UriBuilder query(String query);
114110

115111
/**
116-
* Set the query of this builder overriding all existing query parameters.
117-
* @param query the query string, or {@code null} to remove all query params
112+
* Clear existing query parameters and then delegate to {@link #query(String)}.
113+
* <p><strong>Note: </strong> please, review the Javadoc of
114+
* {@link #queryParam(String, Object...)} for further notes on the treatment
115+
* and encoding of individual query parameters.
116+
* @param query the query string; a {@code null} value removes all query parameters.
118117
*/
119118
UriBuilder replaceQuery(@Nullable String query);
120119

121120
/**
122-
* Append the given query parameter to the existing query parameters. The
123-
* given name or any of the values may contain URI template variables. If no
121+
* Append the given query parameter. Both the parameter name and values may
122+
* contain URI template variables to be expanded later from values. If no
124123
* values are given, the resulting URI will contain the query parameter name
125-
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}.
124+
* only, e.g. {@code "?foo"} instead of {@code "?foo=bar"}.
125+
* <p><strong>Note:</strong> encoding, if applied, will only encode characters
126+
* that are illegal in a query parameter name or value such as {@code "="}
127+
* or {@code "&"}. All others that are legal as per syntax rules in
128+
* <a href="https://tools.ietf.org/html/rfc3986">RFC 3986</a> are not
129+
* encoded. This includes {@code "+"} which sometimes needs to be encoded
130+
* to avoid its interpretation as an encoded space. Stricter encoding may
131+
* be applied by using a URI template variable along with stricter encoding
132+
* on variable values. For more details please read the
133+
* <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#web-uri-encoding">"URI Encoding"</a>
134+
* section of the Spring Framework reference.
126135
* @param name the query parameter name
127136
* @param values the query parameter values
128137
* @see #queryParam(String, Collection)
129138
*/
130139
UriBuilder queryParam(String name, Object... values);
131140

132141
/**
133-
* Append the given query parameter to the existing query parameters. The
134-
* given name or any of the values may contain URI template variables. If no
135-
* values are given, the resulting URI will contain the query parameter name
136-
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}.
142+
* Variant of {@link #queryParam(String, Object...)} with a Collection.
143+
* <p><strong>Note: </strong> please, review the Javadoc of
144+
* {@link #queryParam(String, Object...)} for further notes on the treatment
145+
* and encoding of individual query parameters.
137146
* @param name the query parameter name
138147
* @param values the query parameter values
139148
* @since 5.2
@@ -142,23 +151,31 @@ public interface UriBuilder {
142151
UriBuilder queryParam(String name, @Nullable Collection<?> values);
143152

144153
/**
145-
* Add the given query parameters.
154+
* Add multiple query parameters and values.
155+
* <p><strong>Note: </strong> please, review the Javadoc of
156+
* {@link #queryParam(String, Object...)} for further notes on the treatment
157+
* and encoding of individual query parameters.
146158
* @param params the params
147159
*/
148160
UriBuilder queryParams(MultiValueMap<String, String> params);
149161

150162
/**
151-
* Set the query parameter values overriding all existing query values for
152-
* the same parameter. If no values are given, the query parameter is removed.
163+
* Set the query parameter values replacing existing values, or if no
164+
* values are given, the query parameter is removed.
165+
* <p><strong>Note: </strong> please, review the Javadoc of
166+
* {@link #queryParam(String, Object...)} for further notes on the treatment
167+
* and encoding of individual query parameters.
153168
* @param name the query parameter name
154169
* @param values the query parameter values
155170
* @see #replaceQueryParam(String, Collection)
156171
*/
157172
UriBuilder replaceQueryParam(String name, Object... values);
158173

159174
/**
160-
* Set the query parameter values overriding all existing query values for
161-
* the same parameter. If no values are given, the query parameter is removed.
175+
* Variant of {@link #replaceQueryParam(String, Object...)} with a Collection.
176+
* <p><strong>Note: </strong> please, review the Javadoc of
177+
* {@link #queryParam(String, Object...)} for further notes on the treatment
178+
* and encoding of individual query parameters.
162179
* @param name the query parameter name
163180
* @param values the query parameter values
164181
* @since 5.2
@@ -167,7 +184,10 @@ public interface UriBuilder {
167184
UriBuilder replaceQueryParam(String name, @Nullable Collection<?> values);
168185

169186
/**
170-
* Set the query parameter values overriding all existing query values.
187+
* Set the query parameter values after removing all existing ones.
188+
* <p><strong>Note: </strong> please, review the Javadoc of
189+
* {@link #queryParam(String, Object...)} for further notes on the treatment
190+
* and encoding of individual query parameters.
171191
* @param params the query parameter name
172192
*/
173193
UriBuilder replaceQueryParams(MultiValueMap<String, String> params);

spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java

+2-119
Original file line numberDiff line numberDiff line change
@@ -521,12 +521,6 @@ public UriComponentsBuilder uriComponents(UriComponents uriComponents) {
521521
return this;
522522
}
523523

524-
/**
525-
* Set the URI scheme. The given scheme may contain URI template variables,
526-
* and may also be {@code null} to clear the scheme of this builder.
527-
* @param scheme the URI scheme
528-
* @return this UriComponentsBuilder
529-
*/
530524
@Override
531525
public UriComponentsBuilder scheme(@Nullable String scheme) {
532526
this.scheme = scheme;
@@ -547,37 +541,20 @@ public UriComponentsBuilder schemeSpecificPart(String ssp) {
547541
return this;
548542
}
549543

550-
/**
551-
* Set the URI user info. The given user info may contain URI template variables,
552-
* and may also be {@code null} to clear the user info of this builder.
553-
* @param userInfo the URI user info
554-
* @return this UriComponentsBuilder
555-
*/
556544
@Override
557545
public UriComponentsBuilder userInfo(@Nullable String userInfo) {
558546
this.userInfo = userInfo;
559547
resetSchemeSpecificPart();
560548
return this;
561549
}
562550

563-
/**
564-
* Set the URI host. The given host may contain URI template variables,
565-
* and may also be {@code null} to clear the host of this builder.
566-
* @param host the URI host
567-
* @return this UriComponentsBuilder
568-
*/
569551
@Override
570552
public UriComponentsBuilder host(@Nullable String host) {
571553
this.host = host;
572554
resetSchemeSpecificPart();
573555
return this;
574556
}
575557

576-
/**
577-
* Set the URI port. Passing {@code -1} will clear the port of this builder.
578-
* @param port the URI port
579-
* @return this UriComponentsBuilder
580-
*/
581558
@Override
582559
public UriComponentsBuilder port(int port) {
583560
Assert.isTrue(port >= -1, "Port must be >= -1");
@@ -586,52 +563,27 @@ public UriComponentsBuilder port(int port) {
586563
return this;
587564
}
588565

589-
/**
590-
* Set the URI port. Use this method only when the port needs to be
591-
* parameterized with a URI variable. Otherwise use {@link #port(int)}.
592-
* Passing {@code null} will clear the port of this builder.
593-
* @param port the URI port
594-
* @return this UriComponentsBuilder
595-
*/
596566
@Override
597567
public UriComponentsBuilder port(@Nullable String port) {
598568
this.port = port;
599569
resetSchemeSpecificPart();
600570
return this;
601571
}
602572

603-
/**
604-
* Append the given path to the existing path of this builder.
605-
* The given path may contain URI template variables.
606-
* @param path the URI path
607-
* @return this UriComponentsBuilder
608-
*/
609573
@Override
610574
public UriComponentsBuilder path(String path) {
611575
this.pathBuilder.addPath(path);
612576
resetSchemeSpecificPart();
613577
return this;
614578
}
615579

616-
/**
617-
* Append path segments to the existing path. Each path segment may contain
618-
* URI template variables and should not contain any slashes.
619-
* Use {@code path("/")} subsequently to ensure a trailing slash.
620-
* @param pathSegments the URI path segments
621-
* @return this UriComponentsBuilder
622-
*/
623580
@Override
624581
public UriComponentsBuilder pathSegment(String... pathSegments) throws IllegalArgumentException {
625582
this.pathBuilder.addPathSegments(pathSegments);
626583
resetSchemeSpecificPart();
627584
return this;
628585
}
629586

630-
/**
631-
* Set the path of this builder overriding all existing path and path segment values.
632-
* @param path the URI path (a {@code null} value results in an empty path)
633-
* @return this UriComponentsBuilder
634-
*/
635587
@Override
636588
public UriComponentsBuilder replacePath(@Nullable String path) {
637589
this.pathBuilder = new CompositePathComponentBuilder();
@@ -642,22 +594,6 @@ public UriComponentsBuilder replacePath(@Nullable String path) {
642594
return this;
643595
}
644596

645-
/**
646-
* Append the given query to the existing query of this builder.
647-
* The given query may contain URI template variables.
648-
* <p><strong>Note:</strong> The presence of reserved characters can prevent
649-
* correct parsing of the URI string. For example if a query parameter
650-
* contains {@code '='} or {@code '&'} characters, the query string cannot
651-
* be parsed unambiguously. Such values should be substituted for URI
652-
* variables to enable correct parsing:
653-
* <pre class="code">
654-
* UriComponentsBuilder.fromUriString(&quot;/hotels/42&quot;)
655-
* .query(&quot;filter={value}&quot;)
656-
* .buildAndExpand(&quot;hot&amp;cold&quot;);
657-
* </pre>
658-
* @param query the query string
659-
* @return this UriComponentsBuilder
660-
*/
661597
@Override
662598
public UriComponentsBuilder query(@Nullable String query) {
663599
if (query != null) {
@@ -676,11 +612,6 @@ public UriComponentsBuilder query(@Nullable String query) {
676612
return this;
677613
}
678614

679-
/**
680-
* Set the query of this builder overriding all existing query parameters.
681-
* @param query the query string; a {@code null} value removes all query parameters.
682-
* @return this UriComponentsBuilder
683-
*/
684615
@Override
685616
public UriComponentsBuilder replaceQuery(@Nullable String query) {
686617
this.queryParams.clear();
@@ -691,16 +622,6 @@ public UriComponentsBuilder replaceQuery(@Nullable String query) {
691622
return this;
692623
}
693624

694-
/**
695-
* Append the given query parameter to the existing query parameters. The
696-
* given name or any of the values may contain URI template variables. If no
697-
* values are given, the resulting URI will contain the query parameter name
698-
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}).
699-
* @param name the query parameter name
700-
* @param values the query parameter values
701-
* @return this UriComponentsBuilder
702-
* @see #queryParam(String, Collection)
703-
*/
704625
@Override
705626
public UriComponentsBuilder queryParam(String name, Object... values) {
706627
Assert.notNull(name, "Name must not be null");
@@ -717,26 +638,13 @@ public UriComponentsBuilder queryParam(String name, Object... values) {
717638
return this;
718639
}
719640

720-
/**
721-
* Append the given query parameter to the existing query parameters. The
722-
* given name or any of the values may contain URI template variables. If no
723-
* values are given, the resulting URI will contain the query parameter name
724-
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}).
725-
* @param name the query parameter name
726-
* @param values the query parameter values
727-
* @return this UriComponentsBuilder
728-
* @since 5.2
729-
* @see #queryParam(String, Object...)
730-
*/
731641
@Override
732642
public UriComponentsBuilder queryParam(String name, @Nullable Collection<?> values) {
733643
return queryParam(name, values != null ? values.toArray() : EMPTY_VALUES);
734644
}
735645

736646
/**
737-
* Add the given query parameters.
738-
* @param params the params
739-
* @return this UriComponentsBuilder
647+
* {@inheritDoc}
740648
* @since 4.0
741649
*/
742650
@Override
@@ -747,14 +655,6 @@ public UriComponentsBuilder queryParams(@Nullable MultiValueMap<String, String>
747655
return this;
748656
}
749657

750-
/**
751-
* Set the query parameter values overriding all existing query values for
752-
* the same parameter. If no values are given, the query parameter is removed.
753-
* @param name the query parameter name
754-
* @param values the query parameter values
755-
* @return this UriComponentsBuilder
756-
* @see #replaceQueryParam(String, Collection)
757-
*/
758658
@Override
759659
public UriComponentsBuilder replaceQueryParam(String name, Object... values) {
760660
Assert.notNull(name, "Name must not be null");
@@ -766,24 +666,13 @@ public UriComponentsBuilder replaceQueryParam(String name, Object... values) {
766666
return this;
767667
}
768668

769-
/**
770-
* Set the query parameter values overriding all existing query values for
771-
* the same parameter. If no values are given, the query parameter is removed.
772-
* @param name the query parameter name
773-
* @param values the query parameter values
774-
* @return this UriComponentsBuilder
775-
* @see #replaceQueryParam(String, Object...)
776-
* @since 5.2
777-
*/
778669
@Override
779670
public UriComponentsBuilder replaceQueryParam(String name, @Nullable Collection<?> values) {
780671
return replaceQueryParam(name, values != null ? values.toArray() : EMPTY_VALUES);
781672
}
782673

783674
/**
784-
* Set the query parameter values overriding all existing query values.
785-
* @param params the query parameter name
786-
* @return this UriComponentsBuilder
675+
* {@inheritDoc}
787676
* @since 4.2
788677
*/
789678
@Override
@@ -795,12 +684,6 @@ public UriComponentsBuilder replaceQueryParams(@Nullable MultiValueMap<String, S
795684
return this;
796685
}
797686

798-
/**
799-
* Set the URI fragment. The given fragment may contain URI template variables,
800-
* and may also be {@code null} to clear the fragment of this builder.
801-
* @param fragment the URI fragment
802-
* @return this UriComponentsBuilder
803-
*/
804687
@Override
805688
public UriComponentsBuilder fragment(@Nullable String fragment) {
806689
if (fragment != null) {

0 commit comments

Comments
 (0)