2424import java .util .HashMap ;
2525import java .util .List ;
2626import java .util .Map ;
27+ import java .util .Objects ;
28+ import java .util .stream .Collectors ;
29+ import java .util .stream .Stream ;
2730
2831import javax .ws .rs .Path ;
2932import javax .ws .rs .core .MultivaluedMap ;
@@ -79,6 +82,7 @@ public class JerseyUriBuilder extends UriBuilder {
7982 public JerseyUriBuilder () {
8083 path = new StringBuilder ();
8184 query = new StringBuilder ();
85+ queryParamStyle = JerseyQueryParamStyle .MULTI_PAIRS ;
8286 }
8387
8488 private JerseyUriBuilder (final JerseyUriBuilder that ) {
@@ -93,6 +97,7 @@ private JerseyUriBuilder(final JerseyUriBuilder that) {
9397 this .query = new StringBuilder (that .query );
9498 this .queryParams = that .queryParams == null ? null : new MultivaluedStringMap (that .queryParams );
9599 this .fragment = that .fragment ;
100+ this .queryParamStyle = that .queryParamStyle ;
96101 }
97102
98103 @ SuppressWarnings ("CloneDoesntCallSuperClone" )
@@ -539,22 +544,32 @@ public JerseyUriBuilder queryParam(String name, final Object... values) {
539544 }
540545
541546 name = encode (name , UriComponent .Type .QUERY_PARAM );
542- if (null == queryParamStyle ) {
543- clientQueryParamMultiPairs (name , values );
544- } else switch (queryParamStyle ) {
545- case ARRAY_PAIRS :
546- clientQueryParamArrayPairs (name , values );
547- break ;
548- case COMMA_SEPARATED :
549- clientQueryParamCommaSeparated (name , values );
550- break ;
551- default :
552- clientQueryParamMultiPairs (name , values );
553- break ;
547+
548+ List <String > stringsValues = Stream .of (values )
549+ .map (this ::convertToString )
550+ .map (value -> encode (value , UriComponent .Type .QUERY_PARAM ))
551+ .collect (Collectors .toList ());
552+
553+ switch (queryParamStyle ) {
554+ case ARRAY_PAIRS :
555+ clientQueryParamArrayPairs (name , stringsValues );
556+ break ;
557+ case COMMA_SEPARATED :
558+ clientQueryParamCommaSeparated (name , stringsValues );
559+ break ;
560+ default :
561+ clientQueryParamMultiPairs (name , stringsValues );
554562 }
555563 return this ;
556564 }
557565
566+ private String convertToString (Object value ) {
567+ if (value == null ) {
568+ throw new IllegalArgumentException (LocalizationMessages .QUERY_PARAM_NULL ());
569+ }
570+ return value .toString ();
571+ }
572+
558573 /**
559574 * Multiple parameter instances, e.g foo=v1&foot=v2&foo=v3 This is
560575 * the default if no style is configured.
@@ -563,27 +578,17 @@ public JerseyUriBuilder queryParam(String name, final Object... values) {
563578 * @param values
564579 * @throws IllegalArgumentException
565580 */
566- private void clientQueryParamMultiPairs (String name , final Object ... values ) {
581+ private void clientQueryParamMultiPairs (String name , List < String > values ) {
567582 if (queryParams == null ) {
568- for (final Object value : values ) {
583+ for (final String value : values ) {
569584 if (query .length () > 0 ) {
570585 query .append ('&' );
571586 }
572- query .append (name );
573-
574- if (value == null ) {
575- throw new IllegalArgumentException (LocalizationMessages .QUERY_PARAM_NULL ());
576- }
577-
578- query .append ('=' ).append (encode (value .toString (), UriComponent .Type .QUERY_PARAM ));
587+ query .append (name ).append ('=' ).append (value );
579588 }
580589 } else {
581- for (final Object value : values ) {
582- if (value == null ) {
583- throw new IllegalArgumentException (LocalizationMessages .QUERY_PARAM_NULL ());
584- }
585-
586- queryParams .add (name , encode (value .toString (), UriComponent .Type .QUERY_PARAM ));
590+ for (final String value : values ) {
591+ queryParams .add (name , value );
587592 }
588593 }
589594 }
@@ -596,40 +601,15 @@ private void clientQueryParamMultiPairs(String name, final Object... values) {
596601 * @param values
597602 * @throws IllegalArgumentException
598603 */
599- private void clientQueryParamCommaSeparated (String name , final Object ... values ) throws IllegalArgumentException {
600- StringBuilder sb = new StringBuilder ();
604+ private void clientQueryParamCommaSeparated (String name , List <String > values ) throws IllegalArgumentException {
601605 if (queryParams == null ) {
602606 if (query .length () > 0 ) {
603607 query .append ('&' );
604608 }
605- query .append (name );
606- int valuesCount = values .length - 1 ;
607- for (final Object value : values ) {
608- if (value == null ) {
609- throw new IllegalArgumentException (LocalizationMessages .QUERY_PARAM_NULL ());
610- }
611- sb .append (encode (value .toString (), UriComponent .Type .QUERY_PARAM ));
612- if (valuesCount > 0 ) {
613- sb .append ("," );
614- --valuesCount ;
615- }
616- }
617- query .append ('=' ).append (sb .toString ());
609+ query .append (name ).append ('=' ).append (String .join ("," , values ));
618610 } else {
619- int valuesCount = values .length - 1 ;
620- for (final Object value : values ) {
621- if (value == null ) {
622- throw new IllegalArgumentException (LocalizationMessages .QUERY_PARAM_NULL ());
623- }
624- sb .append (encode (value .toString (), UriComponent .Type .QUERY_PARAM ));
625- if (valuesCount > 0 ) {
626- sb .append ("," );
627- --valuesCount ;
628- }
629- }
630- queryParams .add (name , sb .toString ());
611+ queryParams .add (name , String .join ("," , values ));
631612 }
632-
633613 }
634614
635615 /**
@@ -640,37 +620,24 @@ private void clientQueryParamCommaSeparated(String name, final Object... values)
640620 * @param values
641621 * @throws IllegalArgumentException
642622 */
643- private void clientQueryParamArrayPairs (String name , final Object ... values ) throws IllegalArgumentException {
623+ private void clientQueryParamArrayPairs (String name , List < String > values ) throws IllegalArgumentException {
644624 if (queryParams == null ) {
645- for (final Object value : values ) {
625+ for (final String value : values ) {
646626 if (query .length () > 0 ) {
647627 query .append ('&' );
648628 }
649- query .append (name ).append ("[]" );
650-
651- if (value == null ) {
652- throw new IllegalArgumentException (LocalizationMessages .QUERY_PARAM_NULL ());
653- }
654-
655- query .append ('=' ).append (encode (value .toString (), UriComponent .Type .QUERY_PARAM ));
629+ query .append (name ).append ("[]" ).append ('=' ).append (value );
656630 }
657631 } else {
658- for (final Object value : values ) {
659- if (value == null ) {
660- throw new IllegalArgumentException (LocalizationMessages .QUERY_PARAM_NULL ());
661- }
662-
663- queryParams .add (name + "[]" , encode (value .toString (), UriComponent .Type .QUERY_PARAM ));
632+ for (final String value : values ) {
633+ queryParams .add (name + "[]" , value );
664634 }
665635 }
666636 }
667637
668- public JerseyQueryParamStyle getQueryParamStyle () {
669- return queryParamStyle ;
670- }
671-
672- public void setQueryParamStyle (JerseyQueryParamStyle queryParamStyle ) {
673- this .queryParamStyle = queryParamStyle ;
638+ public JerseyUriBuilder setQueryParamStyle (JerseyQueryParamStyle queryParamStyle ) {
639+ this .queryParamStyle = Objects .requireNonNull (queryParamStyle );
640+ return this ;
674641 }
675642
676643 @ Override
@@ -780,7 +747,7 @@ private JerseyUriBuilder resolveTemplates(final Map<String, Object> templateValu
780747 path .append (newPath );
781748
782749 final String newQuery = UriTemplate .resolveTemplateValues (UriComponent .Type .QUERY_PARAM , query .toString (), encode ,
783- templateValues );
750+ templateValues );
784751 query .setLength (0 );
785752 query .append (newQuery );
786753
@@ -827,7 +794,7 @@ private void appendPath(String segments, final boolean isSegment) {
827794 encodeMatrix ();
828795
829796 segments = encode (segments ,
830- (isSegment ) ? UriComponent .Type .PATH_SEGMENT : UriComponent .Type .PATH );
797+ (isSegment ) ? UriComponent .Type .PATH_SEGMENT : UriComponent .Type .PATH );
831798
832799 final boolean pathEndsInSlash = path .length () > 0 && path .charAt (path .length () - 1 ) == '/' ;
833800 final boolean segmentStartsWithSlash = segments .charAt (0 ) == '/' ;
@@ -998,6 +965,9 @@ private URI _build(final boolean encode, final boolean encodeSlashInPath, final
998965
999966 encodeMatrix ();
1000967 encodeQuery ();
968+ if (queryParamStyle == JerseyQueryParamStyle .COMMA_SEPARATED ) {
969+ groupQueryParams ();
970+ }
1001971
1002972 final String uri = UriTemplate .createURI (
1003973 scheme , authority ,
@@ -1006,6 +976,12 @@ private URI _build(final boolean encode, final boolean encodeSlashInPath, final
1006976 return createURI (uri );
1007977 }
1008978
979+ private void groupQueryParams () {
980+ MultivaluedMap <String , String > queryParams = UriComponent .decodeQuery (query .toString (), false , false );
981+ query .setLength (0 );
982+ queryParams .forEach (this ::clientQueryParamCommaSeparated );
983+ }
984+
1009985 private String create () {
1010986 return UriComponent .encodeTemplateNames (toTemplate ());
1011987 }
0 commit comments