From 66167d0656bcab664d24f8dbc26fae60b9c93daf Mon Sep 17 00:00:00 2001 From: looly Date: Thu, 31 Jan 2019 18:46:49 +0000 Subject: [PATCH 1/7] prepare 4.4.5 --- CHANGELOG.md | 8 ++++++++ README.md | 8 ++++---- docs/index.html | 6 +++--- hutool-all/pom.xml | 2 +- hutool-aop/pom.xml | 2 +- hutool-bloomFilter/pom.xml | 2 +- hutool-cache/pom.xml | 2 +- hutool-captcha/pom.xml | 2 +- hutool-core/pom.xml | 2 +- hutool-cron/pom.xml | 2 +- hutool-crypto/pom.xml | 2 +- hutool-db/pom.xml | 2 +- hutool-dfa/pom.xml | 2 +- hutool-extra/pom.xml | 2 +- hutool-http/pom.xml | 2 +- hutool-json/pom.xml | 2 +- hutool-log/pom.xml | 2 +- hutool-poi/pom.xml | 2 +- hutool-script/pom.xml | 2 +- hutool-setting/pom.xml | 2 +- hutool-system/pom.xml | 2 +- pom.xml | 2 +- 22 files changed, 34 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54cc1c7f81..73122967f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ ------------------------------------------------------------------------------------------------------------- +## 4.4.5 + +### 新特性 + +### Bug修复 + +------------------------------------------------------------------------------------------------------------- + ## 4.4.4 ### 新特性 diff --git a/README.md b/README.md index bb67578d13..f2b8592e90 100644 --- a/README.md +++ b/README.md @@ -86,21 +86,21 @@ Hutool是Hu + tool的自造词,谐音“糊涂”,寓意追求“万事都 cn.hutool hutool-all - 4.4.4 + 4.4.5 ``` ### Gradle ``` -compile 'cn.hutool:hutool-all:4.4.4' +compile 'cn.hutool:hutool-all:4.4.5' ``` ### 非Maven项目 点击以下任一链接,下载`hutool-all-X.X.X.jar`即可: -- [Maven中央库1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/4.4.4/) -- [Maven中央库2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/4.4.4/) +- [Maven中央库1](https://repo1.maven.org/maven2/cn/hutool/hutool-all/4.4.5/) +- [Maven中央库2](http://repo2.maven.org/maven2/cn/hutool/hutool-all/4.4.5/) > 注意 > Hutool只支持JDK7+,对应Android平台没有测试,部分方法并不支持。 diff --git a/docs/index.html b/docs/index.html index cb855c5a4c..a33cfb7b4e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -60,7 +60,7 @@

Hutool - v4.4.4 + v4.4.5

A set of tools that keep Java sweet.

@@ -143,12 +143,12 @@

A set of tools that keep Java sweet.

<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> - <version>4.4.4</version> + <version>4.4.5</version> </dependency>
Gradle:
-									compile 'cn.hutool:hutool-all:4.4.4'
+									compile 'cn.hutool:hutool-all:4.4.5'
 								

从Maven安装 diff --git a/hutool-all/pom.xml b/hutool-all/pom.xml index ee412ce837..59c375a8bc 100644 --- a/hutool-all/pom.xml +++ b/hutool-all/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-all diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml index 1e00b27a8d..c273e116fd 100644 --- a/hutool-aop/pom.xml +++ b/hutool-aop/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-aop diff --git a/hutool-bloomFilter/pom.xml b/hutool-bloomFilter/pom.xml index eecafa67a3..639448bbb4 100644 --- a/hutool-bloomFilter/pom.xml +++ b/hutool-bloomFilter/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-bloomFilter diff --git a/hutool-cache/pom.xml b/hutool-cache/pom.xml index cf30c73844..de492088ba 100644 --- a/hutool-cache/pom.xml +++ b/hutool-cache/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-cache diff --git a/hutool-captcha/pom.xml b/hutool-captcha/pom.xml index b5a679b3ac..a67499ffbc 100644 --- a/hutool-captcha/pom.xml +++ b/hutool-captcha/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-captcha diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index a6c0693071..5ffd77a05e 100644 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-core diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index 57eaf52d67..4d574159db 100644 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index 870b5116f0..8b3284c015 100644 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index 9ff5cc1e1f..526c153e8d 100644 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index c0a9e63228..13b5c55394 100644 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-dfa diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index 26007c6ac8..0155a35387 100644 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-extra diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index e0d189b685..53d3178b86 100644 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-http diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index d950c2ed7d..727a3b4d85 100644 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-json diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 4fe83e51ec..cbbbe8aa97 100644 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index dc84df0123..91967c1236 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index 04265934da..d8d18ba67a 100644 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index 2dfbc99747..94925e1709 100644 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-setting diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index 032392ddc8..2adbdb3305 100644 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool-system diff --git a/pom.xml b/pom.xml index 2141840c7a..26c881ac2c 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 4.4.4 + 4.4.5-SNAPSHOT hutool 提供丰富的Java工具方法 https://github.com/looly/hutool From 6b559d788d0fdc418ecc659083385db2195399ef Mon Sep 17 00:00:00 2001 From: looly Date: Sat, 2 Feb 2019 14:24:53 +0000 Subject: [PATCH 2/7] fix StrFormater --- CHANGELOG.md | 2 +- .../cn/hutool/core/text/StrFormatter.java | 62 ++++++++++--------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73122967f8..733311d56d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ## 4.4.5 ### 新特性 +* 【core】 增加StrFormater代码逻辑可读性(pr#269@Github) ### Bug修复 @@ -19,7 +20,6 @@ ### Bug修复 * 【core】 修复Profile中路径参数失效问题(issue#265@Github) -* 【core】 修复Profile中路径参数失效问题 * 【core】 修复MapConvert中值类型转换错误的问题(issue#268@Github) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/text/StrFormatter.java b/hutool-core/src/main/java/cn/hutool/core/text/StrFormatter.java index b3c49e3a8d..03a87e59c6 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/StrFormatter.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/StrFormatter.java @@ -5,6 +5,7 @@ /** * 字符串格式化工具 + * * @author Looly * */ @@ -15,9 +16,10 @@ public class StrFormatter { * 此方法只是简单将占位符 {} 按照顺序替换为参数
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
* 例:
- * 通常使用:format("this is {} for {}", "a", "b") =》 this is a for b
- * 转义{}: format("this is \\{} for {}", "a", "b") =》 this is \{} for a
- * 转义\: format("this is \\\\{} for {}", "a", "b") =》 this is \a for b
+ * 通常使用:format("this is {} for {}", "a", "b") =》 this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") =》 this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") =》 this is \a for b
+ * * @param strPattern 字符串模板 * @param argArray 参数列表 * @return 结果 @@ -28,45 +30,47 @@ public static String format(final String strPattern, final Object... argArray) { } final int strPatternLength = strPattern.length(); - //初始化定义好的长度以获得更好的性能 + // 初始化定义好的长度以获得更好的性能 StringBuilder sbuf = new StringBuilder(strPatternLength + 50); - int handledPosition = 0;//记录已经处理到的位置 - int delimIndex;//占位符所在位置 + int handledPosition = 0;// 记录已经处理到的位置 + int delimIndex;// 占位符所在位置 for (int argIndex = 0; argIndex < argArray.length; argIndex++) { delimIndex = strPattern.indexOf(StrUtil.EMPTY_JSON, handledPosition); - if (delimIndex == -1) {//剩余部分无占位符 - if (handledPosition == 0) { //不带占位符的模板直接返回 + if (delimIndex == -1) {// 剩余部分无占位符 + if (handledPosition == 0) { // 不带占位符的模板直接返回 return strPattern; - } else { //字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 - sbuf.append(strPattern, handledPosition, strPatternLength); - return sbuf.toString(); } - } else { - if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == StrUtil.C_BACKSLASH) {//转义符 - if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == StrUtil.C_BACKSLASH) {//双转义符 - //转义符之前还有一个转义符,占位符依旧有效 - sbuf.append(strPattern, handledPosition, delimIndex - 1); - sbuf.append(StrUtil.utf8Str(argArray[argIndex])); - handledPosition = delimIndex + 2; - } else { - //占位符被转义 - argIndex--; - sbuf.append(strPattern, handledPosition, delimIndex - 1); - sbuf.append(StrUtil.C_DELIM_START); - handledPosition = delimIndex + 1; - } - } else {//正常占位符 - sbuf.append(strPattern, handledPosition, delimIndex); + // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + + // 转义符 + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == StrUtil.C_BACKSLASH) {// 转义符 + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == StrUtil.C_BACKSLASH) {// 双转义符 + // 转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); sbuf.append(StrUtil.utf8Str(argArray[argIndex])); handledPosition = delimIndex + 2; + } else { + // 占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(StrUtil.C_DELIM_START); + handledPosition = delimIndex + 1; } + } else {// 正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(StrUtil.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; } } + // append the characters following the last {} pair. - //加入最后一个占位符后所有的字符 + // 加入最后一个占位符后所有的字符 sbuf.append(strPattern, handledPosition, strPattern.length()); - + return sbuf.toString(); } } From 164863b9e50b80fb1a14ca3648ce9109a4a3bfa7 Mon Sep 17 00:00:00 2001 From: looly Date: Sat, 2 Feb 2019 15:10:02 +0000 Subject: [PATCH 3/7] fix StrFormater --- CHANGELOG.md | 1 + .../java/cn/hutool/core/lang/Validator.java | 266 ++++++++++++++---- 2 files changed, 215 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 733311d56d..2ca53b05ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### 新特性 * 【core】 增加StrFormater代码逻辑可读性(pr#269@Github) +* 【core】 Validator中使用泛型 ### Bug修复 diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java b/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java index 6d57f66019..968c21d09a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Validator.java @@ -55,6 +55,62 @@ private Validator() { /** 中国车牌号码 */ public final static Pattern PLATE_NUMBER = PatternPool.PLATE_NUMBER; + /** + * 给定值是否为true + * + * @param value 值 + * @return 是否为ture + * @since 4.4.5 + */ + public static boolean isTrue(boolean value) { + return value; + } + + /** + * 给定值是否不为false + * + * @param value 值 + * @return 是否不为false + * @since 4.4.5 + */ + public static boolean isFalse(boolean value) { + return false == value; + } + + /** + * 检查指定值是否为ture + * + * @param value 值 + * @param errorMsgTemplate 错误消息内容模板(变量使用{}表示) + * @param params 模板中变量替换后的值 + * @return 检查过后的值 + * @throws ValidateException 检查不满足条件抛出的异常 + * @since 4.4.5 + */ + public static boolean validateTrue(boolean value, String errorMsgTemplate, Object... params) throws ValidateException { + if (isFalse(value)) { + throw new ValidateException(errorMsgTemplate, params); + } + return value; + } + + /** + * 检查指定值是否为false + * + * @param value 值 + * @param errorMsgTemplate 错误消息内容模板(变量使用{}表示) + * @param params 模板中变量替换后的值 + * @return 检查过后的值 + * @throws ValidateException 检查不满足条件抛出的异常 + * @since 4.4.5 + */ + public static boolean validateFalse(boolean value, String errorMsgTemplate, Object... params) throws ValidateException { + if (isTrue(value)) { + throw new ValidateException(errorMsgTemplate, params); + } + return value; + } + /** * 给定值是否为null * @@ -75,6 +131,24 @@ public static boolean isNotNull(Object value) { return null != value; } + /** + * 检查指定值是否为非null + * + * @param 被检查的对象类型 + * @param value 值 + * @param errorMsgTemplate 错误消息内容模板(变量使用{}表示) + * @param params 模板中变量替换后的值 + * @return 检查过后的值 + * @throws ValidateException 检查不满足条件抛出的异常 + * @since 4.4.5 + */ + public static T validateNull(T value, String errorMsgTemplate, Object... params) throws ValidateException { + if (isNotNull(value)) { + throw new ValidateException(errorMsgTemplate, params); + } + return value; + } + /** * 检查指定值是否为null * @@ -122,12 +196,30 @@ public static boolean isNotEmpty(Object value) { * * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值,验证通过返回此值,空值 * @throws ValidateException 验证异常 */ - public static void validateNotEmpty(Object value, String errorMsg) throws ValidateException { + public static T validateEmpty(T value, String errorMsg) throws ValidateException { + if (isNotEmpty(value)) { + throw new ValidateException(errorMsg); + } + return value; + } + + /** + * 验证是否为空,为空时抛出异常
+ * 对于String类型判定是否为empty(null 或 "")
+ * + * @param value 值 + * @param errorMsg 验证错误的信息 + * @return 验证后的值,验证通过返回此值,非空值 + * @throws ValidateException 验证异常 + */ + public static T validateNotEmpty(T value, String errorMsg) throws ValidateException { if (isEmpty(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -148,12 +240,14 @@ public static boolean equal(Object t1, Object t2) { * @param t1 对象1 * @param t2 对象2 * @param errorMsg 错误信息 + * @return 相同值 * @throws ValidateException 验证异常 */ - public static void validateEqual(Object t1, Object t2, String errorMsg) throws ValidateException { + public static Object validateEqual(Object t1, Object t2, String errorMsg) throws ValidateException { if (false == equal(t1, t2)) { throw new ValidateException(errorMsg); } + return t1; } /** @@ -207,23 +301,26 @@ public static void validateNotEmptyAndNotEqual(Object t1, Object t2, String erro * @param value 值 * @return 是否匹配正则 */ - public static boolean isMactchRegex(String regex, String value) { + public static boolean isMactchRegex(String regex, CharSequence value) { return ReUtil.isMatch(regex, value); } /** * 通过正则表达式验证
- * 不符合正则 + * 不符合正则抛出{@link ValidateException} 异常 * + * @param 字符串类型 * @param regex 正则 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateMatchRegex(String regex, String value, String errorMsg) throws ValidateException { + public static T validateMatchRegex(String regex, T value, String errorMsg) throws ValidateException { if (false == isMactchRegex(regex, value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -233,7 +330,7 @@ public static void validateMatchRegex(String regex, String value, String errorMs * @param value 值 * @return 是否匹配正则 */ - public static boolean isMactchRegex(Pattern pattern, String value) { + public static boolean isMactchRegex(Pattern pattern, CharSequence value) { return ReUtil.isMatch(pattern, value); } @@ -243,21 +340,24 @@ public static boolean isMactchRegex(Pattern pattern, String value) { * @param value 值 * @return 是否为英文字母 、数字和下划线 */ - public static boolean isGeneral(String value) { + public static boolean isGeneral(CharSequence value) { return isMactchRegex(GENERAL, value); } /** * 验证是否为英文字母 、数字和下划线 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateGeneral(String value, String errorMsg) throws ValidateException { + public static T validateGeneral(T value, String errorMsg) throws ValidateException { if (false == isGeneral(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -268,7 +368,7 @@ public static void validateGeneral(String value, String errorMsg) throws Validat * @param max 最大长度,0或负数表示不限制最大长度 * @return 是否为给定长度范围的英文字母 、数字和下划线 */ - public static boolean isGeneral(String value, int min, int max) { + public static boolean isGeneral(CharSequence value, int min, int max) { String reg = "^\\w{" + min + "," + max + "}$"; if (min < 0) { min = 0; @@ -282,16 +382,19 @@ public static boolean isGeneral(String value, int min, int max) { /** * 验证是否为给定长度范围的英文字母 、数字和下划线 * + * @param 字符串类型 * @param value 值 * @param min 最小长度,负数自动识别为0 * @param max 最大长度,0或负数表示不限制最大长度 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateGeneral(String value, int min, int max, String errorMsg) throws ValidateException { + public static T validateGeneral(T value, int min, int max, String errorMsg) throws ValidateException { if (false == isGeneral(value, min, max)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -301,20 +404,22 @@ public static void validateGeneral(String value, int min, int max, String errorM * @param min 最小长度,负数自动识别为0 * @return 是否为给定最小长度的英文字母 、数字和下划线 */ - public static boolean isGeneral(String value, int min) { + public static boolean isGeneral(CharSequence value, int min) { return isGeneral(value, min, 0); } /** * 验证是否为给定最小长度的英文字母 、数字和下划线 * + * @param 字符串类型 * @param value 值 * @param min 最小长度,负数自动识别为0 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateGeneral(String value, int min, String errorMsg) throws ValidateException { - validateGeneral(value, min, 0, errorMsg); + public static T validateGeneral(T value, int min, String errorMsg) throws ValidateException { + return validateGeneral(value, min, 0, errorMsg); } /** @@ -324,7 +429,7 @@ public static void validateGeneral(String value, int min, String errorMsg) throw * @return 是否全部为字母组成,包括大写和小写字母和汉字 * @since 3.3.0 */ - public static boolean isLetter(String value) { + public static boolean isLetter(CharSequence value) { return StrUtil.isAllCharMatch(value, new cn.hutool.core.lang.Matcher() { @Override public boolean match(Character t) { @@ -336,15 +441,18 @@ public boolean match(Character t) { /** * 验证是否全部为字母组成,包括大写和小写字母和汉字 * + * @param 字符串类型 * @param value 表单值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 * @since 3.3.0 */ - public static void validateLetter(String value, String errorMsg) throws ValidateException { + public static T validateLetter(T value, String errorMsg) throws ValidateException { if (false == isLetter(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -354,7 +462,7 @@ public static void validateLetter(String value, String errorMsg) throws Validate * @return 是否全部为大写字母 * @since 3.3.0 */ - public static boolean isUpperCase(String value) { + public static boolean isUpperCase(CharSequence value) { return StrUtil.isAllCharMatch(value, new cn.hutool.core.lang.Matcher() { @Override public boolean match(Character t) { @@ -366,15 +474,18 @@ public boolean match(Character t) { /** * 验证字符串是否全部为大写字母 * + * @param 字符串类型 * @param value 表单值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 * @since 3.3.0 */ - public static void validateUpperCase(String value, String errorMsg) throws ValidateException { + public static T validateUpperCase(T value, String errorMsg) throws ValidateException { if (false == isUpperCase(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -384,7 +495,7 @@ public static void validateUpperCase(String value, String errorMsg) throws Valid * @return 是否全部为小写字母 * @since 3.3.0 */ - public static boolean isLowerCase(String value) { + public static boolean isLowerCase(CharSequence value) { return StrUtil.isAllCharMatch(value, new cn.hutool.core.lang.Matcher() { @Override public boolean match(Character t) { @@ -396,15 +507,18 @@ public boolean match(Character t) { /** * 验证字符串是否全部为小写字母 * + * @param 字符串类型 * @param value 表单值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 * @since 3.3.0 */ - public static void validateLowerCase(String value, String errorMsg) throws ValidateException { + public static T validateLowerCase(T value, String errorMsg) throws ValidateException { if (false == isLowerCase(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -422,12 +536,14 @@ public static boolean isNumber(String value) { * * @param value 表单值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateNumber(String value, String errorMsg) throws ValidateException { + public static String validateNumber(String value, String errorMsg) throws ValidateException { if (false == isNumber(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -437,22 +553,25 @@ public static void validateNumber(String value, String errorMsg) throws Validate * @return 是否是字母(包括大写和小写字母) * @since 4.1.8 */ - public static boolean isWord(String value) { + public static boolean isWord(CharSequence value) { return isMactchRegex(PatternPool.WORD, value); } /** * 验证是否为字母(包括大写和小写字母) * + * @param 字符串类型 * @param value 表单值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 * @since 4.1.8 */ - public static void validateWord(String value, String errorMsg) throws ValidateException { + public static T validateWord(T value, String errorMsg) throws ValidateException { if (false == isWord(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -461,21 +580,25 @@ public static void validateWord(String value, String errorMsg) throws ValidateEx * @param value 值 * @return 是否为货币 */ - public static boolean isMoney(String value) { + public static boolean isMoney(CharSequence value) { return isMactchRegex(MONEY, value); } /** * 验证是否为货币 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateMoney(String value, String errorMsg) throws ValidateException { + public static T validateMoney(T value, String errorMsg) throws ValidateException { if (false == isMoney(value)) { throw new ValidateException(errorMsg); } + return value; + } /** @@ -484,21 +607,24 @@ public static void validateMoney(String value, String errorMsg) throws ValidateE * @param value 值 * @return 是否为邮政编码(中国) */ - public static boolean isZipCode(String value) { + public static boolean isZipCode(CharSequence value) { return isMactchRegex(ZIP_CODE, value); } /** * 验证是否为邮政编码(中国) * + * @param 字符串类型 * @param value 表单值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateZipCode(String value, String errorMsg) throws ValidateException { + public static T validateZipCode(T value, String errorMsg) throws ValidateException { if (false == isZipCode(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -507,21 +633,24 @@ public static void validateZipCode(String value, String errorMsg) throws Validat * @param value 值 * @return 否为可用邮箱地址 */ - public static boolean isEmail(String value) { + public static boolean isEmail(CharSequence value) { return isMactchRegex(EMAIL, value); } /** * 验证是否为可用邮箱地址 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateEmail(String value, String errorMsg) throws ValidateException { + public static T validateEmail(T value, String errorMsg) throws ValidateException { if (false == isEmail(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -530,21 +659,24 @@ public static void validateEmail(String value, String errorMsg) throws ValidateE * @param value 值 * @return 是否为手机号码(中国) */ - public static boolean isMobile(String value) { + public static boolean isMobile(CharSequence value) { return isMactchRegex(MOBILE, value); } /** * 验证是否为手机号码(中国) * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateMobile(String value, String errorMsg) throws ValidateException { + public static T validateMobile(T value, String errorMsg) throws ValidateException { if (false == isMobile(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -554,7 +686,7 @@ public static void validateMobile(String value, String errorMsg) throws Validate * @param value 值 * @return 是否为身份证号码(18位中国) */ - public static boolean isCitizenId(String value) { + public static boolean isCitizenId(CharSequence value) { return isMactchRegex(CITIZEN_ID, value); } @@ -562,14 +694,17 @@ public static boolean isCitizenId(String value) { * 验证是否为身份证号码(18位中国)
* 出生日期只支持到到2999年 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateCitizenIdNumber(String value, String errorMsg) throws ValidateException { + public static T validateCitizenIdNumber(T value, String errorMsg) throws ValidateException { if (false == isCitizenId(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -621,7 +756,7 @@ public static boolean isBirthday(int year, int month, int day) { * @param value 值 * @return 是否为生日 */ - public static boolean isBirthday(String value) { + public static boolean isBirthday(CharSequence value) { if (isMactchRegex(BIRTHDAY, value)) { Matcher matcher = BIRTHDAY.matcher(value); if (matcher.find()) { @@ -635,16 +770,19 @@ public static boolean isBirthday(String value) { } /** - * 验证验证是否为生日
+ * 验证验证是否为生日 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateBirthday(String value, String errorMsg) throws ValidateException { + public static T validateBirthday(T value, String errorMsg) throws ValidateException { if (false == isBirthday(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -653,21 +791,24 @@ public static void validateBirthday(String value, String errorMsg) throws Valida * @param value 值 * @return 是否为IPV4地址 */ - public static boolean isIpv4(String value) { + public static boolean isIpv4(CharSequence value) { return isMactchRegex(IPV4, value); } /** * 验证是否为IPV4地址 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateIpv4(String value, String errorMsg) throws ValidateException { + public static T validateIpv4(T value, String errorMsg) throws ValidateException { if (false == isIpv4(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -677,22 +818,25 @@ public static void validateIpv4(String value, String errorMsg) throws ValidateEx * @return 是否为MAC地址 * @since 4.1.3 */ - public static boolean isMac(String value) { + public static boolean isMac(CharSequence value) { return isMactchRegex(PatternPool.MAC_ADDRESS, value); } /** * 验证是否为MAC地址 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 * @since 4.1.3 */ - public static void validateMac(String value, String errorMsg) throws ValidateException { + public static T validateMac(T value, String errorMsg) throws ValidateException { if (false == isMac(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -702,22 +846,25 @@ public static void validateMac(String value, String errorMsg) throws ValidateExc * @return 是否为中国车牌号 * @since 3.0.6 */ - public static boolean isPlateNumber(String value) { + public static boolean isPlateNumber(CharSequence value) { return isMactchRegex(PLATE_NUMBER, value); } /** * 验证是否为中国车牌号 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 * @since 3.0.6 */ - public static void validatePlateNumber(String value, String errorMsg) throws ValidateException { + public static T validatePlateNumber(T value, String errorMsg) throws ValidateException { if (false == isPlateNumber(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -726,9 +873,9 @@ public static void validatePlateNumber(String value, String errorMsg) throws Val * @param value 值 * @return 是否为URL */ - public static boolean isUrl(String value) { + public static boolean isUrl(CharSequence value) { try { - new java.net.URL(value); + new java.net.URL(StrUtil.str(value)); } catch (MalformedURLException e) { return false; } @@ -738,14 +885,17 @@ public static boolean isUrl(String value) { /** * 验证是否为URL * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateUrl(String value, String errorMsg) throws ValidateException { + public static T validateUrl(T value, String errorMsg) throws ValidateException { if (false == isUrl(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -754,21 +904,24 @@ public static void validateUrl(String value, String errorMsg) throws ValidateExc * @param value 值 * @return 是否为汉字 */ - public static boolean isChinese(String value) { + public static boolean isChinese(CharSequence value) { return isMactchRegex("^" + ReUtil.RE_CHINESE + "+$", value); } /** * 验证是否为汉字 * + * @param 字符串类型 * @param value 表单值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateChinese(String value, String errorMsg) throws ValidateException { + public static T validateChinese(T value, String errorMsg) throws ValidateException { if (false == isChinese(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -777,21 +930,24 @@ public static void validateChinese(String value, String errorMsg) throws Validat * @param value 值 * @return 是否为中文字、英文字母、数字和下划线 */ - public static boolean isGeneralWithChinese(String value) { + public static boolean isGeneralWithChinese(CharSequence value) { return isMactchRegex(GENERAL_WITH_CHINESE, value); } /** * 验证是否为中文字、英文字母、数字和下划线 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateGeneralWithChinese(String value, String errorMsg) throws ValidateException { + public static T validateGeneralWithChinese(T value, String errorMsg) throws ValidateException { if (false == isGeneralWithChinese(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -801,7 +957,7 @@ public static void validateGeneralWithChinese(String value, String errorMsg) thr * @param value 值 * @return 是否为UUID */ - public static boolean isUUID(String value) { + public static boolean isUUID(CharSequence value) { return isMactchRegex(UUID, value) || isMactchRegex(UUID_SIMPLE, value); } @@ -809,14 +965,17 @@ public static boolean isUUID(String value) { * 验证是否为UUID
* 包括带横线标准格式和不带横线的简单模式 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 */ - public static void validateUUID(String value, String errorMsg) throws ValidateException { + public static T validateUUID(T value, String errorMsg) throws ValidateException { if (false == isUUID(value)) { throw new ValidateException(errorMsg); } + return value; } /** @@ -826,22 +985,25 @@ public static void validateUUID(String value, String errorMsg) throws ValidateEx * @return 是否为Hex(16进制)字符串 * @since 4.3.3 */ - public static boolean isHex(String value) { + public static boolean isHex(CharSequence value) { return isMactchRegex(PatternPool.HEX, value); } /** * 验证是否为Hex(16进制)字符串 * + * @param 字符串类型 * @param value 值 * @param errorMsg 验证错误的信息 + * @return 验证后的值 * @throws ValidateException 验证异常 * @since 4.3.3 */ - public static void validateHex(String value, String errorMsg) throws ValidateException { + public static T validateHex(T value, String errorMsg) throws ValidateException { if (false == isHex(value)) { throw new ValidateException(errorMsg); } + return value; } /** From 286e2405665f116b9ba4284c20278772e6241afc Mon Sep 17 00:00:00 2001 From: looly Date: Sat, 9 Feb 2019 12:36:06 +0000 Subject: [PATCH 4/7] fix getAnnotationValue --- CHANGELOG.md | 1 + .../main/java/cn/hutool/core/annotation/AnnotationUtil.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ca53b05ac..63c8e1321a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * 【core】 Validator中使用泛型 ### Bug修复 +* 【core】 修复AnnotationUtil.getAnnotationValue获取对象错误问题(issue#271@Github) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java index eb2c6b93a1..dc7b666cf9 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java @@ -93,11 +93,11 @@ public static T getAnnotationValue(AnnotatedElement annotationEle, Class Date: Sat, 9 Feb 2019 12:49:54 +0000 Subject: [PATCH 5/7] add test --- .../core/annotation/AnnotationForTest.java | 27 +++++++++++++++++++ .../core/annotation/AnnotationUtilTest.java | 18 +++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationForTest.java create mode 100644 hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationForTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationForTest.java new file mode 100644 index 0000000000..10d99596ab --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationForTest.java @@ -0,0 +1,27 @@ +package cn.hutool.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 用于单元测试的注解类
+ * 注解类相关说明见:https://www.cnblogs.com/xdp-gacl/p/3622275.html + * + * @author looly + * + */ +// Retention注解决定MyAnnotation注解的生命周期 +@Retention(RetentionPolicy.RUNTIME) +// Target注解决定MyAnnotation注解可以加在哪些成分上,如加在类身上,或者属性身上,或者方法身上等成分 +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface AnnotationForTest { + + /** + * 注解的默认属性值 + * + * @return + */ + String value(); +} diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java new file mode 100644 index 0000000000..64f3d63428 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java @@ -0,0 +1,18 @@ +package cn.hutool.core.annotation; + +import org.junit.Assert; +import org.junit.Test; + +public class AnnotationUtilTest { + + @Test + public void getAnnotationValueTest() { + Object value = AnnotationUtil.getAnnotationValue(ClassWithAnnotation.class, AnnotationForTest.class); + Assert.assertEquals("测试", value); + } + + @AnnotationForTest("测试") + class ClassWithAnnotation{ + + } +} From 9b07368ce54fbe9d68cddbc3f27be69e0d31fc51 Mon Sep 17 00:00:00 2001 From: looly Date: Tue, 12 Feb 2019 12:32:14 +0000 Subject: [PATCH 6/7] add SemaphoreRunnable --- CHANGELOG.md | 3 + .../java/cn/hutool/core/net/NioServer.java | 173 ------------------ .../hutool/core/thread/SemaphoreRunnable.java | 47 +++++ .../java/cn/hutool/core/util/NetUtil.java | 9 +- .../java/cn/hutool/core/util/NumberUtil.java | 37 +++- .../java/cn/hutool/core/util/XmlUtil.java | 68 ++++--- .../hutool/http/webservice/SoapRequest.java | 19 +- .../http/webservice/SoapRequestTest.java | 7 +- hutool-log/pom.xml | 2 +- 9 files changed, 160 insertions(+), 205 deletions(-) delete mode 100644 hutool-core/src/main/java/cn/hutool/core/net/NioServer.java create mode 100644 hutool-core/src/main/java/cn/hutool/core/thread/SemaphoreRunnable.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 63c8e1321a..2e468e953e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ### 新特性 * 【core】 增加StrFormater代码逻辑可读性(pr#269@Github) * 【core】 Validator中使用泛型 +* 【core】 NumberUtil增加toBytes和toInt方法 +* 【core】 XmlUtil增加format方法,支持缩进 +* 【http】 SoapRequest增加executeBody方法(issue#IRN6I@Gitee) ### Bug修复 * 【core】 修复AnnotationUtil.getAnnotationValue获取对象错误问题(issue#271@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/net/NioServer.java b/hutool-core/src/main/java/cn/hutool/core/net/NioServer.java deleted file mode 100644 index 0c31358549..0000000000 --- a/hutool-core/src/main/java/cn/hutool/core/net/NioServer.java +++ /dev/null @@ -1,173 +0,0 @@ -package cn.hutool.core.net; - -import java.io.Closeable; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.nio.channels.SelectableChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.util.Iterator; - -import cn.hutool.core.io.IORuntimeException; -import cn.hutool.core.io.IoUtil; - -/** - * 基于NIO的Socket服务端实现 - * - * @author looly - * - */ -public abstract class NioServer implements Closeable { - - private Selector selector; - private ServerSocketChannel serverSocketChannel; - - /** - * 构造 - * - * @param port 端口 - */ - public NioServer(int port) { - init(new InetSocketAddress(port)); - } - - /** - * 初始化 - * - * @param address 地址和端口 - * @return this - */ - public NioServer init(InetSocketAddress address) { - try { - // 打开服务器套接字通道 - this.serverSocketChannel = ServerSocketChannel.open(); - // 设置为非阻塞状态 - serverSocketChannel.configureBlocking(false); - // 获取通道相关联的套接字 - final ServerSocket serverSocket = serverSocketChannel.socket(); - // 绑定端口号 - serverSocket.bind(address); - - // 打开一个选择器 - selector = Selector.open(); - // 服务器套接字注册到Selector中 并指定Selector监控连接事件 - serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); - } catch (IOException e) { - throw new IORuntimeException(e); - } - - return this; - } - - /** - * 开始监听 - */ - public void listen() { - try { - doListen(); - } catch (IOException e) { - throw new IORuntimeException(e); - } - } - - /** - * 开始监听 - * - * @throws IOException IO异常 - */ - private void doListen() throws IOException { - while (0 != this.selector.select()) { - // 返回已选择键的集合 - final Iterator keyIter = selector.selectedKeys().iterator(); - while (keyIter.hasNext()) { - handle(keyIter.next()); - keyIter.remove(); - } - } - } - - /** - * 处理SelectionKey - * - * @param key SelectionKey - */ - private void handle(SelectionKey key) { - // 有客户端接入此服务端 - if (key.isAcceptable()) { - final ServerSocketChannel server = (ServerSocketChannel) key.channel();// 获取通道 转化为要处理的类型 - SocketChannel socketChannel; - try { - // 获取连接到此服务器的客户端通道 - socketChannel = server.accept(); - } catch (IOException e) { - throw new IORuntimeException(e); - } - - // SocketChannel通道的可读事件注册到Selector中 - registerChannel(selector, socketChannel, Operation.READ); - } - - // 读事件就绪 - if (key.isReadable()) { - final SocketChannel socketChannel = (SocketChannel) key.channel(); - read(socketChannel); - - // SocketChannel通道的可写事件注册到Selector中 - registerChannel(selector, socketChannel, Operation.WRITE); - } - - // 写事件就绪 - if (key.isWritable()) { - final SocketChannel socketChannel = (SocketChannel) key.channel(); - write(socketChannel); - // SocketChannel通道的可读事件注册到Selector中 - registerChannel(selector, socketChannel, Operation.READ); - } - } - - @Override - public void close() throws IOException { - IoUtil.close(this.selector); - IoUtil.close(this.serverSocketChannel); - } - - /** - * 处理读事件
- * 当收到读取准备就绪的信号后,回调此方法,用户可读取从客户端传世来的消息 - * - * @param socketChannel SocketChannel - */ - protected abstract void read(SocketChannel socketChannel); - - /** - * 实现写逻辑
- * 当收到写出准备就绪的信号后,回调此方法,用户可向客户端发送消息 - * - * @param socketChannel SocketChannel - */ - protected abstract void write(SocketChannel socketChannel); - - /** - * 注册通道到指定Selector上 - * - * @param selector Selector - * @param channel 通道 - * @param ops 注册的通道监听类型 - */ - private void registerChannel(Selector selector, SelectableChannel channel, Operation ops) { - if (channel == null) { - return; - } - - try { - channel.configureBlocking(false); - // 注册通道 - channel.register(selector, ops.getValue()); - } catch (IOException e) { - throw new IORuntimeException(e); - } - } -} diff --git a/hutool-core/src/main/java/cn/hutool/core/thread/SemaphoreRunnable.java b/hutool-core/src/main/java/cn/hutool/core/thread/SemaphoreRunnable.java new file mode 100644 index 0000000000..9cdcfc3043 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/thread/SemaphoreRunnable.java @@ -0,0 +1,47 @@ +package cn.hutool.core.thread; + +import java.util.concurrent.Semaphore; + +/** + * 带有信号量控制的{@link Runnable} 接口抽象实现 + * + *

+ * 通过设置信号量,可以限制可以访问某些资源(物理或逻辑的)线程数目。
+ * 例如:设置信号量为2,表示最多有两个线程可以同时执行方法逻辑,其余线程等待,直到此线程逻辑执行完毕 + *

+ * + * @author looly + * @since 4.4.5 + */ +public class SemaphoreRunnable implements Runnable { + + /** 实际执行的逻辑 */ + private Runnable runnable; + /** 信号量 */ + private Semaphore semaphore; + + /** + * 构造 + * + * @param runnable 实际执行的线程逻辑 + * @param semaphore 信号量,多个线程必须共享同一信号量 + */ + public SemaphoreRunnable(Runnable runnable, Semaphore semaphore) { + this.runnable = runnable; + this.semaphore = semaphore; + } + + @Override + public void run() { + if (null != this.semaphore) { + try { + semaphore.acquire(); + this.runnable.run(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } finally { + semaphore.release(); + } + } + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NetUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NetUtil.java index 63a5999066..fc56bffba9 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NetUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NetUtil.java @@ -375,16 +375,19 @@ public static String getMacAddress(InetAddress inetAddress, String separator) { } return null; } - + /** * 创建 {@link InetSocketAddress} * - * @param host 域名或IP地址 - * @param port 端口 + * @param host 域名或IP地址,空表示任意地址 + * @param port 端口,0表示系统分配临时端口 * @return {@link InetSocketAddress} * @since 3.3.0 */ public static InetSocketAddress createAddress(String host, int port) { + if(StrUtil.isBlank(host)) { + return new InetSocketAddress(port); + } return new InetSocketAddress(host, port); } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java index b1676a221e..45e11867e2 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -2171,7 +2171,7 @@ public static long parseLong(String number) { // 0x04表示16进制数 return Long.parseLong(number.substring(2), 16); } - + return Long.parseLong(removeNumberFlag(number)); } @@ -2191,6 +2191,40 @@ public static Number parseNumber(String numberStr) { } } + /** + * int值转byte数组,使用大端字节序(高位字节在前,低位字节在后)
+ * 见:http://www.ruanyifeng.com/blog/2016/11/byte-order.html + * + * @param value 值 + * @return byte数组 + * @since 4.4.5 + */ + public static byte[] toBytes(int value) { + final byte[] result = new byte[4]; + + result[0] = (byte) (value >> 24); + result[1] = (byte) (value >> 16); + result[2] = (byte) (value >> 8); + result[3] = (byte) (value /* >> 0 */); + + return result; + } + + /** + * byte数组转int,使用大端字节序(高位字节在前,低位字节在后)
+ * 见:http://www.ruanyifeng.com/blog/2016/11/byte-order.html + * + * @param bytes + * @return int + * @since 4.4.5 + */ + public static int toInt(byte[] bytes) { + return (bytes[0] & 0xff) << 24// + | (bytes[1] & 0xff) << 16// + | (bytes[2] & 0xff) << 8// + | (bytes[3] & 0xff); + } + // ------------------------------------------------------------------------------------------- Private method start private static int mathSubnode(int selectNum, int minNum) { if (selectNum == minNum) { @@ -2210,6 +2244,7 @@ private static int mathNode(int selectNum) { /** * 去掉数字尾部的数字标识,例如12D,44.0F,22L中的最后一个字母 + * * @param number 数字字符串 * @return 去掉标识的字符串 */ diff --git a/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java index 012dffe5d4..3b248e3132 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java @@ -10,7 +10,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; -import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; @@ -57,6 +56,8 @@ public class XmlUtil { /** 在XML中无效的字符 正则 */ public final static String INVALID_REGEX = "[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]"; + /** XML格式化输出默认缩进量 */ + public final static int INDENT_DEFAULT = 2; // -------------------------------------------------------------------------------------- Read /** @@ -211,13 +212,14 @@ public static T readObjectFromXml(InputSource source) throws IOException { // -------------------------------------------------------------------------------------- Write /** * 将XML文档转换为String
- * 字符编码使用XML文档中的编码,获取不到则使用UTF-8 + * 字符编码使用XML文档中的编码,获取不到则使用UTF-8
+ * 默认非格式化输出,若想格式化请使用{@link #format(Document)} * * @param doc XML文档 * @return XML字符串 */ public static String toStr(Document doc) { - return toStr(doc, true); + return toStr(doc, false); } /** @@ -230,13 +232,7 @@ public static String toStr(Document doc) { * @since 3.0.9 */ public static String toStr(Document doc, boolean isPretty) { - final StringWriter writer = StrUtil.getWriter(); - try { - write(doc, writer, isPretty); - } catch (Exception e) { - throw new UtilException(e, "Trans xml document to string error!"); - } - return writer.toString(); + return toStr(doc, null, isPretty); } /** @@ -252,13 +248,35 @@ public static String toStr(Document doc, boolean isPretty) { public static String toStr(Document doc, String charset, boolean isPretty) { final ByteArrayOutputStream out = new ByteArrayOutputStream(); try { - write(doc, out, charset, isPretty); + write(doc, out, charset, isPretty ? INDENT_DEFAULT : 0); } catch (Exception e) { throw new UtilException(e, "Trans xml document to string error!"); } return out.toString(); } + /** + * 格式化XML输出 + * + * @param doc {@link Document} XML文档 + * @return 格式化后的XML字符串 + * @since 4.4.5 + */ + public static String format(Document doc) { + return toStr(doc, true); + } + + /** + * 格式化XML输出 + * + * @param xmlStr XML字符串 + * @return 格式化后的XML字符串 + * @since 4.4.5 + */ + public static String format(String xmlStr) { + return format(parseXml(xmlStr)); + } + /** * 将XML文档写入到文件
* 使用Document中的编码 @@ -288,7 +306,7 @@ public static void toFile(Document doc, String path, String charset) { BufferedWriter writer = null; try { writer = FileUtil.getWriter(path, charset, false); - write(doc, writer, true); + write(doc, writer, INDENT_DEFAULT); } finally { IoUtil.close(writer); } @@ -299,11 +317,11 @@ public static void toFile(Document doc, String path, String charset) { * * @param node {@link Node} XML文档节点或文档本身 * @param writer 写出的Writer,Writer决定了输出XML的编码 - * @param isPretty 是否格式化输出 + * @param indent 格式化输出中缩进量,小于1表示不格式化输出 * @since 3.0.9 */ - public static void write(Node node, Writer writer, boolean isPretty) { - transform(new DOMSource(node), new StreamResult(writer), null, isPretty); + public static void write(Node node, Writer writer, int indent) { + transform(new DOMSource(node), new StreamResult(writer), null, indent); } /** @@ -312,27 +330,31 @@ public static void write(Node node, Writer writer, boolean isPretty) { * @param node {@link Node} XML文档节点或文档本身 * @param out 写出的Writer,Writer决定了输出XML的编码 * @param charset 编码 - * @param isPretty 是否格式化输出 + * @param indent 格式化输出中缩进量,小于1表示不格式化输出 * @since 4.0.8 */ - public static void write(Node node, OutputStream out, String charset, boolean isPretty) { - transform(new DOMSource(node), new StreamResult(out), charset, isPretty); + public static void write(Node node, OutputStream out, String charset, int indent) { + transform(new DOMSource(node), new StreamResult(out), charset, indent); } /** - * 将XML文档写出 + * 将XML文档写出
+ * 格式化输出逻辑参考:https://stackoverflow.com/questions/139076/how-to-pretty-print-xml-from-java * * @param source 源 * @param result 目标 * @param charset 编码 - * @param isPretty 是否格式化输出 + * @param indent 格式化输出中缩进量,小于1表示不格式化输出 * @since 4.0.9 */ - public static void transform(Source source, Result result, String charset, boolean isPretty) { + public static void transform(Source source, Result result, String charset, int indent) { final TransformerFactory factory = TransformerFactory.newInstance(); try { final Transformer xformer = factory.newTransformer(); - xformer.setOutputProperty(OutputKeys.INDENT, isPretty ? "yes" : "no"); + if(indent > 0) { + xformer.setOutputProperty(OutputKeys.INDENT, "yes"); + xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent)); + } if (StrUtil.isNotBlank(charset)) { xformer.setOutputProperty(OutputKeys.ENCODING, charset); } @@ -780,7 +802,7 @@ private static void mapToXml(Document doc, Element element, Map data) { // value作为标签内的值。 if (null != value) { if (value instanceof Map) { - //如果值依旧为map,递归继续 + // 如果值依旧为map,递归继续 mapToXml(doc, filedEle, (Map) value); element.appendChild(filedEle); } else { diff --git a/hutool-http/src/main/java/cn/hutool/http/webservice/SoapRequest.java b/hutool-http/src/main/java/cn/hutool/http/webservice/SoapRequest.java index 728cc31445..cae7ea267b 100644 --- a/hutool-http/src/main/java/cn/hutool/http/webservice/SoapRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/webservice/SoapRequest.java @@ -3,9 +3,11 @@ import java.nio.charset.Charset; import java.util.LinkedHashMap; import java.util.Map; +import java.util.regex.Pattern; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; @@ -17,7 +19,12 @@ */ public class SoapRequest { + /** 默认的xmlns */ + public static final String XMLNS_SOAPENV = "soapenv"; + private static final String TEXT_XML_CONTENT_TYPE = "text/xml;charset="; + /** 返回值中soap:Body标签内的内容正则 */ + private static final Pattern SOAP_BODY_PATTERN = Pattern.compile("(.*?)", Pattern.DOTALL); /** 编码 */ private Charset charset = CharsetUtil.CHARSET_UTF_8; @@ -26,7 +33,7 @@ public class SoapRequest { /** 方法的命名空间 */ private String methodNamespace; /** 命名空间envelope(ns) */ - private String xmlns = "soapenv"; + private String xmlns = XMLNS_SOAPENV; /** 请求方法 */ private String method; /** 请求参数 */ @@ -74,7 +81,7 @@ public SoapRequest setMethodNamespace(String namespace) { } /** - * 设置命名空间envelope(ns) + * 设置命名空间envelope(ns),默认是 * * @return this */ @@ -127,6 +134,14 @@ public String execute() { return HttpRequest.post(this.url).body(toSoapXml()).contentType(getXmlContentType()).execute().body(); } + /** + * 执行Webservice请求,既发送SOAP内容 + * @return 返回结果 + */ + public String executeBody() { + return ReUtil.getGroup1(SOAP_BODY_PATTERN, execute()); + } + //------------------------------------------------------------------------------------------------------------------------- Private method start /** * 生成SOAP请求的XML文本 diff --git a/hutool-http/src/test/java/cn/hutool/http/webservice/SoapRequestTest.java b/hutool-http/src/test/java/cn/hutool/http/webservice/SoapRequestTest.java index c652f51787..4917dbed41 100644 --- a/hutool-http/src/test/java/cn/hutool/http/webservice/SoapRequestTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/webservice/SoapRequestTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import cn.hutool.core.lang.Console; +import cn.hutool.core.util.XmlUtil; /** * SOAP相关单元测试 @@ -23,7 +24,9 @@ public void requestTest() { request.setXmlns("soapenv"); request.setMethod("getCountryCityByIp"); request.addParam("theIpAddress", "218.21.240.106"); - - Console.log(request.execute()); + + String body = request.executeBody(); + Console.log(body); + Console.log(XmlUtil.format(body)); } } diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index cbbbe8aa97..a7c8bac921 100644 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -21,7 +21,7 @@ 1.7.25 1.2.3 1.2.17 - 2.11.1 + 2.11.2 1.2 1.3.5 3.3.2.Final From 62742d40d1e599ee32dbd73ea537d448911e6afe Mon Sep 17 00:00:00 2001 From: looly Date: Tue, 12 Feb 2019 12:36:56 +0000 Subject: [PATCH 7/7] release 4.4.5 --- hutool-all/pom.xml | 2 +- hutool-aop/pom.xml | 2 +- hutool-bloomFilter/pom.xml | 2 +- hutool-cache/pom.xml | 2 +- hutool-captcha/pom.xml | 2 +- hutool-core/pom.xml | 2 +- hutool-cron/pom.xml | 2 +- hutool-crypto/pom.xml | 2 +- hutool-db/pom.xml | 2 +- hutool-dfa/pom.xml | 2 +- hutool-extra/pom.xml | 2 +- hutool-http/pom.xml | 2 +- hutool-json/pom.xml | 2 +- hutool-log/pom.xml | 2 +- hutool-poi/pom.xml | 2 +- hutool-script/pom.xml | 2 +- hutool-setting/pom.xml | 2 +- hutool-system/pom.xml | 2 +- pom.xml | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/hutool-all/pom.xml b/hutool-all/pom.xml index 59c375a8bc..a86f9cf4d3 100644 --- a/hutool-all/pom.xml +++ b/hutool-all/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-all diff --git a/hutool-aop/pom.xml b/hutool-aop/pom.xml index c273e116fd..f9b73e4c7e 100644 --- a/hutool-aop/pom.xml +++ b/hutool-aop/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-aop diff --git a/hutool-bloomFilter/pom.xml b/hutool-bloomFilter/pom.xml index 639448bbb4..4e2f9fa1b9 100644 --- a/hutool-bloomFilter/pom.xml +++ b/hutool-bloomFilter/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-bloomFilter diff --git a/hutool-cache/pom.xml b/hutool-cache/pom.xml index de492088ba..c2386b2c19 100644 --- a/hutool-cache/pom.xml +++ b/hutool-cache/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-cache diff --git a/hutool-captcha/pom.xml b/hutool-captcha/pom.xml index a67499ffbc..6a70a383ca 100644 --- a/hutool-captcha/pom.xml +++ b/hutool-captcha/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-captcha diff --git a/hutool-core/pom.xml b/hutool-core/pom.xml index 5ffd77a05e..9c414db63d 100644 --- a/hutool-core/pom.xml +++ b/hutool-core/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-core diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml index 4d574159db..68c2cbcfe2 100644 --- a/hutool-cron/pom.xml +++ b/hutool-cron/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-cron diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml index 8b3284c015..49bc38018d 100644 --- a/hutool-crypto/pom.xml +++ b/hutool-crypto/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-crypto diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index 526c153e8d..eb5ce7ef9c 100644 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-db diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml index 13b5c55394..53fe3ee544 100644 --- a/hutool-dfa/pom.xml +++ b/hutool-dfa/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-dfa diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index 0155a35387..6e6e3c9312 100644 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-extra diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml index 53d3178b86..cadf2948ff 100644 --- a/hutool-http/pom.xml +++ b/hutool-http/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-http diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml index 727a3b4d85..74aaa17b28 100644 --- a/hutool-json/pom.xml +++ b/hutool-json/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-json diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index a7c8bac921..278fcf1c1e 100644 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -9,7 +9,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-log diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 91967c1236..6f05ba2bef 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-poi diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml index d8d18ba67a..bf50b4bf32 100644 --- a/hutool-script/pom.xml +++ b/hutool-script/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-script diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml index 94925e1709..e6b4d71c43 100644 --- a/hutool-setting/pom.xml +++ b/hutool-setting/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-setting diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml index 2adbdb3305..b1556768fe 100644 --- a/hutool-system/pom.xml +++ b/hutool-system/pom.xml @@ -7,7 +7,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool-system diff --git a/pom.xml b/pom.xml index 26c881ac2c..2a7b1e6998 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ cn.hutool hutool-parent - 4.4.5-SNAPSHOT + 4.4.5 hutool 提供丰富的Java工具方法 https://github.com/looly/hutool