Deprecated #setQuery method; added method to set arbitrary custom query component

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1356775 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2012-07-03 15:02:44 +00:00
parent 9a17be0126
commit d545fdd180
3 changed files with 117 additions and 25 deletions

View File

@ -58,6 +58,7 @@ public class URIBuilder {
private String encodedPath;
private String encodedQuery;
private List<NameValuePair> queryParams;
private String query;
private String fragment;
private String encodedFragment;
@ -136,14 +137,23 @@ public class URIBuilder {
}
if (this.encodedQuery != null) {
sb.append("?").append(this.encodedQuery);
} else if (this.queryParams != null) {
sb.append("?").append(encodeQuery(this.queryParams));
} else if (this.query != null || this.queryParams != null) {
sb.append("?");
if (this.query != null) {
sb.append(encodeUric(this.query));
}
if (this.queryParams != null) {
if (this.query != null) {
sb.append("&");
}
sb.append(encodeUrlForm(this.queryParams));
}
}
}
if (this.encodedFragment != null) {
sb.append("#").append(this.encodedFragment);
} else if (this.fragment != null) {
sb.append("#").append(encodeFragment(this.fragment));
sb.append("#").append(encodeUric(this.fragment));
}
return sb.toString();
}
@ -172,12 +182,12 @@ public class URIBuilder {
return URLEncodedUtils.encPath(path, Consts.UTF_8);
}
private String encodeQuery(final List<NameValuePair> params) {
private String encodeUrlForm(final List<NameValuePair> params) {
return URLEncodedUtils.format(params, Consts.UTF_8);
}
private String encodeFragment(final String fragment) {
return URLEncodedUtils.encFragment(fragment, Consts.UTF_8);
private String encodeUric(final String fragment) {
return URLEncodedUtils.encUric(fragment, Consts.UTF_8);
}
/**
@ -243,6 +253,7 @@ public class URIBuilder {
*/
public URIBuilder removeQuery() {
this.queryParams = null;
this.query = null;
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
return this;
@ -252,14 +263,58 @@ public class URIBuilder {
* Sets URI query.
* <p>
* The value is expected to be encoded form data.
*
* @deprecated (4.3) use {@link #setParameters(List)} or {@link #setParameters(NameValuePair...)}
*
* @see URLEncodedUtils#parse
*/
@Deprecated
public URIBuilder setQuery(final String query) {
this.queryParams = parseQuery(query, Consts.UTF_8);
this.query = null;
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
return this;
}
/**
* Sets URI query parameters. The parameter name / values are expected to be unescaped
* and may contain non ASCII characters.
*
* @since 4.3
*/
public URIBuilder setParameters(final List <NameValuePair> nvps) {
if (this.queryParams == null) {
this.queryParams = new ArrayList<NameValuePair>();
} else {
this.queryParams.clear();
}
this.queryParams.addAll(nvps);
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
return this;
}
/**
* Sets URI query parameters. The parameter name / values are expected to be unescaped
* and may contain non ASCII characters.
*
* @since 4.3
*/
public URIBuilder setParameters(final NameValuePair... nvps) {
if (this.queryParams == null) {
this.queryParams = new ArrayList<NameValuePair>();
} else {
this.queryParams.clear();
}
for (NameValuePair nvp: nvps) {
this.queryParams.add(nvp);
}
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
return this;
}
/**
* Adds parameter to URI query. The parameter name and value are expected to be unescaped
* and may contain non ASCII characters.
@ -296,6 +351,31 @@ public class URIBuilder {
return this;
}
/**
* Clears URI query parameters.
*
* @since 4.3
*/
public URIBuilder clearParameters() {
this.queryParams = null;
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
return this;
}
/**
* Sets custom URI query. The value is expected to be unescaped and may contain non ASCII
* characters. Please note, this method does NOT override query parameters if set.
*
* @since 4.3
*/
public URIBuilder setCustomQuery(final String query) {
this.query = query;
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
return this;
}
/**
* Sets URI fragment. The value is expected to be unescaped and may contain non ASCII
* characters.

View File

@ -271,12 +271,15 @@ public class URLEncodedUtils {
* These are the additional characters allowed by userinfo.
*/
private static final BitSet PUNCT = new BitSet(256);
/** Characters which are safe to use in userinfo, i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation */
/** Characters which are safe to use in userinfo,
* i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation */
private static final BitSet USERINFO = new BitSet(256);
/** Characters which are safe to use in a path, i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation plus / @ */
/** Characters which are safe to use in a path,
* i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation plus / @ */
private static final BitSet PATHSAFE = new BitSet(256);
/** Characters which are safe to use in a fragment, i.e. {@link #RESERVED} plus {@link #UNRESERVED} */
private static final BitSet FRAGMENT = new BitSet(256);
/** Characters which are safe to use in a query or a fragment,
* i.e. {@link #RESERVED} plus {@link #UNRESERVED} */
private static final BitSet URIC = new BitSet(256);
/**
* Reserved characters, i.e. {@code ;/?:@&=+$,[]}
@ -355,8 +358,8 @@ public class URLEncodedUtils {
RESERVED.set('['); // added by RFC 2732
RESERVED.set(']'); // added by RFC 2732
FRAGMENT.or(RESERVED);
FRAGMENT.or(UNRESERVED);
URIC.or(RESERVED);
URIC.or(UNRESERVED);
}
private static final int RADIX = 16;
@ -516,16 +519,16 @@ public class URLEncodedUtils {
}
/**
* Encode a String using the {@link #FRAGMENT} set of characters.
* Encode a String using the {@link #URIC} set of characters.
* <p>
* Used by URIBuilder to encode the userinfo segment.
* Used by URIBuilder to encode the query and fragment segments.
*
* @param content the string to encode, does not convert space to '+'
* @param charset the charset to use
* @return the encoded string
*/
static String encFragment(final String content, final Charset charset) {
return urlencode(content, charset, FRAGMENT, false);
static String encUric(final String content, final Charset charset) {
return urlencode(content, charset, URIC, false);
}
/**

View File

@ -81,7 +81,7 @@ public class TestURIBuilder {
@Test
public void testOpaqueUriMutation() throws Exception {
URI uri = new URI("stuff", "some-stuff", "fragment");
URIBuilder uribuilder = new URIBuilder(uri).setQuery("param1&param2=stuff").setFragment(null);
URIBuilder uribuilder = new URIBuilder(uri).setCustomQuery("param1&param2=stuff").setFragment(null);
Assert.assertEquals(new URI("stuff:?param1&param2=stuff"), uribuilder.build());
}
@ -153,6 +153,18 @@ public class TestURIBuilder {
Assert.assertEquals(uri1, uri2);
}
@Test
public void testQueryAndParameterEncoding() throws Exception {
URI uri1 = new URI("https://somehost.com/stuff?this&that" +
"&param1=12345&param2=67890");
URI uri2 = new URIBuilder("https://somehost.com/stuff")
.setCustomQuery("this&that")
.clearParameters()
.addParameter("param1","12345")
.addParameter("param2","67890").build();
Assert.assertEquals(uri1, uri2);
}
@Test
public void testPathEncoding() throws Exception {
URI uri1 = new URI("https://somehost.com/some%20path%20with%20blanks/");
@ -177,7 +189,7 @@ public class TestURIBuilder {
.setHost(host)
.setUserInfo(specials)
.setPath(specials)
.addParameter(specials, null) // hack to bypass parsing of query data
.setCustomQuery(specials)
.setFragment(specials)
.build();
@ -198,18 +210,15 @@ public class TestURIBuilder {
// Check that the encoded URI generated by URI builder agrees with that generated by using URI directly
final String scheme="https";
final String host="localhost";
final String specials="/ abcd!$&*()_-+.,=:;'~<>/@[]|#^%\"{}\\`xyz"; // N.B. excludes \u00a3`\u00ac\u00a6
final String formdatasafe = "abcd-_.*zyz";
URI uri = new URI(scheme, specials, host, 80, specials,
formdatasafe, // TODO replace with specials when supported
specials);
final String specials="/ abcd!$&*()_-+.,=:;'~<>/@[]|#^%\"{}\\`xyz"; // N.B. excludes \u00a3\u00ac\u00a6
URI uri = new URI(scheme, specials, host, 80, specials, specials, specials);
URI bld = new URIBuilder()
.setScheme(scheme)
.setHost(host)
.setUserInfo(specials)
.setPath(specials)
.addParameter(formdatasafe, null) // TODO replace with specials when supported
.setCustomQuery(specials)
.setFragment(specials)
.build();