mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
fix code
This commit is contained in:
@@ -19,6 +19,7 @@ import org.dromara.hutool.core.convert.Convert;
|
|||||||
import org.dromara.hutool.core.map.MapUtil;
|
import org.dromara.hutool.core.map.MapUtil;
|
||||||
import org.dromara.hutool.core.map.TableMap;
|
import org.dromara.hutool.core.map.TableMap;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -39,58 +40,12 @@ public class UrlQuery {
|
|||||||
|
|
||||||
private final TableMap<CharSequence, CharSequence> query;
|
private final TableMap<CharSequence, CharSequence> query;
|
||||||
/**
|
/**
|
||||||
* 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
* 编码模式
|
||||||
*/
|
*/
|
||||||
private final boolean isFormUrlEncoded;
|
private EncodeMode encodeMode;
|
||||||
/**
|
|
||||||
* 是否严格模式,严格模式下,query的name和value中均不允许有分隔符。
|
|
||||||
*/
|
|
||||||
private boolean isStrict;
|
|
||||||
|
|
||||||
// region ----- of
|
// region ----- of
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建UrlQuery
|
|
||||||
*
|
|
||||||
* @return UrlQuery
|
|
||||||
*/
|
|
||||||
public static UrlQuery of() {
|
|
||||||
return of(false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建UrlQuery
|
|
||||||
*
|
|
||||||
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
|
||||||
* @param isStrict 是否严格模式,严格模式下,query的name和value中均不允许有分隔符。
|
|
||||||
* @return UrlQuery
|
|
||||||
*/
|
|
||||||
public static UrlQuery of(final boolean isFormUrlEncoded, final boolean isStrict) {
|
|
||||||
return new UrlQuery(null, isFormUrlEncoded, isStrict);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建UrlQuery
|
|
||||||
*
|
|
||||||
* @param queryMap 初始化的查询键值对
|
|
||||||
* @return UrlQuery
|
|
||||||
*/
|
|
||||||
public static UrlQuery of(final Map<? extends CharSequence, ?> queryMap) {
|
|
||||||
return of(queryMap, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建UrlQuery
|
|
||||||
*
|
|
||||||
* @param queryMap 初始化的查询键值对
|
|
||||||
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
|
||||||
* @param isStrict 是否严格模式,严格模式下,query的name和value中均不允许有分隔符。
|
|
||||||
* @return UrlQuery
|
|
||||||
*/
|
|
||||||
public static UrlQuery of(final Map<? extends CharSequence, ?> queryMap, final boolean isFormUrlEncoded, final boolean isStrict) {
|
|
||||||
return new UrlQuery(queryMap, isFormUrlEncoded, isStrict);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建UrlQuery
|
* 构建UrlQuery
|
||||||
*
|
*
|
||||||
@@ -112,52 +67,89 @@ public class UrlQuery {
|
|||||||
* @since 5.5.8
|
* @since 5.5.8
|
||||||
*/
|
*/
|
||||||
public static UrlQuery of(final String queryStr, final Charset charset, final boolean autoRemovePath) {
|
public static UrlQuery of(final String queryStr, final Charset charset, final boolean autoRemovePath) {
|
||||||
return of(queryStr, charset, autoRemovePath, false, false);
|
return of(queryStr, charset, autoRemovePath, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建UrlQuery
|
* 构建UrlQuery
|
||||||
*
|
*
|
||||||
* @param queryStr 初始化的查询字符串
|
* @param queryStr 初始化的查询字符串
|
||||||
* @param charset decode用的编码,null表示不做decode
|
* @param charset decode用的编码,null表示不做decode
|
||||||
* @param autoRemovePath 是否自动去除path部分,{@code true}则自动去除第一个?前的内容
|
* @param autoRemovePath 是否自动去除path部分,{@code true}则自动去除第一个?前的内容
|
||||||
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
* @param encodeMode 编码模式。
|
||||||
* @param isStrict 是否严格模式,严格模式下,query的name和value中均不允许有分隔符。
|
|
||||||
* @return UrlQuery
|
* @return UrlQuery
|
||||||
* @since 5.7.16
|
|
||||||
*/
|
*/
|
||||||
public static UrlQuery of(final String queryStr, final Charset charset, final boolean autoRemovePath
|
public static UrlQuery of(final String queryStr, final Charset charset, final boolean autoRemovePath, final EncodeMode encodeMode) {
|
||||||
, final boolean isFormUrlEncoded, final boolean isStrict) {
|
return of(encodeMode).parse(queryStr, charset, autoRemovePath);
|
||||||
return new UrlQuery(null, isFormUrlEncoded, isStrict).parse(queryStr, charset, autoRemovePath);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建UrlQuery
|
||||||
|
*
|
||||||
|
* @return UrlQuery
|
||||||
|
*/
|
||||||
|
public static UrlQuery of() {
|
||||||
|
return of(EncodeMode.NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建UrlQuery
|
||||||
|
*
|
||||||
|
* @param encodeMode 编码模式
|
||||||
|
* @return UrlQuery
|
||||||
|
*/
|
||||||
|
public static UrlQuery of(final EncodeMode encodeMode) {
|
||||||
|
return new UrlQuery(null, encodeMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建UrlQuery
|
||||||
|
*
|
||||||
|
* @param queryMap 初始化的查询键值对
|
||||||
|
* @return UrlQuery
|
||||||
|
*/
|
||||||
|
public static UrlQuery of(final Map<? extends CharSequence, ?> queryMap) {
|
||||||
|
return of(queryMap, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建UrlQuery
|
||||||
|
*
|
||||||
|
* @param queryMap 初始化的查询键值对
|
||||||
|
* @param encodeMode 编码模式
|
||||||
|
* @return UrlQuery
|
||||||
|
*/
|
||||||
|
public static UrlQuery of(final Map<? extends CharSequence, ?> queryMap, final EncodeMode encodeMode) {
|
||||||
|
return new UrlQuery(queryMap, encodeMode);
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param queryMap 初始化的查询键值对
|
* @param queryMap 初始化的查询键值对
|
||||||
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
* @param encodeMode 编码模式
|
||||||
* @param isStrict 是否严格模式,严格模式下,query的name和value中均不允许有分隔符。
|
|
||||||
*/
|
*/
|
||||||
public UrlQuery(final Map<? extends CharSequence, ?> queryMap, final boolean isFormUrlEncoded, final boolean isStrict) {
|
public UrlQuery(final Map<? extends CharSequence, ?> queryMap, final EncodeMode encodeMode) {
|
||||||
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;
|
this.encodeMode = ObjUtil.defaultIfNull(encodeMode, EncodeMode.NORMAL);
|
||||||
this.isStrict = isStrict;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置是否严格模式
|
* 设置编码模式<br>
|
||||||
|
* 根据不同场景以及不同环境,对Query中的name和value采用不同的编码策略
|
||||||
*
|
*
|
||||||
* @param strict 是否严格模式
|
* @param encodeMode 编码模式
|
||||||
* @return this
|
* @return this
|
||||||
|
* @since 6.0.0
|
||||||
*/
|
*/
|
||||||
public UrlQuery setStrict(final boolean strict) {
|
public UrlQuery setEncodeMode(final EncodeMode encodeMode) {
|
||||||
isStrict = strict;
|
this.encodeMode = encodeMode;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,14 +267,14 @@ public class UrlQuery {
|
|||||||
* @return URL查询字符串
|
* @return URL查询字符串
|
||||||
*/
|
*/
|
||||||
public String build(final Charset charset, final boolean encodePercent) {
|
public String build(final Charset charset, final boolean encodePercent) {
|
||||||
if (isFormUrlEncoded) {
|
switch (this.encodeMode) {
|
||||||
return build(FormUrlencoded.ALL, FormUrlencoded.ALL, charset, encodePercent);
|
case FORM_URL_ENCODED:
|
||||||
|
return build(FormUrlencoded.ALL, FormUrlencoded.ALL, charset, encodePercent);
|
||||||
|
case STRICT:
|
||||||
|
return build(RFC3986.QUERY_PARAM_NAME_STRICT, RFC3986.QUERY_PARAM_VALUE_STRICT, charset, encodePercent);
|
||||||
|
default:
|
||||||
|
return build(RFC3986.QUERY_PARAM_NAME, RFC3986.QUERY_PARAM_VALUE, charset, encodePercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStrict) {
|
|
||||||
return build(RFC3986.QUERY_PARAM_NAME_STRICT, RFC3986.QUERY_PARAM_VALUE_STRICT, charset, encodePercent);
|
|
||||||
}
|
|
||||||
return build(RFC3986.QUERY_PARAM_NAME, RFC3986.QUERY_PARAM_VALUE, charset, encodePercent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -318,7 +310,8 @@ public class UrlQuery {
|
|||||||
* @return URL查询字符串
|
* @return URL查询字符串
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public String build(final PercentCodec keyCoder, final PercentCodec valueCoder, final Charset charset, final boolean encodePercent) {
|
public String build(final PercentCodec keyCoder, final PercentCodec valueCoder,
|
||||||
|
final Charset charset, final boolean encodePercent) {
|
||||||
if (MapUtil.isEmpty(this.query)) {
|
if (MapUtil.isEmpty(this.query)) {
|
||||||
return StrUtil.EMPTY;
|
return StrUtil.EMPTY;
|
||||||
}
|
}
|
||||||
@@ -432,6 +425,7 @@ public class UrlQuery {
|
|||||||
* @param charset 编码
|
* @param charset 编码
|
||||||
*/
|
*/
|
||||||
private void addParam(final String key, final String value, final Charset charset) {
|
private void addParam(final String key, final String value, final Charset charset) {
|
||||||
|
final boolean isFormUrlEncoded = EncodeMode.FORM_URL_ENCODED == this.encodeMode;
|
||||||
if (null != key) {
|
if (null != key) {
|
||||||
final String actualKey = URLDecoder.decode(key, charset, isFormUrlEncoded);
|
final String actualKey = URLDecoder.decode(key, charset, isFormUrlEncoded);
|
||||||
this.query.put(actualKey, StrUtil.emptyIfNull(URLDecoder.decode(value, charset, isFormUrlEncoded)));
|
this.query.put(actualKey, StrUtil.emptyIfNull(URLDecoder.decode(value, charset, isFormUrlEncoded)));
|
||||||
@@ -440,4 +434,26 @@ public class UrlQuery {
|
|||||||
this.query.put(URLDecoder.decode(value, charset, isFormUrlEncoded), null);
|
this.query.put(URLDecoder.decode(value, charset, isFormUrlEncoded), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编码模式<br>
|
||||||
|
* 根据不同场景以及不同环境,对Query中的name和value采用不同的编码策略
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public enum EncodeMode {
|
||||||
|
/**
|
||||||
|
* 正常模式(宽松模式),这种模式下,部分分隔符无需转义
|
||||||
|
*/
|
||||||
|
NORMAL,
|
||||||
|
/**
|
||||||
|
* x-www-form-urlencoded模式,此模式下空格会编码为'+',"~"和"*"会被转义
|
||||||
|
*/
|
||||||
|
FORM_URL_ENCODED,
|
||||||
|
/**
|
||||||
|
* 严格模式,此模式下,非UNRESERVED的字符都会被转义
|
||||||
|
*/
|
||||||
|
STRICT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -55,10 +55,9 @@ public class UrlQueryUtil {
|
|||||||
* @param paramMap 表单数据
|
* @param paramMap 表单数据
|
||||||
* @param charset 编码,{@code null} 表示不encode键值对
|
* @param charset 编码,{@code null} 表示不encode键值对
|
||||||
* @return url参数
|
* @return url参数
|
||||||
* @see #toQuery(Map, Charset, boolean)
|
|
||||||
*/
|
*/
|
||||||
public static String toQuery(final Map<String, ?> paramMap, final Charset charset) {
|
public static String toQuery(final Map<String, ?> paramMap, final Charset charset) {
|
||||||
return toQuery(paramMap, charset, false);
|
return toQuery(paramMap, charset, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,34 +69,13 @@ public class UrlQueryUtil {
|
|||||||
* key1=v1&key2=&key3=v3
|
* key1=v1&key2=&key3=v3
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param paramMap 表单数据
|
* @param paramMap 表单数据
|
||||||
* @param charset 编码,null表示不encode键值对
|
* @param charset 编码,null表示不encode键值对
|
||||||
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
* @param encodeMode 编码模式
|
||||||
* @return url参数
|
|
||||||
* @since 5.7.16
|
|
||||||
*/
|
|
||||||
public static String toQuery(final Map<String, ?> paramMap, final Charset charset, final boolean isFormUrlEncoded) {
|
|
||||||
return toQuery(paramMap, charset, isFormUrlEncoded, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将Map形式的Form表单数据转换为Url参数形式<br>
|
|
||||||
* paramMap中如果key为空(null和"")会被忽略,如果value为null,会被做为空白符("")<br>
|
|
||||||
* 会自动url编码键和值
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* key1=v1&key2=&key3=v3
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @param paramMap 表单数据
|
|
||||||
* @param charset 编码,null表示不encode键值对
|
|
||||||
* @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
|
||||||
* @param isStrict 是否严格模式,严格模式下,query的name和value中均不允许有分隔符。
|
|
||||||
* @return url参数
|
* @return url参数
|
||||||
*/
|
*/
|
||||||
public static String toQuery(final Map<String, ?> paramMap, final Charset charset
|
public static String toQuery(final Map<String, ?> paramMap, final Charset charset, final UrlQuery.EncodeMode encodeMode) {
|
||||||
, final boolean isFormUrlEncoded, final boolean isStrict) {
|
return UrlQuery.of(paramMap, encodeMode).build(charset);
|
||||||
return UrlQuery.of(paramMap, isFormUrlEncoded, isStrict).build(charset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -148,7 +148,7 @@ public class UrlQueryTest {
|
|||||||
@Test
|
@Test
|
||||||
void issueI78PB1Test() {
|
void issueI78PB1Test() {
|
||||||
// 严格模式
|
// 严格模式
|
||||||
final UrlQuery query = UrlQuery.of(false, true);
|
final UrlQuery query = UrlQuery.of(UrlQuery.EncodeMode.STRICT);
|
||||||
query.add(":/?#[]@!$&'()*+,;= ", ":/?#[]@!$&'()*+,;= ");
|
query.add(":/?#[]@!$&'()*+,;= ", ":/?#[]@!$&'()*+,;= ");
|
||||||
|
|
||||||
final String string = query.build(CharsetUtil.UTF_8);
|
final String string = query.build(CharsetUtil.UTF_8);
|
||||||
|
@@ -52,7 +52,7 @@ public class UrlEncodedFormBody extends FormBody<UrlEncodedFormBody> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final OutputStream out) {
|
public void write(final OutputStream out) {
|
||||||
final byte[] bytes = ByteUtil.toBytes(UrlQuery.of(form, true, false).build(charset), charset);
|
final byte[] bytes = ByteUtil.toBytes(UrlQuery.of(form, UrlQuery.EncodeMode.FORM_URL_ENCODED).build(charset), charset);
|
||||||
IoUtil.write(out, false, bytes);
|
IoUtil.write(out, false, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user