fix UrlQuery

This commit is contained in:
Looly 2021-11-07 03:23:44 +08:00
parent a5adc9ae94
commit 941e4f39ca
5 changed files with 76 additions and 19 deletions

View File

@ -67,10 +67,13 @@ public class URLDecoder implements Serializable {
*
* @param str 包含URL编码后的字符串
* @param isPlusToSpace 是否+转换为空格
* @param charset 编码
* @param charset 编码{@code null}表示不做编码
* @return 解码后的字符串
*/
public static String decode(String str, Charset charset, boolean isPlusToSpace) {
if(null == charset){
return str;
}
return StrUtil.str(decode(StrUtil.bytes(str, charset), isPlusToSpace), charset);
}

View File

@ -6,9 +6,10 @@ import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.TableMap;
import cn.hutool.core.net.FormUrlencoded;
import cn.hutool.core.net.RFC3986;
import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import java.nio.charset.Charset;
import java.util.Iterator;
@ -26,6 +27,10 @@ import java.util.Map;
public class UrlQuery {
private final TableMap<CharSequence, CharSequence> query;
/**
* 是否为x-www-form-urlencoded模式此模式下空格会编码为'+'
*/
private final boolean isFormUrlEncoded;
/**
* 构建UrlQuery
@ -37,6 +42,17 @@ public class UrlQuery {
return new UrlQuery(queryMap);
}
/**
* 构建UrlQuery
*
* @param queryMap 初始化的查询键值对
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式此模式下空格会编码为'+'
* @return UrlQuery
*/
public static UrlQuery of(Map<? extends CharSequence, ?> queryMap, boolean isFormUrlEncoded) {
return new UrlQuery(queryMap, isFormUrlEncoded);
}
/**
* 构建UrlQuery
*
@ -58,9 +74,21 @@ public class UrlQuery {
* @since 5.5.8
*/
public static UrlQuery of(String queryStr, Charset charset, boolean autoRemovePath) {
final UrlQuery urlQuery = new UrlQuery();
urlQuery.parse(queryStr, charset, autoRemovePath);
return urlQuery;
return of(queryStr, charset, autoRemovePath, false);
}
/**
* 构建UrlQuery
*
* @param queryStr 初始化的查询字符串
* @param charset decode用的编码null表示不做decode
* @param autoRemovePath 是否自动去除path部分{@code true}则自动去除第一个?前的内容
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式此模式下空格会编码为'+'
* @return UrlQuery
* @since 5.7.16
*/
public static UrlQuery of(String queryStr, Charset charset, boolean autoRemovePath, boolean isFormUrlEncoded) {
return new UrlQuery(isFormUrlEncoded).parse(queryStr, charset, autoRemovePath);
}
/**
@ -73,15 +101,37 @@ public class UrlQuery {
/**
* 构造
*
* @param queryMap 初始化的查询键值对
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式此模式下空格会编码为'+'
* @since 5.7.16
*/
public UrlQuery(boolean isFormUrlEncoded) {
this(null, isFormUrlEncoded);
}
/**
* 构造
*
* @param queryMap 初始化的查询键值对
*/
public UrlQuery(Map<? extends CharSequence, ?> queryMap) {
this(queryMap, false);
}
/**
* 构造
*
* @param queryMap 初始化的查询键值对
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式此模式下空格会编码为'+'
* @since 5.7.16
*/
public UrlQuery(Map<? extends CharSequence, ?> queryMap, boolean isFormUrlEncoded) {
if (MapUtil.isNotEmpty(queryMap)) {
query = new TableMap<>(queryMap.size());
addAll(queryMap);
} else {
query = new TableMap<>(MapUtil.DEFAULT_INITIAL_CAPACITY);
}
this.isFormUrlEncoded = isFormUrlEncoded;
}
/**
@ -182,6 +232,10 @@ public class UrlQuery {
* @return URL查询字符串
*/
public String build(Charset charset) {
if (isFormUrlEncoded) {
return build(FormUrlencoded.ALL, FormUrlencoded.ALL, charset);
}
return build(RFC3986.QUERY_PARAM_NAME, RFC3986.QUERY_PARAM_VALUE, charset);
}
@ -315,11 +369,11 @@ public class UrlQuery {
*/
private void addParam(String key, String value, Charset charset) {
if (null != key) {
final String actualKey = URLUtil.decode(key, charset);
this.query.put(actualKey, StrUtil.nullToEmpty(URLUtil.decode(value, charset)));
final String actualKey = URLDecoder.decode(key, charset, isFormUrlEncoded);
this.query.put(actualKey, StrUtil.nullToEmpty(URLDecoder.decode(value, charset, isFormUrlEncoded)));
} else if (null != value) {
// name为空value作为namevalue赋值null
this.query.put(URLUtil.decode(value, charset), null);
this.query.put(URLDecoder.decode(value, charset, isFormUrlEncoded), null);
}
}
}

View File

@ -328,9 +328,6 @@ public class URLUtil extends URLEncodeUtil {
* @since 4.4.1
*/
public static String decode(String content, Charset charset) {
if (null == charset) {
return content;
}
return URLDecoder.decode(content, charset);
}
@ -345,9 +342,6 @@ public class URLUtil extends URLEncodeUtil {
* @since 5.6.3
*/
public static String decode(String content, Charset charset, boolean isPlusToSpace) {
if (null == charset) {
return content;
}
return URLDecoder.decode(content, charset, isPlusToSpace);
}
@ -361,7 +355,7 @@ public class URLUtil extends URLEncodeUtil {
* @throws UtilException UnsupportedEncodingException
*/
public static String decode(String content, String charset) throws UtilException {
return decode(content, CharsetUtil.charset(charset));
return decode(content, StrUtil.isEmpty(charset) ? null : CharsetUtil.charset(charset));
}
/**

View File

@ -108,6 +108,14 @@ public class UrlQueryTest {
Assert.assertEquals("a+b=1+2", a);
}
@Test
public void parsePlusTest(){
// 根据RFC3986在URL中+是安全字符即此符号不转义
final String a = UrlQuery.of("a+b=1+2", CharsetUtil.CHARSET_UTF_8)
.build(CharsetUtil.CHARSET_UTF_8);
Assert.assertEquals("a+b=1+2", a);
}
@Test
public void spaceTest(){
// 根据RFC3986在URL中空格编码为"%20"

View File

@ -10,7 +10,6 @@ import cn.hutool.core.io.resource.MultiFileResource;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.net.FormUrlencoded;
import cn.hutool.core.net.SSLUtil;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.net.url.UrlQuery;
@ -1229,8 +1228,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
* @since 5.3.2
*/
private String getFormUrlEncoded() {
return UrlQuery.of(this.form)
.build(FormUrlencoded.ALL, FormUrlencoded.ALL, this.charset);
return UrlQuery.of(this.form, true).build(this.charset);
}
/**