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 encodedPath;
private String encodedQuery; private String encodedQuery;
private List<NameValuePair> queryParams; private List<NameValuePair> queryParams;
private String query;
private String fragment; private String fragment;
private String encodedFragment; private String encodedFragment;
@ -136,14 +137,23 @@ public class URIBuilder {
} }
if (this.encodedQuery != null) { if (this.encodedQuery != null) {
sb.append("?").append(this.encodedQuery); sb.append("?").append(this.encodedQuery);
} else if (this.queryParams != null) { } else if (this.query != null || this.queryParams != null) {
sb.append("?").append(encodeQuery(this.queryParams)); 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) { if (this.encodedFragment != null) {
sb.append("#").append(this.encodedFragment); sb.append("#").append(this.encodedFragment);
} else if (this.fragment != null) { } else if (this.fragment != null) {
sb.append("#").append(encodeFragment(this.fragment)); sb.append("#").append(encodeUric(this.fragment));
} }
return sb.toString(); return sb.toString();
} }
@ -172,12 +182,12 @@ public class URIBuilder {
return URLEncodedUtils.encPath(path, Consts.UTF_8); 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); return URLEncodedUtils.format(params, Consts.UTF_8);
} }
private String encodeFragment(final String fragment) { private String encodeUric(final String fragment) {
return URLEncodedUtils.encFragment(fragment, Consts.UTF_8); return URLEncodedUtils.encUric(fragment, Consts.UTF_8);
} }
/** /**
@ -243,6 +253,7 @@ public class URIBuilder {
*/ */
public URIBuilder removeQuery() { public URIBuilder removeQuery() {
this.queryParams = null; this.queryParams = null;
this.query = null;
this.encodedQuery = null; this.encodedQuery = null;
this.encodedSchemeSpecificPart = null; this.encodedSchemeSpecificPart = null;
return this; return this;
@ -252,14 +263,58 @@ public class URIBuilder {
* Sets URI query. * Sets URI query.
* <p> * <p>
* The value is expected to be encoded form data. * 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) { public URIBuilder setQuery(final String query) {
this.queryParams = parseQuery(query, Consts.UTF_8); this.queryParams = parseQuery(query, Consts.UTF_8);
this.query = null;
this.encodedQuery = null; this.encodedQuery = null;
this.encodedSchemeSpecificPart = null; this.encodedSchemeSpecificPart = null;
return this; 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 * Adds parameter to URI query. The parameter name and value are expected to be unescaped
* and may contain non ASCII characters. * and may contain non ASCII characters.
@ -296,6 +351,31 @@ public class URIBuilder {
return this; 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 * Sets URI fragment. The value is expected to be unescaped and may contain non ASCII
* characters. * characters.

View File

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

View File

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