mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
Merge branch 'v5-dev' of https://gitee.com/deligense/hutool into v5-dev
This commit is contained in:
commit
8f35f5429b
@ -3,7 +3,7 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.7.16 (2021-10-28)
|
||||
# 5.7.16 (2021-10-31)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 增加DateTime.toLocalDateTime
|
||||
@ -15,6 +15,10 @@
|
||||
* 【extra 】 Sftp增加put和upload重载(issue#I4FGDH@Gitee)
|
||||
* 【core 】 TemporalUtil增加toChronoUnit、toTimeUnit方法(issue#I4FGDH@Gitee)
|
||||
* 【core 】 StopWatch增加prettyPrint重载(issue#1910@Github)
|
||||
* 【core 】 修改RegexPool中Ipv4正则
|
||||
* 【json 】 Filter改为MutablePair,以便编辑键值对(issue#1921@Github)
|
||||
* 【core 】 Opt增加peeks方法(pr#445@Gitee)
|
||||
* 【extra 】 MailAccount中user默认值改为邮箱全称(issue#I4FYVY@Gitee)
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【core 】 修复UrlBuilder.addPath歧义问题(issue#1912@Github)
|
||||
@ -22,6 +26,7 @@
|
||||
* 【core 】 修复CharSequenceUtil.wrapIfMissing预定义长度计算问题(issue#I4FDZ2@Gitee)
|
||||
* 【poi 】 修复合并单元格为日期时,导出单元格数据为数字问题(issue#1911@Github)
|
||||
* 【core 】 修复CompilerUtil.getFileManager参数没有使用的问题(issue#I4FIO6@Gitee)
|
||||
* 【core 】 修复NetUtil.isInRange的cidr判断问题(pr#1917@Github)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@ -39,6 +44,8 @@
|
||||
* 【core 】 ZipUtil增加append方法(pr#441@Gitee)
|
||||
* 【core 】 CollUtil增加重载(issue#I4E9FS@Gitee)
|
||||
* 【core 】 CopyOptions新增setFieldValueEditor(issue#I4E08T@Gitee)
|
||||
* 【core 】 增加SystemPropsUtil(issue#1918@Gitee)
|
||||
* 【core 】 增加`hutool.date.lenient`系统属性(issue#1918@Gitee)
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【core 】 修复CollUtil.isEqualList两个null返回错误问题(issue#1885@Github)
|
||||
|
@ -7,6 +7,7 @@ import cn.hutool.core.date.format.GlobalCustomFormat;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.SystemPropsUtil;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DateFormat;
|
||||
@ -288,7 +289,7 @@ public class DateTime extends Date {
|
||||
* @see DatePattern
|
||||
*/
|
||||
public DateTime(CharSequence dateStr, DateParser dateParser) {
|
||||
this(dateStr, dateParser, true);
|
||||
this(dateStr, dateParser, SystemPropsUtil.getBoolean(SystemPropsUtil.HUTOOL_DATE_LENIENT, true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -262,6 +262,25 @@ public class Opt<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 如果包裹里元素的值存在,就执行对应的操作集,并返回本身
|
||||
* 如果不存在,返回一个空的{@code Opt}
|
||||
*
|
||||
* <p>属于 {@link #ifPresent}的链式拓展
|
||||
* <p>属于 {@link #peek(Consumer)}的动态拓展
|
||||
*
|
||||
* @param actions 值存在时执行的操作,动态参数,可传入数组,当数组为一个空数组时并不会抛出 {@code NPE}
|
||||
* @return this
|
||||
* @throws NullPointerException 如果值存在,并且传入的操作集中的元素为 {@code null}
|
||||
* @author VampireAchao
|
||||
*/
|
||||
@SafeVarargs
|
||||
public final Opt<T> peeks(Consumer<T>... actions) throws NullPointerException {
|
||||
// 第三个参数 (opts, opt) -> null其实并不会执行到该函数式接口所以直接返回了个null
|
||||
return Stream.of(actions).reduce(this, Opt<T>::peek, (opts, opt) -> null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果包裹里元素的值存在,就返回本身,如果不存在,则使用传入的操作执行后获得的 {@code Opt}
|
||||
*
|
||||
|
@ -16,17 +16,17 @@ import java.util.Objects;
|
||||
public class Pair<K, V> extends CloneSupport<Pair<K, V>> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final K key;
|
||||
private final V value;
|
||||
protected K key;
|
||||
protected V value;
|
||||
|
||||
/**
|
||||
* 构建{@link Pair}对象
|
||||
* 构建{@code Pair}对象
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return {@link Pair}
|
||||
* @return {@code Pair}
|
||||
* @since 5.4.3
|
||||
*/
|
||||
public static <K, V> Pair<K, V> of(K key, V value) {
|
||||
|
@ -32,9 +32,11 @@ public interface RegexPool {
|
||||
*/
|
||||
String GROUP_VAR = "\\$(\\d+)";
|
||||
/**
|
||||
* IP v4
|
||||
* IP v4<br>
|
||||
* 采用分组方式便于解析地址的每一个段
|
||||
*/
|
||||
String IPV4 = "\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b";
|
||||
//String IPV4 = "\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b";
|
||||
String IPV4 = "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)$";
|
||||
/**
|
||||
* IP v6
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@ package cn.hutool.core.lang.mutable;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
|
||||
/**
|
||||
* 可变 <code>double</code> 类型
|
||||
* 可变 {@code double} 类型
|
||||
*
|
||||
* @see Double
|
||||
* @since 3.0.1
|
||||
@ -150,12 +150,12 @@ public class MutableDouble extends Number implements Comparable<MutableDouble>,
|
||||
* 相等需同时满足如下条件:
|
||||
* <ol>
|
||||
* <li>非空</li>
|
||||
* <li>类型为 {@link MutableDouble}</li>
|
||||
* <li>类型为 {@code MutableDouble}</li>
|
||||
* <li>值相等</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param obj 比对的对象
|
||||
* @return 相同返回<code>true</code>,否则 <code>false</code>
|
||||
* @return 相同返回<code>true</code>,否则 {@code false}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
@ -175,7 +175,7 @@ public class MutableDouble extends Number implements Comparable<MutableDouble>,
|
||||
/**
|
||||
* 比较
|
||||
*
|
||||
* @param other 其它 {@link MutableDouble} 对象
|
||||
* @param other 其它 {@code MutableDouble} 对象
|
||||
* @return x==y返回0,x<y返回-1,x>y返回1
|
||||
*/
|
||||
@Override
|
||||
|
@ -0,0 +1,57 @@
|
||||
package cn.hutool.core.lang.mutable;
|
||||
|
||||
import cn.hutool.core.lang.Pair;
|
||||
|
||||
/**
|
||||
* 可变{@link Pair}实现,可以修改键和值
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @since 5.7.16
|
||||
*/
|
||||
public class MutablePair<K, V> extends Pair<K, V> implements Mutable<Pair<K, V>>{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public MutablePair(K key, V value) {
|
||||
super(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置键
|
||||
*
|
||||
* @param key 新键
|
||||
* @return this
|
||||
*/
|
||||
public MutablePair<K, V> setKey(K key) {
|
||||
this.key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置值
|
||||
*
|
||||
* @param value 新值
|
||||
* @return this
|
||||
*/
|
||||
public MutablePair<K, V> setValue(V value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<K, V> get() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Pair<K, V> pair) {
|
||||
this.key = pair.getKey();
|
||||
this.value = pair.getValue();
|
||||
}
|
||||
}
|
@ -3,13 +3,14 @@ package cn.hutool.core.net;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.core.lang.PatternPool;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* IPV4地址工具类
|
||||
@ -20,6 +21,7 @@ import java.util.Objects;
|
||||
* @since 5.4.1
|
||||
*/
|
||||
public class Ipv4Util {
|
||||
|
||||
/**
|
||||
* IP段的分割符
|
||||
*/
|
||||
@ -149,18 +151,25 @@ public class Ipv4Util {
|
||||
/**
|
||||
* 根据ip地址(xxx.xxx.xxx.xxx)计算出long型的数据
|
||||
* 方法别名:inet_aton
|
||||
*
|
||||
* @param strIP IP V4 地址
|
||||
* @return long值
|
||||
*/
|
||||
public static long ipv4ToLong(String strIP) {
|
||||
Validator.validateIpv4(strIP, "Invalid IPv4 address!");
|
||||
final long[] ip = Convert.convert(long[].class, StrUtil.split(strIP, CharUtil.DOT));
|
||||
return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
|
||||
final Matcher matcher = PatternPool.IPV4.matcher(strIP);
|
||||
if (matcher.matches()) {
|
||||
return matchAddress(matcher);
|
||||
}
|
||||
// Validator.validateIpv4(strIP, "Invalid IPv4 address!");
|
||||
// final long[] ip = Convert.convert(long[].class, StrUtil.split(strIP, CharUtil.DOT));
|
||||
// return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
|
||||
throw new IllegalArgumentException("Invalid IPv4 address!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ip/掩码位 计算IP段的起始IP(字符串型)
|
||||
* 方法别名:inet_ntoa
|
||||
*
|
||||
* @param ip 给定的IP,如218.240.38.69
|
||||
* @param maskBit 给定的掩码位,如30
|
||||
* @return 起始IP的字符串表示
|
||||
@ -195,9 +204,7 @@ public class Ipv4Util {
|
||||
* 根据子网掩码转换为掩码位
|
||||
*
|
||||
* @param mask 掩码的点分十进制表示,例如 255.255.255.0
|
||||
*
|
||||
* @return 掩码位,例如 24
|
||||
*
|
||||
* @throws IllegalArgumentException 子网掩码非法
|
||||
*/
|
||||
public static int getMaskBitByMask(String mask) {
|
||||
@ -282,7 +289,6 @@ public class Ipv4Util {
|
||||
* 判断掩码是否合法
|
||||
*
|
||||
* @param mask 掩码的点分十进制表示,例如 255.255.255.0
|
||||
*
|
||||
* @return true:掩码合法;false:掩码不合法
|
||||
*/
|
||||
public static boolean isMaskValid(String mask) {
|
||||
@ -293,7 +299,6 @@ public class Ipv4Util {
|
||||
* 判断掩码位是否合法
|
||||
*
|
||||
* @param maskBit 掩码位,例如 24
|
||||
*
|
||||
* @return true:掩码位合法;false:掩码位不合法
|
||||
*/
|
||||
public static boolean isMaskBitValid(int maskBit) {
|
||||
@ -315,5 +320,19 @@ public class Ipv4Util {
|
||||
return getBeginIpLong(ip, maskBit)
|
||||
+ ~ipv4ToLong(getMaskByMaskBit(maskBit));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将匹配到的Ipv4地址的4个分组分别处理
|
||||
*
|
||||
* @param matcher 匹配到的Ipv4正则
|
||||
* @return ipv4对应long
|
||||
*/
|
||||
private static long matchAddress(Matcher matcher) {
|
||||
long addr = 0;
|
||||
for (int i = 1; i <= 4; ++i) {
|
||||
addr |= Long.parseLong(matcher.group(i)) << 8 * (4 - i);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
//-------------------------------------------------------------------------------- Private method end
|
||||
}
|
||||
|
@ -699,14 +699,15 @@ public class NetUtil {
|
||||
* @since 4.0.6
|
||||
*/
|
||||
public static boolean isInRange(String ip, String cidr) {
|
||||
String[] ips = StrUtil.splitToArray(ip, '.');
|
||||
int ipAddr = (Integer.parseInt(ips[0]) << 24) | (Integer.parseInt(ips[1]) << 16) | (Integer.parseInt(ips[2]) << 8) | Integer.parseInt(ips[3]);
|
||||
int type = Integer.parseInt(cidr.replaceAll(".*/", ""));
|
||||
int mask = 0xFFFFFFFF << (32 - type);
|
||||
String cidrIp = cidr.replaceAll("/.*", "");
|
||||
String[] cidrIps = cidrIp.split("\\.");
|
||||
int cidrIpAddr = (Integer.parseInt(cidrIps[0]) << 24) | (Integer.parseInt(cidrIps[1]) << 16) | (Integer.parseInt(cidrIps[2]) << 8) | Integer.parseInt(cidrIps[3]);
|
||||
return (ipAddr & mask) == (cidrIpAddr & mask);
|
||||
final int maskSplitMarkIndex = cidr.lastIndexOf(Ipv4Util.IP_MASK_SPLIT_MARK);
|
||||
if(maskSplitMarkIndex < 0){
|
||||
throw new IllegalArgumentException("Invalid cidr: " + cidr);
|
||||
}
|
||||
|
||||
final long mask = (-1L << 32 - Integer.parseInt(cidr.substring(maskSplitMarkIndex + 1)));
|
||||
long cidrIpAddr = ipv4ToLong(cidr.substring(0, maskSplitMarkIndex));
|
||||
|
||||
return (ipv4ToLong(ip) & mask) == (cidrIpAddr & mask);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,6 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
@ -118,7 +117,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
||||
public static <T> boolean hasNull(T... array) {
|
||||
if (isNotEmpty(array)) {
|
||||
for (T element : array) {
|
||||
if (null == element) {
|
||||
if (ObjectUtil.isNull(element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -150,7 +149,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T firstNonNull(T... array) {
|
||||
return firstMatch(Objects::nonNull, array);
|
||||
return firstMatch(ObjectUtil::isNotNull, array);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,7 +292,7 @@ public class ObjectUtil {
|
||||
* @since 3.0.7
|
||||
*/
|
||||
public static <T> T defaultIfNull(final T object, final T defaultValue) {
|
||||
return (null != object) ? object : defaultValue;
|
||||
return isNull(object) ? defaultValue : object;
|
||||
}
|
||||
|
||||
|
||||
@ -300,14 +300,14 @@ public class ObjectUtil {
|
||||
* 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值
|
||||
*
|
||||
* @param source Object 类型对象
|
||||
* @param handle 自定义的处理方法
|
||||
* @param handle 非空时自定义的处理方法
|
||||
* @param defaultValue 默认为空的返回值
|
||||
* @param <T> 被检查对象为{@code null}返回默认值,否则返回自定义handle处理后的返回值
|
||||
* @return 处理后的返回值
|
||||
* @since 5.4.6
|
||||
*/
|
||||
public static <T> T defaultIfNull(Object source, Supplier<? extends T> handle, final T defaultValue) {
|
||||
if (Objects.nonNull(source)) {
|
||||
if (isNotNull(source)) {
|
||||
return handle.get();
|
||||
}
|
||||
return defaultValue;
|
||||
|
@ -0,0 +1,146 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Console;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 系统属性工具<br>
|
||||
* 此工具用于读取系统属性或环境变量信息,封装包括:
|
||||
* <ul>
|
||||
* <li>{@link System#getProperty(String)}</li>
|
||||
* <li>{@link System#getenv(String)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.7.16
|
||||
*/
|
||||
public class SystemPropsUtil {
|
||||
|
||||
/** Hutool自定义系统属性:是否解析日期字符串采用严格模式 */
|
||||
public static String HUTOOL_DATE_LENIENT = "hutool.date.lenient";
|
||||
|
||||
/**
|
||||
* 取得系统属性,如果因为Java安全的限制而失败,则将错误打在Log中,然后返回 defaultValue
|
||||
*
|
||||
* @param name 属性名
|
||||
* @param defaultValue 默认值
|
||||
* @return 属性值或defaultValue
|
||||
* @see System#getProperty(String)
|
||||
* @see System#getenv(String)
|
||||
*/
|
||||
public static String get(String name, String defaultValue) {
|
||||
return StrUtil.nullToDefault(get(name, false), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得系统属性,如果因为Java安全的限制而失败,则将错误打在Log中,然后返回 {@code null}
|
||||
*
|
||||
* @param name 属性名
|
||||
* @param quiet 安静模式,不将出错信息打在{@code System.err}中
|
||||
* @return 属性值或{@code null}
|
||||
* @see System#getProperty(String)
|
||||
* @see System#getenv(String)
|
||||
*/
|
||||
public static String get(String name, boolean quiet) {
|
||||
String value = null;
|
||||
try {
|
||||
value = System.getProperty(name);
|
||||
} catch (SecurityException e) {
|
||||
if (false == quiet) {
|
||||
Console.error("Caught a SecurityException reading the system property '{}'; " +
|
||||
"the SystemUtil property value will default to null.", name);
|
||||
}
|
||||
}
|
||||
|
||||
if (null == value) {
|
||||
try {
|
||||
value = System.getenv(name);
|
||||
} catch (SecurityException e) {
|
||||
if (false == quiet) {
|
||||
Console.error("Caught a SecurityException reading the system env '{}'; " +
|
||||
"the SystemUtil env value will default to null.", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得System属性
|
||||
*
|
||||
* @param key 键
|
||||
* @return 属性值
|
||||
* @see System#getProperty(String)
|
||||
* @see System#getenv(String)
|
||||
*/
|
||||
public static String get(String key) {
|
||||
return get(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得boolean类型值
|
||||
*
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
*/
|
||||
public static boolean getBoolean(String key, boolean defaultValue) {
|
||||
String value = get(key);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
value = value.trim().toLowerCase();
|
||||
if (value.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Convert.toBool(value, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得int类型值
|
||||
*
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
*/
|
||||
public static long getInt(String key, int defaultValue) {
|
||||
return Convert.toInt(get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得long类型值
|
||||
*
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
*/
|
||||
public static long getLong(String key, long defaultValue) {
|
||||
return Convert.toLong(get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 属性列表
|
||||
*/
|
||||
public static Properties getProps() {
|
||||
return System.getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置系统属性,value为{@code null}表示移除此属性
|
||||
*
|
||||
* @param key 属性名
|
||||
* @param value 属性值,{@code null}表示移除此属性
|
||||
*/
|
||||
public static void set(String key, String value) {
|
||||
if (null == value) {
|
||||
System.clearProperty(key);
|
||||
} else {
|
||||
System.setProperty(key, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -63,6 +63,34 @@ public class OptTest {
|
||||
Assert.assertEquals("hutool", name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void peeksTest() {
|
||||
User user = new User();
|
||||
// 相当于上面peek的动态参数调用,更加灵活,你可以像操作数组一样去动态设置中间的步骤,也可以使用这种方式去编写你的代码
|
||||
// 可以一行搞定
|
||||
Opt.ofNullable("hutool").peeks(user::setUsername, user::setNickname);
|
||||
// 也可以在适当的地方换行使得代码的可读性提高
|
||||
Opt.of(user).peeks(
|
||||
u -> Assert.assertEquals("hutool", u.getNickname()),
|
||||
u -> Assert.assertEquals("hutool", u.getUsername())
|
||||
);
|
||||
Assert.assertEquals("hutool", user.getNickname());
|
||||
Assert.assertEquals("hutool", user.getUsername());
|
||||
|
||||
// 注意,传入的lambda中,对包裹内的元素执行赋值操作并不会影响到原来的元素,这是java语言的特性。。。
|
||||
// 这也是为什么我们需要getter和setter而不直接给bean中的属性赋值中的其中一个原因
|
||||
String name = Opt.ofNullable("hutool").peeks(
|
||||
username -> username = "123", username -> username = "456",
|
||||
n -> Assert.assertEquals("hutool", n)).get();
|
||||
Assert.assertEquals("hutool", name);
|
||||
|
||||
// 当然,以下情况不会抛出NPE,但也没什么意义
|
||||
Opt.ofNullable("hutool").peeks().peeks().peeks();
|
||||
Opt.ofNullable(null).peeks(i -> {
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void orTest() {
|
||||
// 这是jdk9 Optional中的新函数,直接照搬了过来
|
||||
|
@ -21,7 +21,7 @@ public class ValidatorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasNumberTest() throws Exception {
|
||||
public void hasNumberTest() {
|
||||
String var1 = "";
|
||||
String var2 = "str";
|
||||
String var3 = "180";
|
||||
@ -218,4 +218,13 @@ public class ValidatorTest {
|
||||
public void isCarDrivingLicenceTest(){
|
||||
Assert.assertTrue(Validator.isCarDrivingLicence("430101758218"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateIpv4Test(){
|
||||
Validator.validateIpv4("192.168.1.1", "Error ip");
|
||||
Validator.validateIpv4("8.8.8.8", "Error ip");
|
||||
Validator.validateIpv4("0.0.0.0", "Error ip");
|
||||
Validator.validateIpv4("255.255.255.255", "Error ip");
|
||||
Validator.validateIpv4("127.0.0.0", "Error ip");
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
package cn.hutool.core.net;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.function.ThrowingRunnable;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.function.ThrowingRunnable;
|
||||
|
||||
public class Ipv4UtilTest {
|
||||
|
||||
@ -40,7 +39,7 @@ public class Ipv4UtilTest {
|
||||
String ip = "192.168.1.1";
|
||||
final int maskBitByMask = Ipv4Util.getMaskBitByMask("255.255.255.0");
|
||||
final String endIpStr = Ipv4Util.getEndIpStr(ip, maskBitByMask);
|
||||
Console.log(endIpStr);
|
||||
Assert.assertEquals("192.168.1.255", endIpStr);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -75,4 +74,16 @@ public class Ipv4UtilTest {
|
||||
boolean maskBitValid = Ipv4Util.isMaskBitValid(33);
|
||||
Assert.assertFalse("掩码位非法检验", maskBitValid);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ipv4ToLongTest(){
|
||||
long l = Ipv4Util.ipv4ToLong("127.0.0.1");
|
||||
Assert.assertEquals(2130706433L, l);
|
||||
l = Ipv4Util.ipv4ToLong("114.114.114.114");
|
||||
Assert.assertEquals(1920103026L, l);
|
||||
l = Ipv4Util.ipv4ToLong("0.0.0.0");
|
||||
Assert.assertEquals(0L, l);
|
||||
l = Ipv4Util.ipv4ToLong("255.255.255.255");
|
||||
Assert.assertEquals(4294967295L, l);
|
||||
}
|
||||
}
|
||||
|
@ -101,4 +101,15 @@ public class NetUtilTest {
|
||||
Console.log(txt);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isInRangeTest(){
|
||||
Assert.assertTrue(NetUtil.isInRange("114.114.114.114","0.0.0.0/0"));
|
||||
Assert.assertTrue(NetUtil.isInRange("192.168.3.4","192.0.0.0/8"));
|
||||
Assert.assertTrue(NetUtil.isInRange("192.168.3.4","192.168.0.0/16"));
|
||||
Assert.assertTrue(NetUtil.isInRange("192.168.3.4","192.168.3.0/24"));
|
||||
Assert.assertTrue(NetUtil.isInRange("192.168.3.4","192.168.3.4/32"));
|
||||
Assert.assertFalse(NetUtil.isInRange("8.8.8.8","192.0.0.0/8"));
|
||||
Assert.assertFalse(NetUtil.isInRange("114.114.114.114","192.168.3.4/32"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
<mail.version>1.6.2</mail.version>
|
||||
<jsch.version>0.1.55</jsch.version>
|
||||
<zxing.version>3.4.1</zxing.version>
|
||||
<net.version>3.7.2</net.version>
|
||||
<net.version>3.8.0</net.version>
|
||||
<emoji-java.version>5.1.1</emoji-java.version>
|
||||
<servlet-api.version>4.0.1</servlet-api.version>
|
||||
<spring-boot.version>2.5.6</spring-boot.version>
|
||||
|
@ -608,8 +608,9 @@ public class MailAccount implements Serializable {
|
||||
this.host = StrUtil.format("smtp.{}", StrUtil.subSuf(fromAddress, fromAddress.indexOf('@') + 1));
|
||||
}
|
||||
if (StrUtil.isBlank(user)) {
|
||||
// 如果用户名为空,默认为发件人邮箱前缀
|
||||
this.user = StrUtil.subPre(fromAddress, fromAddress.indexOf('@'));
|
||||
// 如果用户名为空,默认为发件人(issue#I4FYVY@Gitee)
|
||||
//this.user = StrUtil.subPre(fromAddress, fromAddress.indexOf('@'));
|
||||
this.user = fromAddress;
|
||||
}
|
||||
if (null == this.auth) {
|
||||
// 如果密码非空白,则使用认证模式
|
||||
|
@ -11,7 +11,7 @@ port = 465
|
||||
# 发件人(必须正确,否则发送失败)
|
||||
from = 小磊<hutool@yeah.net>
|
||||
# 用户名(注意:如果使用foxmail邮箱,此处user为qq号)
|
||||
user = hutool
|
||||
user = hutool@yeah.net
|
||||
# 密码
|
||||
pass = q1w2e3
|
||||
# 使用 STARTTLS安全连接
|
||||
|
@ -4,7 +4,7 @@ import cn.hutool.core.bean.BeanPath;
|
||||
import cn.hutool.core.collection.ArrayIter;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Filter;
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import cn.hutool.core.lang.mutable.MutablePair;
|
||||
import cn.hutool.core.text.StrJoiner;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
@ -446,13 +446,13 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
/**
|
||||
* 加入或者替换JSONArray中指定Index的值,如果index大于JSONArray的长度,将在指定index设置值,之前的位置填充JSONNull.Null
|
||||
*
|
||||
* @param index 位置
|
||||
* @param index 位置
|
||||
* @param element 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
||||
* @return 替换的值,即之前的值
|
||||
*/
|
||||
@Override
|
||||
public Object set(int index, Object element) {
|
||||
if(index >= size()){
|
||||
if (index >= size()) {
|
||||
add(index, element);
|
||||
}
|
||||
return this.rawList.set(index, JSONUtil.wrap(element, this.config));
|
||||
@ -537,11 +537,11 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
* 支持过滤器,即选择哪些字段或值不写出
|
||||
*
|
||||
* @param indentFactor 每层缩进空格数
|
||||
* @param filter 键值对过滤器
|
||||
* @param filter 过滤器,可以修改值,key(index)无法修改
|
||||
* @return JSON字符串
|
||||
* @since 5.7.15
|
||||
*/
|
||||
public String toJSONString(int indentFactor, Filter<Pair<Integer, Object>> filter){
|
||||
public String toJSONString(int indentFactor, Filter<MutablePair<Integer, Object>> filter) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
synchronized (sw.getBuffer()) {
|
||||
return this.write(sw, indentFactor, 0, filter).toString();
|
||||
@ -560,18 +560,19 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
* @param writer writer
|
||||
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
||||
* @param indent 本级别缩进量
|
||||
* @param filter 过滤器
|
||||
* @param filter 过滤器,可以修改值,key(index)无法修改
|
||||
* @return Writer
|
||||
* @throws JSONException JSON相关异常
|
||||
* @since 5.7.15
|
||||
*/
|
||||
public Writer write(Writer writer, int indentFactor, int indent, Filter<Pair<Integer, Object>> filter) throws JSONException {
|
||||
public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Integer, Object>> filter) throws JSONException {
|
||||
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
||||
.beginArray();
|
||||
|
||||
CollUtil.forEach(this, (value, index)->{
|
||||
if (null == filter || filter.accept(new Pair<>(index, value))) {
|
||||
jsonWriter.writeValue(value);
|
||||
CollUtil.forEach(this, (value, index) -> {
|
||||
final MutablePair<Integer, Object> pair = new MutablePair<>(index, value);
|
||||
if (null == filter || filter.accept(pair)) {
|
||||
jsonWriter.writeValue(pair.getValue());
|
||||
}
|
||||
});
|
||||
jsonWriter.end();
|
||||
@ -580,6 +581,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
|
@ -7,7 +7,7 @@ import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Filter;
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import cn.hutool.core.lang.mutable.MutablePair;
|
||||
import cn.hutool.core.map.CaseInsensitiveLinkedMap;
|
||||
import cn.hutool.core.map.CaseInsensitiveMap;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
@ -560,11 +560,11 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
||||
* 支持过滤器,即选择哪些字段或值不写出
|
||||
*
|
||||
* @param indentFactor 每层缩进空格数
|
||||
* @param filter 键值对过滤器
|
||||
* @param filter 过滤器,同时可以修改编辑键和值
|
||||
* @return JSON字符串
|
||||
* @since 5.7.15
|
||||
*/
|
||||
public String toJSONString(int indentFactor, Filter<Pair<String, Object>> filter){
|
||||
public String toJSONString(int indentFactor, Filter<MutablePair<String, Object>> filter) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
synchronized (sw.getBuffer()) {
|
||||
return this.write(sw, indentFactor, 0, filter).toString();
|
||||
@ -583,17 +583,18 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
||||
* @param writer writer
|
||||
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
||||
* @param indent 本级别缩进量
|
||||
* @param filter 过滤器
|
||||
* @param filter 过滤器,同时可以修改编辑键和值
|
||||
* @return Writer
|
||||
* @throws JSONException JSON相关异常
|
||||
* @since 5.7.15
|
||||
*/
|
||||
public Writer write(Writer writer, int indentFactor, int indent, Filter<Pair<String, Object>> filter) throws JSONException {
|
||||
public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<String, Object>> filter) throws JSONException {
|
||||
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
||||
.beginObj();
|
||||
this.forEach((key, value) -> {
|
||||
if (null == filter || filter.accept(new Pair<>(key, value))) {
|
||||
jsonWriter.writeField(key, value);
|
||||
final MutablePair<String, Object> pair = new MutablePair<>(key, value);
|
||||
if (null == filter || filter.accept(pair)) {
|
||||
jsonWriter.writeField(pair.getKey(), pair.getValue());
|
||||
}
|
||||
});
|
||||
jsonWriter.end();
|
||||
|
@ -10,6 +10,7 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.test.bean.JSONBean;
|
||||
import cn.hutool.json.test.bean.ResultDto;
|
||||
@ -67,7 +68,7 @@ public class JSONObjectTest {
|
||||
@Test
|
||||
public void toStringTest3() {
|
||||
JSONObject json = Objects.requireNonNull(JSONUtil.createObj()//
|
||||
.set("dateTime", DateUtil.parse("2019-05-02 22:12:01")))//
|
||||
.set("dateTime", DateUtil.parse("2019-05-02 22:12:01")))//
|
||||
.setDateFormat(DatePattern.NORM_DATE_PATTERN);
|
||||
Assert.assertEquals("{\"dateTime\":\"2019-05-02\"}", json.toString());
|
||||
}
|
||||
@ -86,14 +87,14 @@ public class JSONObjectTest {
|
||||
@Test
|
||||
public void putAllTest() {
|
||||
JSONObject json1 = JSONUtil.createObj()
|
||||
.set("a", "value1")
|
||||
.set("b", "value2")
|
||||
.set("c", "value3")
|
||||
.set("d", true);
|
||||
.set("a", "value1")
|
||||
.set("b", "value2")
|
||||
.set("c", "value3")
|
||||
.set("d", true);
|
||||
|
||||
JSONObject json2 = JSONUtil.createObj()
|
||||
.set("a", "value21")
|
||||
.set("b", "value22");
|
||||
.set("a", "value21")
|
||||
.set("b", "value22");
|
||||
|
||||
// putAll操作会覆盖相同key的值,因此a,b两个key的值改变,c的值不变
|
||||
json1.putAll(json2);
|
||||
@ -399,7 +400,7 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aliasTest(){
|
||||
public void aliasTest() {
|
||||
final BeanWithAlias beanWithAlias = new BeanWithAlias();
|
||||
beanWithAlias.setValue1("张三");
|
||||
beanWithAlias.setValue2(35);
|
||||
@ -417,7 +418,7 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDateFormatTest(){
|
||||
public void setDateFormatTest() {
|
||||
JSONConfig jsonConfig = JSONConfig.create();
|
||||
jsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
jsonConfig.setOrder(true);
|
||||
@ -430,7 +431,7 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDateFormatTest2(){
|
||||
public void setDateFormatTest2() {
|
||||
JSONConfig jsonConfig = JSONConfig.create();
|
||||
jsonConfig.setDateFormat("yyyy#MM#dd");
|
||||
jsonConfig.setOrder(true);
|
||||
@ -451,7 +452,7 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setCustomDateFormatTest(){
|
||||
public void setCustomDateFormatTest() {
|
||||
JSONConfig jsonConfig = JSONConfig.create();
|
||||
jsonConfig.setDateFormat("#sss");
|
||||
jsonConfig.setOrder(true);
|
||||
@ -472,7 +473,7 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTimestampTest(){
|
||||
public void getTimestampTest() {
|
||||
String timeStr = "1970-01-01 00:00:00";
|
||||
final JSONObject jsonObject = JSONUtil.createObj().set("time", timeStr);
|
||||
final Timestamp time = jsonObject.get("time", Timestamp.class);
|
||||
@ -518,7 +519,7 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseBeanSameNameTest(){
|
||||
public void parseBeanSameNameTest() {
|
||||
final SameNameBean sameNameBean = new SameNameBean();
|
||||
final JSONObject parse = JSONUtil.parseObj(sameNameBean);
|
||||
Assert.assertEquals("123", parse.getStr("username"));
|
||||
@ -537,9 +538,11 @@ public class JSONObjectTest {
|
||||
public static class SameNameBean {
|
||||
private final String username = "123";
|
||||
private final String userName = "abc";
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@PropIgnore
|
||||
private final String fieldToIgnore = "sfdsdads";
|
||||
|
||||
@ -547,13 +550,13 @@ public class JSONObjectTest {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public String getFieldToIgnore(){
|
||||
public String getFieldToIgnore() {
|
||||
return this.fieldToIgnore;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setEntryTest(){
|
||||
public void setEntryTest() {
|
||||
final HashMap<String, String> of = MapUtil.of("test", "testValue");
|
||||
final Set<Map.Entry<String, String>> entries = of.entrySet();
|
||||
final Map.Entry<String, String> next = entries.iterator().next();
|
||||
@ -563,13 +566,13 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test(expected = JSONException.class)
|
||||
public void createJSONObjectTest(){
|
||||
public void createJSONObjectTest() {
|
||||
// 集合类不支持转为JSONObject
|
||||
new JSONObject(new JSONArray(), JSONConfig.create());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void floatTest(){
|
||||
public void floatTest() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("c", 2.0F);
|
||||
|
||||
@ -578,7 +581,7 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accumulateTest(){
|
||||
public void accumulateTest() {
|
||||
final JSONObject jsonObject = JSONUtil.createObj().accumulate("key1", "value1");
|
||||
Assert.assertEquals("{\"key1\":\"value1\"}", jsonObject.toString());
|
||||
|
||||
@ -598,7 +601,7 @@ public class JSONObjectTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void bigDecimalTest(){
|
||||
public void bigDecimalTest() {
|
||||
String jsonStr = "{\"orderId\":\"1704747698891333662002277\"}";
|
||||
BigDecimalBean bigDecimalBean = JSONUtil.toBean(jsonStr, BigDecimalBean.class);
|
||||
Assert.assertEquals("{\"orderId\":1704747698891333662002277}", JSONUtil.toJsonStr(bigDecimalBean));
|
||||
@ -606,12 +609,12 @@ public class JSONObjectTest {
|
||||
|
||||
@Data
|
||||
static
|
||||
class BigDecimalBean{
|
||||
class BigDecimalBean {
|
||||
private BigDecimal orderId;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterIncludeTest(){
|
||||
public void filterIncludeTest() {
|
||||
JSONObject json1 = JSONUtil.createObj(JSONConfig.create().setOrder(true))
|
||||
.set("a", "value1")
|
||||
.set("b", "value2")
|
||||
@ -623,7 +626,7 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterExcludeTest(){
|
||||
public void filterExcludeTest() {
|
||||
JSONObject json1 = JSONUtil.createObj(JSONConfig.create().setOrder(true))
|
||||
.set("a", "value1")
|
||||
.set("b", "value2")
|
||||
@ -633,4 +636,37 @@ public class JSONObjectTest {
|
||||
final String s = json1.toJSONString(0, (pair) -> false == pair.getKey().equals("b"));
|
||||
Assert.assertEquals("{\"a\":\"value1\",\"c\":\"value3\",\"d\":true}", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void editTest() {
|
||||
JSONObject json1 = JSONUtil.createObj(JSONConfig.create().setOrder(true))
|
||||
.set("a", "value1")
|
||||
.set("b", "value2")
|
||||
.set("c", "value3")
|
||||
.set("d", true);
|
||||
|
||||
final String s = json1.toJSONString(0, (pair) -> {
|
||||
if ("b".equals(pair.getKey())) {
|
||||
// 修改值为新值
|
||||
pair.setValue(pair.getValue() + "_edit");
|
||||
return true;
|
||||
}
|
||||
// 除了"b",其他都去掉
|
||||
return false;
|
||||
});
|
||||
Assert.assertEquals("{\"b\":\"value2_edit\"}", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullToEmptyTest() {
|
||||
JSONObject json1 = JSONUtil.createObj(JSONConfig.create().setOrder(true).setIgnoreNullValue(false))
|
||||
.set("a", null)
|
||||
.set("b", "value2");
|
||||
|
||||
final String s = json1.toJSONString(0, (pair) -> {
|
||||
pair.setValue(ObjectUtil.defaultIfNull(pair.getValue(), StrUtil.EMPTY));
|
||||
return true;
|
||||
});
|
||||
Assert.assertEquals("{\"a\":\"\",\"b\":\"value2\"}", s);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.SystemPropsUtil;
|
||||
import cn.hutool.log.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@ -24,7 +25,7 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Setting文件加载器
|
||||
*
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
@ -47,7 +48,7 @@ public class SettingLoader {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
*
|
||||
* @param groupedMap GroupedMap
|
||||
*/
|
||||
public SettingLoader(GroupedMap groupedMap) {
|
||||
@ -56,7 +57,7 @@ public class SettingLoader {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
*
|
||||
* @param groupedMap GroupedMap
|
||||
* @param charset 编码
|
||||
* @param isUseVariable 是否使用变量
|
||||
@ -69,7 +70,7 @@ public class SettingLoader {
|
||||
|
||||
/**
|
||||
* 加载设置文件
|
||||
*
|
||||
*
|
||||
* @param resource 配置文件URL
|
||||
* @return 加载是否成功
|
||||
*/
|
||||
@ -93,7 +94,7 @@ public class SettingLoader {
|
||||
|
||||
/**
|
||||
* 加载设置文件。 此方法不会关闭流对象
|
||||
*
|
||||
*
|
||||
* @param settingStream 文件流
|
||||
* @return 加载成功与否
|
||||
* @throws IOException IO异常
|
||||
@ -146,7 +147,7 @@ public class SettingLoader {
|
||||
/**
|
||||
* 设置变量的正则<br>
|
||||
* 正则只能有一个group表示变量本身,剩余为字符 例如 \$\{(name)\}表示${name}变量名为name的一个变量表示
|
||||
*
|
||||
*
|
||||
* @param regex 正则
|
||||
*/
|
||||
public void setVarRegex(String regex) {
|
||||
@ -155,7 +156,7 @@ public class SettingLoader {
|
||||
|
||||
/**
|
||||
* 赋值分隔符(用于分隔键值对)
|
||||
*
|
||||
*
|
||||
* @param assignFlag 正则
|
||||
* @since 4.6.5
|
||||
*/
|
||||
@ -166,7 +167,7 @@ public class SettingLoader {
|
||||
/**
|
||||
* 持久化当前设置,会覆盖掉之前的设置<br>
|
||||
* 持久化会不会保留之前的分组
|
||||
*
|
||||
*
|
||||
* @param absolutePath 设置文件的绝对路径
|
||||
*/
|
||||
public void store(String absolutePath) {
|
||||
@ -194,7 +195,7 @@ public class SettingLoader {
|
||||
|
||||
/**
|
||||
* 存储到Writer
|
||||
*
|
||||
*
|
||||
* @param writer Writer
|
||||
*/
|
||||
synchronized private void store(PrintWriter writer) {
|
||||
@ -209,7 +210,7 @@ public class SettingLoader {
|
||||
// ----------------------------------------------------------------------------------- Private method start
|
||||
/**
|
||||
* 替换给定值中的变量标识
|
||||
*
|
||||
*
|
||||
* @param group 所在分组
|
||||
* @param value 值
|
||||
* @return 替换后的字符串
|
||||
@ -230,13 +231,9 @@ public class SettingLoader {
|
||||
varValue = this.groupedMap.get(groupAndKey.get(0), groupAndKey.get(1));
|
||||
}
|
||||
}
|
||||
// 系统参数中查找
|
||||
// 系统参数和环境变量中查找
|
||||
if (null == varValue) {
|
||||
varValue = System.getProperty(key);
|
||||
}
|
||||
// 环境变量中查找
|
||||
if (null == varValue) {
|
||||
varValue = System.getenv(key);
|
||||
varValue = SystemPropsUtil.get(key);
|
||||
}
|
||||
|
||||
if (null != varValue) {
|
||||
|
@ -13,7 +13,7 @@ public class YamlUtilTest {
|
||||
|
||||
@Test
|
||||
public void loadByPathTest() {
|
||||
final Dict result = YamlUtil.loadByPath("test.yaml", Dict.class);
|
||||
final Dict result = YamlUtil.loadByPath("test.yaml");
|
||||
|
||||
Assert.assertEquals("John", result.getStr("firstName"));
|
||||
|
||||
|
@ -11,3 +11,4 @@ homeAddress:
|
||||
city: "City Y"
|
||||
state: "State Y"
|
||||
zip: 345657
|
||||
123: 345
|
||||
|
@ -1,9 +1,9 @@
|
||||
package cn.hutool.system;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.lang.Singleton;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.SystemPropsUtil;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.management.ClassLoadingMXBean;
|
||||
@ -17,7 +17,6 @@ import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Java的System类封装工具类。<br>
|
||||
@ -25,7 +24,7 @@ import java.util.Properties;
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class SystemUtil {
|
||||
public class SystemUtil extends SystemPropsUtil {
|
||||
|
||||
// ----- Java运行时环境信息 -----/
|
||||
/**
|
||||
@ -149,117 +148,6 @@ public class SystemUtil {
|
||||
*/
|
||||
public final static String USER_DIR = SystemPropsKeys.USER_DIR;
|
||||
|
||||
// ----------------------------------------------------------------------- Basic start
|
||||
|
||||
/**
|
||||
* 取得系统属性,如果因为Java安全的限制而失败,则将错误打在Log中,然后返回 defaultValue
|
||||
*
|
||||
* @param name 属性名
|
||||
* @param defaultValue 默认值
|
||||
* @return 属性值或defaultValue
|
||||
* @see System#getProperty(String)
|
||||
* @see System#getenv(String)
|
||||
*/
|
||||
public static String get(String name, String defaultValue) {
|
||||
return StrUtil.nullToDefault(get(name, false), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得系统属性,如果因为Java安全的限制而失败,则将错误打在Log中,然后返回 {@code null}
|
||||
*
|
||||
* @param name 属性名
|
||||
* @param quiet 安静模式,不将出错信息打在{@code System.err}中
|
||||
* @return 属性值或{@code null}
|
||||
* @see System#getProperty(String)
|
||||
* @see System#getenv(String)
|
||||
*/
|
||||
public static String get(String name, boolean quiet) {
|
||||
String value = null;
|
||||
try {
|
||||
value = System.getProperty(name);
|
||||
} catch (SecurityException e) {
|
||||
if (false == quiet) {
|
||||
Console.error("Caught a SecurityException reading the system property '{}'; " +
|
||||
"the SystemUtil property value will default to null.", name);
|
||||
}
|
||||
}
|
||||
|
||||
if (null == value) {
|
||||
try {
|
||||
value = System.getenv(name);
|
||||
} catch (SecurityException e) {
|
||||
if (false == quiet) {
|
||||
Console.error("Caught a SecurityException reading the system env '{}'; " +
|
||||
"the SystemUtil env value will default to null.", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得System属性
|
||||
*
|
||||
* @param key 键
|
||||
* @return 属性值
|
||||
* @see System#getProperty(String)
|
||||
* @see System#getenv(String)
|
||||
*/
|
||||
public static String get(String key) {
|
||||
return get(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得boolean类型值
|
||||
*
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
*/
|
||||
public static boolean getBoolean(String key, boolean defaultValue) {
|
||||
String value = get(key);
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
value = value.trim().toLowerCase();
|
||||
if (value.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Convert.toBool(value, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得int类型值
|
||||
*
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
*/
|
||||
public static long getInt(String key, int defaultValue) {
|
||||
return Convert.toInt(get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得long类型值
|
||||
*
|
||||
* @param key 键
|
||||
* @param defaultValue 默认值
|
||||
* @return 值
|
||||
*/
|
||||
public static long getLong(String key, long defaultValue) {
|
||||
return Convert.toLong(get(key), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 属性列表
|
||||
*/
|
||||
public static Properties props() {
|
||||
return System.getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前进程 PID
|
||||
*
|
||||
@ -268,7 +156,6 @@ public class SystemUtil {
|
||||
public static long getCurrentPID() {
|
||||
return Long.parseLong(getRuntimeMXBean().getName().split("@")[0]);
|
||||
}
|
||||
// ----------------------------------------------------------------------- Basic end
|
||||
|
||||
/**
|
||||
* 返回Java虚拟机类加载系统相关属性
|
||||
|
Loading…
Reference in New Issue
Block a user