top.jfunc.http.util.ParamUtil Maven / Gradle / Ivy
package top.jfunc.http.util;
import top.jfunc.common.Editor;
import top.jfunc.http.base.Protocol;
import top.jfunc.common.utils.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.BiConsumer;
import static top.jfunc.common.utils.StrUtil.*;
/**
* @author xiongshiyan at 2017/12/11
* @since 1.1.1新增MultiValueMap的支持
*/
public class ParamUtil {
private ParamUtil(){}
/////////////////////////////////////////////////URL判断////////////////////////////////////////////////////////
/**
* 检测是否https
* @param url 完整的URL
* @return 是否https
*/
public static boolean isHttps(String url) {
return urlStartWith(url, HTTPS_PREFIX);
}
/**
* 检测是否http
* @param url 完整的URL
* @return 是否https
*/
public static boolean isHttp(String url) {
return urlStartWith(url, HTTP_PREFIX);
}
private static boolean urlStartWith(String url, String prefix) {
if(StrUtil.isEmpty(url) || url.length() < prefix.length()){
return false;
}
return prefix.equalsIgnoreCase(url.substring(0, prefix.length()));
}
/**
* 判断给定的字符串是否是完整的URL
* https://localhost:8080/... true
* http://localhost:8080/... true
* /xxx/xxx false
* yyy/yyy false
*
*/
public static boolean isCompletedUrl(String url){
return isHttp(url) || isHttps(url);
}
/**
* 获取一个链接的协议,支持任何URL
* @param completeUrl 完整的URL
* @return 协议
*/
public static String protocol(String completeUrl){
int index = completeUrl.indexOf(StrUtil.COLON);
if(-1 == index){
return null;
}
return completeUrl.substring(0, index);
//return completeUrl.split(StrUtil.COLON)[0];
}
/**
* 获取http协议
* @param httpCompleteUrl 完整的Http URL
* @return Protocol
*/
public static Protocol httpProtocol(String httpCompleteUrl){
String protocol = protocol(httpCompleteUrl);
if(null == protocol){
return null;
}
return Protocol.valueOf(protocol.toUpperCase());
}
/////////////////////////////////////////////////URL编解码////////////////////////////////////////////////////////
/**
* 对字符串进行URL编码
* @param valueCharset 字符编码,字符编码不对原样返回
* @param src 原字符串
* @return 编码后的字符串
*/
public static String urlEncode(String src, String valueCharset) {
try {
return URLEncoder.encode(src, valueCharset);
}catch (UnsupportedEncodingException e){
return src;
}
}
public static String urlEncode(String src) {
try {
return URLEncoder.encode(src, CharsetUtil.UTF_8);
}catch (UnsupportedEncodingException e){
return src;
}
}
/**
* 对字符串进行URL解码
* @param valueCharset 字符编码,字符编码不对原样返回
* @param src 原字符串
* @return 解码后的字符串
*/
public static String urlDecode(String src, String valueCharset) {
try {
return URLDecoder.decode(src, valueCharset);
}catch (UnsupportedEncodingException e){
return src;
}
}
public static String urlDecode(String src) {
try {
return URLDecoder.decode(src, CharsetUtil.UTF_8);
}catch (UnsupportedEncodingException e){
return src;
}
}
/////////////////////////////////////////////////parse参数////////////////////////////////////////////////////////
public static Map parseParam(String kvParams){
return parseParam(kvParams, ParamUtil::urlDecode, StrUtil.AND);
}
public static Map parseParam(String kvParams , Editor valueEditor){
return parseParam(kvParams, valueEditor, StrUtil.AND);
}
public static Map parseParam(String kvParams , String breakRegex){
return parseParam(kvParams, ParamUtil::urlDecode, breakRegex);
}
/**
* 对于key1=value1&key2=value2解析为map
* @param kvParams key1=value1&key2=value2
* @param valueEditor 对value进一步处理
* @param breakRegex kv之间的分割,支持&、|等
*/
public static Map parseParam(String kvParams , Editor valueEditor , String breakRegex){
if(StrUtil.isEmpty(kvParams)){
return Collections.emptyMap();
}
String[] kvs = kvParams.split(breakRegex);
Map params = new HashMap<>(kvs.length);
parse(kvs , valueEditor , params::put);
return params;
}
public static MultiValueMap parseMultiValueParam(String kvParams){
return parseMultiValueParam(kvParams, ParamUtil::urlDecode, StrUtil.AND);
}
public static MultiValueMap parseMultiValueParam(String kvParams , Editor valueEditor){
return parseMultiValueParam(kvParams, valueEditor, StrUtil.AND);
}
public static MultiValueMap parseMultiValueParam(String kvParams , String breakRegex){
return parseMultiValueParam(kvParams, ParamUtil::urlDecode, breakRegex);
}
/**
* 是对{@link ParamUtil#parseParam(String, Editor, String)} 的升级,因为有些情况下value可能有多个
* @param kvParams key1=value1&key2=value2
* @param valueEditor 对value进一步处理
* @param breakRegex kv之间的分割,支持&和|
*/
public static MultiValueMap parseMultiValueParam(String kvParams , Editor valueEditor , String breakRegex){
if(StrUtil.isEmpty(kvParams)){
return new ArrayListMultiValueMap<>();
}
String[] kvs = kvParams.split(breakRegex);
MultiValueMap params = new ArrayListMultiValueMap<>(kvs.length);
parse(kvs , valueEditor , params::add);
return params;
}
private static void parse(String[] kvs , Editor valueEditor , BiConsumer putFunction){
for (String kv : kvs) {
//不包含=
if(!kv.contains(StrUtil.EQUALS)){
putFunction.accept(kv , StrUtil.BLANK);
continue;
}
String[] split = kv.split(StrUtil.EQUALS);
//k1=的情况,value为空
if(split.length == 1){
putFunction.accept(split[0] , StrUtil.BLANK);
continue;
}
String value = split[1];
if(null != valueEditor && StrUtil.isNotEmpty(value)){
value = valueEditor.edit(value);
}
putFunction.accept(split[0] , value);
}
}
/////////////////////////////////////////////////contact参数////////////////////////////////////////////////////////
/**
* 默认UTF-8编码
*/
public static String contactMap(Map map){
return contactMap(map , CharsetUtil.UTF_8);
}
/**
* key1=value1&key2=value2,如果value=null 或者 size=0 返回 ""
* @param map 键值对
*/
public static String contactMap(Map map , final String valueCharset){
return contactMap(map, (v)-> urlEncode(v , valueCharset));
}
public static String contactMap(Map map , final Editor valueEditor){
if(MapUtil.isEmpty(map)){return BLANK;}
return Joiner.on(AND).withKeyValueSeparator(EQUALS,valueEditor).useForNull(StrUtil.BLANK).join(map);
}
public static String contactMap(MultiValueMap multiValueMap){
return contactMap(multiValueMap , CharsetUtil.UTF_8);
}
/**
* key1=value1&key2=value2&key2=value3,如果value=null 或者 size=0 返回 ""
* @param multiValueMap 键值对
*/
public static String contactMap(MultiValueMap multiValueMap , final String valueCharset){
if(MapUtil.isEmpty(multiValueMap)){return BLANK;}
return contactIterable(multiValueMap.entrySet(), valueCharset);
}
/**
* value进行URL编码
* key1=value1&key2=value2&key2=value3,如果value=null 或者 size=0 返回 ""
* @param entries Map.Entries
*/
public static String contactIterable(Iterable>> entries, String valueCharset) {
return contactIterable(entries , (v) -> urlEncode(v , valueCharset));
}
/**
* value不进行URL编码
* key1=value1&key2=value2&key2=value3,如果value=null 或者 size=0 返回 ""
* @param entries Map.Entries
*/
public static String contactIterableNotEncode(Iterable>> entries) {
return contactIterable(entries , (v) -> v);
}
/**
* 连接key-value,并对value做一定的处理
* @param entries Iterable>>
* @param valueEditor value处理器
* @return 连接后的字符串
*/
public static String contactIterable(Iterable>> entries , Editor valueEditor){
if(null == entries){
return StrUtil.BLANK;
}
StringBuilder params = new StringBuilder();
for (Map.Entry> entry : entries) {
String key = entry.getKey();
for (String v : entry.getValue()) {
params.append(key).append(EQUALS)
.append(valueEditor.edit(v))
.append(AND);
}
}
if(params.length() > 0){
params = params.deleteCharAt(params.length() - 1);
}
return params.toString();
}
/**
* URL和参数
* @param actionName URL,可以包含?
* @param paramString 参数字符串,可以为"",null,k1=v1&k2=v2
* @return 连接后的字符串
*/
public static String contactUrlParams(String actionName, String paramString) {
String url = actionName;
if(!StrUtil.BLANK.equals(paramString)) {
//如果包含?,則直接追加//不包含?,則用?追加
url = actionName.contains(QUESTION_MARK) ? actionName + AND + paramString : actionName + QUESTION_MARK + paramString;
}
return url;
}
public static String contactUrlParams(String actionName, MultiValueMap params) {
Objects.requireNonNull(actionName);
return contactUrlParams(actionName , contactMap(params , CharsetUtil.UTF_8));
}
public static String contactUrlParams(String actionName, MultiValueMap params , String valueCharset) {
Objects.requireNonNull(actionName);
return contactUrlParams(actionName , contactMap(params , valueCharset));
}
/**
* @see ParamUtil#contactMap(Map , String)
* @see ParamUtil#contactUrlParams(String, String)
*/
public static String contactUrlParams(String actionName, Map params , String valueCharset) {
Objects.requireNonNull(actionName);
return contactUrlParams(actionName , contactMap(params , valueCharset));
}
public static String contactUrlParams(String actionName, Map params) {
Objects.requireNonNull(actionName);
return contactUrlParams(actionName , contactMap(params , CharsetUtil.UTF_8));
}
/**
* 将两截URL连接起来,主要功能是对 / 的兼容处理
* @param firstFragment firstFragment
* @param secondFragment secondFragment
*/
public static String concatUrlIfNecessary(String firstFragment , String secondFragment){
//1.baseUrl为空不处理
//2.本身是完整的URL不处理
if(StrUtil.isEmpty(firstFragment) || ParamUtil.isCompletedUrl(secondFragment)){
return secondFragment;
}
if(firstFragment.endsWith(StrUtil.SLASH) && secondFragment.startsWith(StrUtil.SLASH)){
return firstFragment + secondFragment.substring(1);
}
if(!firstFragment.endsWith(StrUtil.SLASH) && !secondFragment.startsWith(StrUtil.SLASH)){
return firstFragment + StrUtil.SLASH + secondFragment;
}
return firstFragment + secondFragment;
}
/////////////////////////////////////////////////处理路径参数////////////////////////////////////////////////////////
/**
* 处理路径参数
* @param originUrl 形如 http://httpbin.org/book/{id}
* @param routeParams 参数值
* @return 处理过后的URL
*/
public static String replaceRouteParamsIfNecessary(String originUrl , Map routeParams){
if(MapUtil.isEmpty(routeParams)){
return originUrl;
}
String url = originUrl;
for (Map.Entry entry : routeParams.entrySet()) {
String key = entry.getKey();
url = url.replaceFirst("\\{" + key + "}", entry.getValue());
/*if(url.contains(key)){
//只替换那些url中包含key的,提升效率[一般map中应该很少有那么多冗余的]
}*/
}
return url;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy