mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix UrlQuery
This commit is contained in:
parent
a5adc9ae94
commit
941e4f39ca
@ -67,10 +67,13 @@ public class URLDecoder implements Serializable {
|
|||||||
*
|
*
|
||||||
* @param str 包含URL编码后的字符串
|
* @param str 包含URL编码后的字符串
|
||||||
* @param isPlusToSpace 是否+转换为空格
|
* @param isPlusToSpace 是否+转换为空格
|
||||||
* @param charset 编码
|
* @param charset 编码,{@code null}表示不做编码
|
||||||
* @return 解码后的字符串
|
* @return 解码后的字符串
|
||||||
*/
|
*/
|
||||||
public static String decode(String str, Charset charset, boolean isPlusToSpace) {
|
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);
|
return StrUtil.str(decode(StrUtil.bytes(str, charset), isPlusToSpace), charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,10 @@ import cn.hutool.core.collection.IterUtil;
|
|||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.map.TableMap;
|
import cn.hutool.core.map.TableMap;
|
||||||
|
import cn.hutool.core.net.FormUrlencoded;
|
||||||
import cn.hutool.core.net.RFC3986;
|
import cn.hutool.core.net.RFC3986;
|
||||||
|
import cn.hutool.core.net.URLDecoder;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.core.util.URLUtil;
|
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -26,6 +27,10 @@ import java.util.Map;
|
|||||||
public class UrlQuery {
|
public class UrlQuery {
|
||||||
|
|
||||||
private final TableMap<CharSequence, CharSequence> query;
|
private final TableMap<CharSequence, CharSequence> query;
|
||||||
|
/**
|
||||||
|
* 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
||||||
|
*/
|
||||||
|
private final boolean isFormUrlEncoded;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建UrlQuery
|
* 构建UrlQuery
|
||||||
@ -37,6 +42,17 @@ public class UrlQuery {
|
|||||||
return new UrlQuery(queryMap);
|
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
|
* 构建UrlQuery
|
||||||
*
|
*
|
||||||
@ -58,9 +74,21 @@ public class UrlQuery {
|
|||||||
* @since 5.5.8
|
* @since 5.5.8
|
||||||
*/
|
*/
|
||||||
public static UrlQuery of(String queryStr, Charset charset, boolean autoRemovePath) {
|
public static UrlQuery of(String queryStr, Charset charset, boolean autoRemovePath) {
|
||||||
final UrlQuery urlQuery = new UrlQuery();
|
return of(queryStr, charset, autoRemovePath, false);
|
||||||
urlQuery.parse(queryStr, charset, autoRemovePath);
|
}
|
||||||
return urlQuery;
|
|
||||||
|
/**
|
||||||
|
* 构建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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,18 +98,40 @@ public class UrlQuery {
|
|||||||
this(null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*
|
||||||
|
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
||||||
|
* @since 5.7.16
|
||||||
|
*/
|
||||||
|
public UrlQuery(boolean isFormUrlEncoded) {
|
||||||
|
this(null, isFormUrlEncoded);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param queryMap 初始化的查询键值对
|
* @param queryMap 初始化的查询键值对
|
||||||
*/
|
*/
|
||||||
public UrlQuery(Map<? extends CharSequence, ?> 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)) {
|
if (MapUtil.isNotEmpty(queryMap)) {
|
||||||
query = new TableMap<>(queryMap.size());
|
query = new TableMap<>(queryMap.size());
|
||||||
addAll(queryMap);
|
addAll(queryMap);
|
||||||
} else {
|
} else {
|
||||||
query = new TableMap<>(MapUtil.DEFAULT_INITIAL_CAPACITY);
|
query = new TableMap<>(MapUtil.DEFAULT_INITIAL_CAPACITY);
|
||||||
}
|
}
|
||||||
|
this.isFormUrlEncoded = isFormUrlEncoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,6 +232,10 @@ public class UrlQuery {
|
|||||||
* @return URL查询字符串
|
* @return URL查询字符串
|
||||||
*/
|
*/
|
||||||
public String build(Charset charset) {
|
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);
|
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) {
|
private void addParam(String key, String value, Charset charset) {
|
||||||
if (null != key) {
|
if (null != key) {
|
||||||
final String actualKey = URLUtil.decode(key, charset);
|
final String actualKey = URLDecoder.decode(key, charset, isFormUrlEncoded);
|
||||||
this.query.put(actualKey, StrUtil.nullToEmpty(URLUtil.decode(value, charset)));
|
this.query.put(actualKey, StrUtil.nullToEmpty(URLDecoder.decode(value, charset, isFormUrlEncoded)));
|
||||||
} else if (null != value) {
|
} else if (null != value) {
|
||||||
// name为空,value作为name,value赋值null
|
// name为空,value作为name,value赋值null
|
||||||
this.query.put(URLUtil.decode(value, charset), null);
|
this.query.put(URLDecoder.decode(value, charset, isFormUrlEncoded), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,9 +328,6 @@ public class URLUtil extends URLEncodeUtil {
|
|||||||
* @since 4.4.1
|
* @since 4.4.1
|
||||||
*/
|
*/
|
||||||
public static String decode(String content, Charset charset) {
|
public static String decode(String content, Charset charset) {
|
||||||
if (null == charset) {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
return URLDecoder.decode(content, charset);
|
return URLDecoder.decode(content, charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,9 +342,6 @@ public class URLUtil extends URLEncodeUtil {
|
|||||||
* @since 5.6.3
|
* @since 5.6.3
|
||||||
*/
|
*/
|
||||||
public static String decode(String content, Charset charset, boolean isPlusToSpace) {
|
public static String decode(String content, Charset charset, boolean isPlusToSpace) {
|
||||||
if (null == charset) {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
return URLDecoder.decode(content, charset, isPlusToSpace);
|
return URLDecoder.decode(content, charset, isPlusToSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,7 +355,7 @@ public class URLUtil extends URLEncodeUtil {
|
|||||||
* @throws UtilException UnsupportedEncodingException
|
* @throws UtilException UnsupportedEncodingException
|
||||||
*/
|
*/
|
||||||
public static String decode(String content, String charset) throws UtilException {
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,6 +108,14 @@ public class UrlQueryTest {
|
|||||||
Assert.assertEquals("a+b=1+2", a);
|
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
|
@Test
|
||||||
public void spaceTest(){
|
public void spaceTest(){
|
||||||
// 根据RFC3986,在URL中,空格编码为"%20"
|
// 根据RFC3986,在URL中,空格编码为"%20"
|
||||||
|
@ -10,7 +10,6 @@ import cn.hutool.core.io.resource.MultiFileResource;
|
|||||||
import cn.hutool.core.io.resource.Resource;
|
import cn.hutool.core.io.resource.Resource;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.net.FormUrlencoded;
|
|
||||||
import cn.hutool.core.net.SSLUtil;
|
import cn.hutool.core.net.SSLUtil;
|
||||||
import cn.hutool.core.net.url.UrlBuilder;
|
import cn.hutool.core.net.url.UrlBuilder;
|
||||||
import cn.hutool.core.net.url.UrlQuery;
|
import cn.hutool.core.net.url.UrlQuery;
|
||||||
@ -1229,8 +1228,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
* @since 5.3.2
|
* @since 5.3.2
|
||||||
*/
|
*/
|
||||||
private String getFormUrlEncoded() {
|
private String getFormUrlEncoded() {
|
||||||
return UrlQuery.of(this.form)
|
return UrlQuery.of(this.form, true).build(this.charset);
|
||||||
.build(FormUrlencoded.ALL, FormUrlencoded.ALL, this.charset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user