From a4515e218b0a69ead4547eec8f842a5c5b5051e4 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 5 Oct 2019 18:18:57 +0800 Subject: [PATCH] add parseCST and fix cookie bug --- CHANGELOG.md | 6 +- .../java/cn/hutool/core/date/DateTime.java | 1 + .../java/cn/hutool/core/date/DateUtil.java | 25 ++++++++- .../{ClassScaner.java => ClassScanner.java} | 14 ++--- .../core/thread/NamedThreadFactory.java | 24 ++++---- .../cn/hutool/core/thread/ThreadUtil.java | 30 +++++----- .../java/cn/hutool/core/util/ClassUtil.java | 20 +++---- .../java/cn/hutool/core/util/StrUtil.java | 14 ++--- .../java/cn/hutool/core/util/URLUtil.java | 14 +++++ .../cn/hutool/core/date/DateUtilTest.java | 11 ++++ .../cn/hutool/core/lang/ClassScanerTest.java | 2 +- .../java/cn/hutool/core/util/URLUtilTest.java | 15 ++++- .../main/java/cn/hutool/cron/CronUtil.java | 6 +- .../main/java/cn/hutool/cron/Scheduler.java | 8 +-- .../main/java/cn/hutool/crypto/KeyUtil.java | 22 +++++--- .../main/java/cn/hutool/http/HttpBase.java | 4 +- .../main/java/cn/hutool/http/HttpRequest.java | 56 ++++++++----------- .../java/cn/hutool/http/HttpResponse.java | 9 +-- .../http/cookie/GlobalCookieManager.java | 28 +++++++++- .../cn/hutool/http/test/HttpRequestTest.java | 9 +++ 20 files changed, 198 insertions(+), 120 deletions(-) rename hutool-core/src/main/java/cn/hutool/core/lang/{ClassScaner.java => ClassScanner.java} (92%) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe8eb0442..265ce3088 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,14 @@ ### 新特性 * 【all】 修复注释中的错别字(issue#I12XE6@Gitee) * 【core】 CsvWriter支持其它类型的参数(issue#I12XE3@Gitee) -* 【core】 ClassScaner支持自定义ClassLoader +* 【core】 ClassScanner支持自定义ClassLoader +* 【core】 修改错别字(pr#568@Github) +* 【core】 增加DateUtil.parseCST方法(issue#570@Github) ### Bug修复 * 【all】 修复阶乘计算错误bug(issue#I12XE4@Gitee) +* 【http】 修复disableCookie无效问题(issue#572@Github) +* 【http】 修复HttpResponse.getCookies导致的问题(issue#572@Github) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java b/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java index 83922c695..b4f9dac56 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java @@ -140,6 +140,7 @@ public class DateTime extends Date { */ public DateTime(Calendar calendar) { this(calendar.getTime(), calendar.getTimeZone()); + this.setFirstDayOfWeek(Week.of(calendar.getFirstDayOfWeek())); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java index 3f163046f..d6b64cfe8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java @@ -757,6 +757,24 @@ public class DateUtil { throw new DateException("No format fit for date String [{}] !", utcString); } + /** + * 解析CST时间,格式:
+ *
    + *
  1. EEE MMM dd HH:mm:ss z yyyy(例如:Wed Aug 01 00:00:00 CST 2012)
  2. + *
+ * + * @param cstString UTC时间 + * @return 日期对象 + * @since 4.6.9 + */ + public static DateTime parseCST(String cstString) { + if (cstString == null) { + return null; + } + + return parse(cstString, DatePattern.JDK_DATETIME_FORMAT); + } + /** * 将日期字符串转换为{@link DateTime}对象,格式:
*
    @@ -808,8 +826,11 @@ public class DateUtil { // HH:mm:ss 或者 HH:mm 时间格式匹配单独解析 return parseTimeToday(dateStr); } else if (StrUtil.containsAnyIgnoreCase(dateStr, wtb)) { - // JDK的Date对象toString默认格式,类似于:Tue Jun 4 16:25:15 +0800 2019 或 Thu May 16 17:57:18 GMT+08:00 2019 - return parse(dateStr, DatePattern.JDK_DATETIME_FORMAT); + // JDK的Date对象toString默认格式,类似于: + // Tue Jun 4 16:25:15 +0800 2019 + // Thu May 16 17:57:18 GMT+08:00 2019 + // Wed Aug 01 00:00:00 CST 2012 + return parseCST(dateStr); } else if (StrUtil.contains(dateStr, 'T')) { // UTC时间 return parseUTC(dateStr); diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/ClassScaner.java b/hutool-core/src/main/java/cn/hutool/core/lang/ClassScanner.java similarity index 92% rename from hutool-core/src/main/java/cn/hutool/core/lang/ClassScaner.java rename to hutool-core/src/main/java/cn/hutool/core/lang/ClassScanner.java index e868b1995..533436a62 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/ClassScaner.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/ClassScanner.java @@ -23,9 +23,9 @@ import java.util.jar.JarFile; * 类扫描器 * * @author looly - * @since 4.1.5 + * @since 4.6.9 */ -public class ClassScaner implements Serializable { +public class ClassScanner implements Serializable { private static final long serialVersionUID = 1L; /** @@ -124,13 +124,13 @@ public class ClassScaner implements Serializable { * @return 类集合 */ public static Set> scanPackage(String packageName, Filter> classFilter) { - return new ClassScaner(packageName, classFilter).scan(); + return new ClassScanner(packageName, classFilter).scan(); } /** * 构造,默认UTF-8编码 */ - public ClassScaner() { + public ClassScanner() { this(null); } @@ -139,7 +139,7 @@ public class ClassScaner implements Serializable { * * @param packageName 包名,所有包传入""或者null */ - public ClassScaner(String packageName) { + public ClassScanner(String packageName) { this(packageName, null); } @@ -149,7 +149,7 @@ public class ClassScaner implements Serializable { * @param packageName 包名,所有包传入""或者null * @param classFilter 过滤器,无需传入null */ - public ClassScaner(String packageName, Filter> classFilter) { + public ClassScanner(String packageName, Filter> classFilter) { this(packageName, classFilter, CharsetUtil.CHARSET_UTF_8); } @@ -160,7 +160,7 @@ public class ClassScaner implements Serializable { * @param classFilter 过滤器,无需传入null * @param charset 编码 */ - public ClassScaner(String packageName, Filter> classFilter, Charset charset) { + public ClassScanner(String packageName, Filter> classFilter, Charset charset) { packageName = StrUtil.nullToEmpty(packageName); this.packageName = packageName; this.packageNameWithDot = StrUtil.addSuffixIfNot(packageName, StrUtil.DOT); diff --git a/hutool-core/src/main/java/cn/hutool/core/thread/NamedThreadFactory.java b/hutool-core/src/main/java/cn/hutool/core/thread/NamedThreadFactory.java index ccc12a495..da768ae7d 100644 --- a/hutool-core/src/main/java/cn/hutool/core/thread/NamedThreadFactory.java +++ b/hutool-core/src/main/java/cn/hutool/core/thread/NamedThreadFactory.java @@ -26,7 +26,7 @@ public class NamedThreadFactory implements ThreadFactory { /** 线程组 */ private final AtomicInteger threadNumber = new AtomicInteger(1); /** 是否守护线程 */ - private final boolean isDeamon; + private final boolean isDaemon; /** 无法捕获的异常统一处理 */ private final UncaughtExceptionHandler handler; @@ -34,10 +34,10 @@ public class NamedThreadFactory implements ThreadFactory { * 构造 * * @param prefix 线程名前缀 - * @param isDeamon 是否守护线程 + * @param isDaemon 是否守护线程 */ - public NamedThreadFactory(String prefix, boolean isDeamon) { - this(prefix, null, isDeamon); + public NamedThreadFactory(String prefix, boolean isDaemon) { + this(prefix, null, isDaemon); } /** @@ -45,10 +45,10 @@ public class NamedThreadFactory implements ThreadFactory { * * @param prefix 线程名前缀 * @param threadGroup 线程组,可以为null - * @param isDeamon 是否守护线程 + * @param isDaemon 是否守护线程 */ - public NamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDeamon) { - this(prefix, threadGroup, isDeamon, null); + public NamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon) { + this(prefix, threadGroup, isDaemon, null); } /** @@ -56,16 +56,16 @@ public class NamedThreadFactory implements ThreadFactory { * * @param prefix 线程名前缀 * @param threadGroup 线程组,可以为null - * @param isDeamon 是否守护线程 + * @param isDaemon 是否守护线程 * @param handler 未捕获异常处理 */ - public NamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDeamon, UncaughtExceptionHandler handler) { + public NamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon, UncaughtExceptionHandler handler) { this.prefix = StrUtil.isBlank(prefix) ? "Hutool" : prefix; if (null == threadGroup) { threadGroup = ThreadUtil.currentThreadGroup(); } this.group = threadGroup; - this.isDeamon = isDeamon; + this.isDaemon = isDaemon; this.handler = handler; } @@ -75,11 +75,11 @@ public class NamedThreadFactory implements ThreadFactory { //守护线程 if (false == t.isDaemon()) { - if (isDeamon) { + if (isDaemon) { // 原线程为非守护则设置为守护 t.setDaemon(true); } - } else if (false == isDeamon) { + } else if (false == isDaemon) { // 原线程为守护则还原为非守护 t.setDaemon(false); } diff --git a/hutool-core/src/main/java/cn/hutool/core/thread/ThreadUtil.java b/hutool-core/src/main/java/cn/hutool/core/thread/ThreadUtil.java index 28f01e5ea..7e5f2dc4c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/thread/ThreadUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/thread/ThreadUtil.java @@ -98,17 +98,17 @@ public class ThreadUtil { * 执行异步方法 * * @param runnable 需要执行的方法体 - * @param isDeamon 是否守护线程。守护线程会在主线程结束后自动结束 + * @param isDaemon 是否守护线程。守护线程会在主线程结束后自动结束 * @return 执行的方法体 */ - public static Runnable excAsync(final Runnable runnable, boolean isDeamon) { + public static Runnable excAsync(final Runnable runnable, boolean isDaemon) { Thread thread = new Thread() { @Override public void run() { runnable.run(); } }; - thread.setDaemon(isDeamon); + thread.setDaemon(isDaemon); thread.start(); return runnable; @@ -192,13 +192,13 @@ public class ThreadUtil { * * @param runnable {@link Runnable} * @param name 线程名 - * @param isDeamon 是否守护线程 + * @param isDaemon 是否守护线程 * @return {@link Thread} * @since 4.1.2 */ - public static Thread newThread(Runnable runnable, String name, boolean isDeamon) { + public static Thread newThread(Runnable runnable, String name, boolean isDaemon) { final Thread t = new Thread(null, runnable, name); - t.setDaemon(isDeamon); + t.setDaemon(isDaemon); return t; } @@ -396,11 +396,11 @@ public class ThreadUtil { * 创建线程工厂 * * @param prefix 线程名前缀 - * @param isDeamon 是否守护线程 + * @param isDaemon 是否守护线程 * @since 4.0.0 */ - public static ThreadFactory newNamedThreadFactory(String prefix, boolean isDeamon) { - return new NamedThreadFactory(prefix, isDeamon); + public static ThreadFactory newNamedThreadFactory(String prefix, boolean isDaemon) { + return new NamedThreadFactory(prefix, isDaemon); } /** @@ -408,11 +408,11 @@ public class ThreadUtil { * * @param prefix 线程名前缀 * @param threadGroup 线程组,可以为null - * @param isDeamon 是否守护线程 + * @param isDaemon 是否守护线程 * @since 4.0.0 */ - public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDeamon) { - return new NamedThreadFactory(prefix, threadGroup, isDeamon); + public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon) { + return new NamedThreadFactory(prefix, threadGroup, isDaemon); } /** @@ -420,12 +420,12 @@ public class ThreadUtil { * * @param prefix 线程名前缀 * @param threadGroup 线程组,可以为null - * @param isDeamon 是否守护线程 + * @param isDaemon 是否守护线程 * @param handler 未捕获异常处理 * @since 4.0.0 */ - public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDeamon, UncaughtExceptionHandler handler) { - return new NamedThreadFactory(prefix, threadGroup, isDeamon, handler); + public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon, UncaughtExceptionHandler handler) { + return new NamedThreadFactory(prefix, threadGroup, isDaemon, handler); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java index 5e9a5d14b..44c586614 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java @@ -21,7 +21,7 @@ import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.lang.Assert; -import cn.hutool.core.lang.ClassScaner; +import cn.hutool.core.lang.ClassScanner; import cn.hutool.core.lang.Filter; import cn.hutool.core.lang.Singleton; @@ -176,10 +176,10 @@ public class ClassUtil { * @param packageName 包路径 * @param annotationClass 注解类 * @return 类集合 - * @see ClassScaner#scanPackageByAnnotation(String, Class) + * @see ClassScanner#scanPackageByAnnotation(String, Class) */ public static Set> scanPackageByAnnotation(String packageName, final Class annotationClass) { - return ClassScaner.scanPackageByAnnotation(packageName, annotationClass); + return ClassScanner.scanPackageByAnnotation(packageName, annotationClass); } /** @@ -188,20 +188,20 @@ public class ClassUtil { * @param packageName 包路径 * @param superClass 父类或接口 * @return 类集合 - * @see ClassScaner#scanPackageBySuper(String, Class) + * @see ClassScanner#scanPackageBySuper(String, Class) */ public static Set> scanPackageBySuper(String packageName, final Class superClass) { - return ClassScaner.scanPackageBySuper(packageName, superClass); + return ClassScanner.scanPackageBySuper(packageName, superClass); } /** * 扫面该包路径下所有class文件 * * @return 类集合 - * @see ClassScaner#scanPackage() + * @see ClassScanner#scanPackage() */ public static Set> scanPackage() { - return ClassScaner.scanPackage(); + return ClassScanner.scanPackage(); } /** @@ -209,10 +209,10 @@ public class ClassUtil { * * @param packageName 包路径 com | com. | com.abs | com.abs. * @return 类集合 - * @see ClassScaner#scanPackage(String) + * @see ClassScanner#scanPackage(String) */ public static Set> scanPackage(String packageName) { - return ClassScaner.scanPackage(packageName); + return ClassScanner.scanPackage(packageName); } /** @@ -225,7 +225,7 @@ public class ClassUtil { * @return 类集合 */ public static Set> scanPackage(String packageName, Filter> classFilter) { - return ClassScaner.scanPackage(packageName, classFilter); + return ClassScanner.scanPackage(packageName, classFilter); } // ----------------------------------------------------------------------------------------- Method diff --git a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java index d0d192b2f..f4ea3e6ab 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java @@ -585,10 +585,7 @@ public class StrUtil { */ public static boolean startWith(CharSequence str, CharSequence prefix, boolean isIgnoreCase) { if (null == str || null == prefix) { - if (null == str && null == prefix) { - return true; - } - return false; + return null == str && null == prefix; } if (isIgnoreCase) { @@ -664,10 +661,7 @@ public class StrUtil { */ public static boolean endWith(CharSequence str, CharSequence suffix, boolean isIgnoreCase) { if (null == str || null == suffix) { - if (null == str && null == suffix) { - return true; - } - return false; + return null == str && null == suffix; } if (isIgnoreCase) { @@ -3831,7 +3825,7 @@ public class StrUtil { } int preIndex = fromIndex; - int index = fromIndex; + int index; while ((index = indexOf(str, searchStr, preIndex, ignoreCase)) > -1) { result.append(str.subSequence(preIndex, index)); result.append(replacement); @@ -3985,7 +3979,7 @@ public class StrUtil { * * @param str1 字符串1 * @param str2 字符串2 - * @param scale + * @param scale 相似度 * @return 相似度百分比 * @since 3.2.3 */ diff --git a/hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java index e9c35797f..1b4ff0a6a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/URLUtil.java @@ -213,6 +213,20 @@ public class URLUtil { return urls; } + /** + * 获取URL中域名部分 + * + * @param url URL + * @return 域名的URI + * @since 4.6.9 + */ + public static URI getHost(URL url){ + if(null == url){ + return null; + } + return toURI(url.getHost()); + } + /** * 补全相对路径 * diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java index f3be73ca9..e4d99ead2 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java @@ -2,6 +2,7 @@ package cn.hutool.core.date; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.BetweenFormater.Level; +import cn.hutool.core.lang.Console; import org.junit.Assert; import org.junit.Test; @@ -472,6 +473,16 @@ public class DateUtilTest { Assert.assertEquals("2018-09-13 13:34:39.999", dateStr); } + @Test + public void parseCSTTest(){ + String dateStr = "Wed Sep 16 11:26:23 CST 2009"; + DateTime dateTime = DateUtil.parseCST(dateStr); + Assert.assertEquals("2009-09-17 01:26:23", dateTime.toString()); + + dateTime = DateUtil.parse(dateStr); + Assert.assertEquals("2009-09-17 01:26:23", dateTime.toString()); + } + @Test public void parseJDkTest() { String dateStr = "Thu May 16 17:57:18 GMT+08:00 2019"; diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/ClassScanerTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/ClassScanerTest.java index 5aeb1c633..c48991320 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/ClassScanerTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/ClassScanerTest.java @@ -10,7 +10,7 @@ public class ClassScanerTest { @Test @Ignore public void scanTest() { - ClassScaner scaner = new ClassScaner("cn.hutool.core.util", null); + ClassScanner scaner = new ClassScanner("cn.hutool.core.util", null); Set> set = scaner.scan(); for (Class clazz : set) { Console.log(clazz.getName()); diff --git a/hutool-core/src/test/java/cn/hutool/core/util/URLUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/URLUtilTest.java index f735fb384..69d202395 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/URLUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/URLUtilTest.java @@ -1,8 +1,13 @@ package cn.hutool.core.util; +import cn.hutool.core.lang.Console; import org.junit.Assert; import org.junit.Test; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; + /** * URLUtil单元测试 * @@ -54,7 +59,15 @@ public class URLUtilTest { String normalize = URLUtil.normalize(url); Assert.assertEquals("http://www.hutool.cn/aaa/bbb?a=1&b=2", normalize); } - + + @Test + public void getHostTest() throws MalformedURLException { + String url = "//www.hutool.cn//aaa/\\bbb?a=1&b=2"; + String normalize = URLUtil.normalize(url); + URI host = URLUtil.getHost(new URL(normalize)); + Assert.assertEquals("www.hutool.cn", host.toString()); + } + @Test public void encodeTest() { String body = "366466 - 副本.jpg"; diff --git a/hutool-cron/src/main/java/cn/hutool/cron/CronUtil.java b/hutool-cron/src/main/java/cn/hutool/cron/CronUtil.java index 61278a446..4b7414ec3 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/CronUtil.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/CronUtil.java @@ -145,9 +145,9 @@ public class CronUtil { /** * 开始 * - * @param isDeamon 是否以守护线程方式启动,如果为true,则在调用{@link #stop()}方法后执行的定时任务立即结束,否则等待执行完毕才结束。 + * @param isDaemon 是否以守护线程方式启动,如果为true,则在调用{@link #stop()}方法后执行的定时任务立即结束,否则等待执行完毕才结束。 */ - synchronized public static void start(boolean isDeamon) { + synchronized public static void start(boolean isDaemon) { if (scheduler.isStarted()) { throw new UtilException("Scheduler has been started, please stop it first!"); } @@ -167,7 +167,7 @@ public class CronUtil { } schedule(crontabSetting); - scheduler.start(isDeamon); + scheduler.start(isDaemon); } /** diff --git a/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java b/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java index 394a4e989..bbdc70826 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/Scheduler.java @@ -126,7 +126,7 @@ public class Scheduler implements Serializable { * * @return 是否为守护线程 */ - public boolean isDeamon() { + public boolean isDaemon() { return this.daemon; } @@ -362,11 +362,11 @@ public class Scheduler implements Serializable { /** * 启动 * - * @param isDeamon 是否以守护线程方式启动,如果为true,则在调用{@link #stop()}方法后执行的定时任务立即结束,否则等待执行完毕才结束。 + * @param isDaemon 是否以守护线程方式启动,如果为true,则在调用{@link #stop()}方法后执行的定时任务立即结束,否则等待执行完毕才结束。 * @return this */ - public Scheduler start(boolean isDeamon) { - this.daemon = isDeamon; + public Scheduler start(boolean isDaemon) { + this.daemon = isDaemon; return start(); } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java index ce3dc2c45..8dbf2fd89 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java @@ -50,8 +50,12 @@ import cn.hutool.crypto.symmetric.SymmetricAlgorithm; public class KeyUtil { /** Java密钥库(Java Key Store,JKS)KEY_STORE */ - public static final String KEY_STORE = "JKS"; - public static final String X509 = "X.509"; + public static final String KEY_TYPE_JKS = "JKS"; + /** jceks */ + public static final String KEY_TYPE_JCEKS = "jceks"; + /** PKCS12是公钥加密标准,它规定了可包含所有私钥、公钥和证书。其以二进制格式存储,也称为 PFX 文件 */ + public static final String KEY_TYPE_PKCS12 = "pkcs12"; + public static final String KEY_TYPE_X509 = "X.509"; /** * 默认密钥字节数 @@ -113,7 +117,7 @@ public class KeyUtil { */ public static SecretKey generateKey(String algorithm, byte[] key) { Assert.notBlank(algorithm, "Algorithm is blank!"); - SecretKey secretKey = null; + SecretKey secretKey; if (algorithm.startsWith("PBE")) { // PBE密钥 secretKey = generatePBEKey(algorithm, (null == key) ? null : StrUtil.str(key, CharsetUtil.CHARSET_UTF_8).toCharArray()); @@ -139,7 +143,7 @@ public class KeyUtil { throw new CryptoException("Algorithm [{}] is not a DES algorithm!"); } - SecretKey secretKey = null; + SecretKey secretKey; if (null == key) { secretKey = generateKey(algorithm); } else { @@ -608,7 +612,7 @@ public class KeyUtil { * @return {@link KeyStore} */ public static KeyStore readJKSKeyStore(InputStream in, char[] password) { - return readKeyStore(KEY_STORE, in, password); + return readKeyStore(KEY_TYPE_JKS, in, password); } /** @@ -618,11 +622,11 @@ public class KeyUtil { * * @param type 类型 * @param in {@link InputStream} 如果想从文件读取.keystore文件,使用 {@link FileUtil#getInputStream(java.io.File)} 读取 - * @param password 密码 + * @param password 密码,null表示无密码 * @return {@link KeyStore} */ public static KeyStore readKeyStore(String type, InputStream in, char[] password) { - KeyStore keyStore = null; + KeyStore keyStore; try { keyStore = KeyStore.getInstance(type); keyStore.load(in, password); @@ -680,7 +684,7 @@ public class KeyUtil { * @since 4.4.1 */ public static Certificate readX509Certificate(InputStream in, char[] password, String alias) { - return readCertificate(X509, in, password, alias); + return readCertificate(KEY_TYPE_X509, in, password, alias); } /** @@ -710,7 +714,7 @@ public class KeyUtil { * @since 4.4.1 */ public static Certificate readX509Certificate(InputStream in) { - return readCertificate(X509, in); + return readCertificate(KEY_TYPE_X509, in); } /** diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpBase.java b/hutool-http/src/main/java/cn/hutool/http/HttpBase.java index 33ac073ae..128690fca 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpBase.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpBase.java @@ -27,7 +27,7 @@ public abstract class HttpBase { public static final String HTTP_1_1 = "HTTP/1.1"; /**存储头信息*/ - protected Map> headers = new HashMap>(); + protected Map> headers = new HashMap<>(); /**编码*/ protected Charset charset = CharsetUtil.CHARSET_UTF_8; /**http版本*/ @@ -90,7 +90,7 @@ public abstract class HttpBase { if(null != name && null != value){ final List values = headers.get(name.trim()); if(isOverride || CollectionUtil.isEmpty(values)) { - final ArrayList valueList = new ArrayList(); + final ArrayList valueList = new ArrayList<>(); valueList.add(value); headers.put(name.trim(), valueList); }else { diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java index 73cf812eb..6dd97775c 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java @@ -1,44 +1,31 @@ package cn.hutool.http; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.CookieManager; -import java.net.HttpCookie; -import java.net.HttpURLConnection; -import java.net.Proxy; -import java.net.URLStreamHandler; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLSocketFactory; - import cn.hutool.core.codec.Base64; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; -import cn.hutool.core.io.resource.BytesResource; -import cn.hutool.core.io.resource.FileResource; -import cn.hutool.core.io.resource.MultiFileResource; -import cn.hutool.core.io.resource.MultiResource; -import cn.hutool.core.io.resource.Resource; +import cn.hutool.core.io.resource.*; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.RandomUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.core.util.URLUtil; +import cn.hutool.core.util.*; import cn.hutool.http.cookie.GlobalCookieManager; import cn.hutool.http.ssl.SSLSocketFactoryBuilder; import cn.hutool.json.JSON; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + /** * http请求类
    * Http请求类用于构建Http请求并同步获取结果,此类通过CookieManager持有域名对应的Cookie值,再次请求时会自动附带Cookie信息 @@ -987,8 +974,6 @@ public class HttpRequest extends HttpBase { .setHttpsInfo(this.hostnameVerifier, this.ssf)// .setConnectTimeout(this.connectionTimeout)// .setReadTimeout(this.readTimeout)// - // 自定义Cookie - .setCookie(this.cookie) // 定义转发 .setInstanceFollowRedirects(this.maxRedirectCount > 0) // 流方式上传数据 @@ -996,8 +981,13 @@ public class HttpRequest extends HttpBase { // 覆盖默认Header .header(this.headers, true); - // 读取全局Cookie信息并附带到请求中 - GlobalCookieManager.add(this.httpConnection); + if (null != this.cookie) { + // 当用户自定义Cookie时,全局Cookie自动失效 + this.httpConnection.setCookie(this.cookie); + } else { + // 读取全局Cookie信息并附带到请求中 + GlobalCookieManager.add(this.httpConnection); + } // 是否禁用缓存 if (this.isDisableCache) { @@ -1193,8 +1183,6 @@ public class HttpRequest extends HttpBase { /** * 设置表单类型为Multipart(文件上传) - * - * @return HttpConnection HTTP连接对象 */ private void setMultipart() { this.httpConnection.header(Header.CONTENT_TYPE, CONTENT_TYPE_MULTIPART_PREFIX + BOUNDARY, true); diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java b/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java index 0456f202e..463b348f1 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java @@ -151,10 +151,9 @@ public class HttpResponse extends HttpBase implements Closeable { * * @return Cookie列表 * @since 3.1.1 - * @see GlobalCookieManager#getCookieManager() */ public List getCookies() { - return GlobalCookieManager.getCookieManager().getCookieStore().getCookies(); + return GlobalCookieManager.getCookies(this.httpConnection); } /** @@ -374,11 +373,10 @@ public class HttpResponse extends HttpBase implements Closeable { try { this.status = httpConnection.responseCode(); } catch (IOException e) { - if (e instanceof FileNotFoundException) { - // 服务器无返回内容,忽略之 - } else { + if (false == (e instanceof FileNotFoundException)) { throw new HttpException(e); } + // 服务器无返回内容,忽略之 } // 读取响应头信息 @@ -410,7 +408,6 @@ public class HttpResponse extends HttpBase implements Closeable { * 读取主体,忽略EOFException异常 * * @param in 输入流 - * @return 自身 * @throws IORuntimeException IO异常 */ private void readBody(InputStream in) throws IORuntimeException { diff --git a/hutool-http/src/main/java/cn/hutool/http/cookie/GlobalCookieManager.java b/hutool-http/src/main/java/cn/hutool/http/cookie/GlobalCookieManager.java index a432452ce..30bcfb439 100644 --- a/hutool-http/src/main/java/cn/hutool/http/cookie/GlobalCookieManager.java +++ b/hutool-http/src/main/java/cn/hutool/http/cookie/GlobalCookieManager.java @@ -7,6 +7,8 @@ import cn.hutool.http.HttpConnection; import java.io.IOException; import java.net.CookieManager; import java.net.CookiePolicy; +import java.net.HttpCookie; +import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -43,6 +45,17 @@ public class GlobalCookieManager { return cookieManager; } + /** + * 获取指定域名下所有Cookie信息 + * + * @param conn HTTP连接 + * @return Cookie信息列表 + * @since 4.6.9 + */ + public static List getCookies(HttpConnection conn){ + return cookieManager.getCookieStore().get(getDomain(conn)); + } + /** * 将本地存储的Cookie信息附带到Http请求中,不覆盖用户定义好的Cookie * @@ -53,10 +66,10 @@ public class GlobalCookieManager { // 全局Cookie管理器关闭 return; } - + Map> cookieHeader; try { - cookieHeader = cookieManager.get(URLUtil.toURI(conn.getUrl()), new HashMap>(0)); + cookieHeader = cookieManager.get(getDomain(conn), new HashMap>(0)); } catch (IOException e) { throw new IORuntimeException(e); } @@ -77,9 +90,18 @@ public class GlobalCookieManager { } try { - cookieManager.put(URLUtil.toURI(conn.getUrl()), conn.headers()); + cookieManager.put(getDomain(conn), conn.headers()); } catch (IOException e) { throw new IORuntimeException(e); } } + + /** + * 获取连接的URL中域名信息,例如http://www.hutool.cn/aaa/bb.html,得到www.hutool.cn + * @param conn HttpConnection + * @return URI + */ + private static URI getDomain(HttpConnection conn){ + return URLUtil.getHost(conn.getUrl()); + } } diff --git a/hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java b/hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java index 917803b8f..7121fc6e3 100644 --- a/hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/test/HttpRequestTest.java @@ -29,6 +29,15 @@ public class HttpRequestTest { String body = HttpRequest.get("https://www.gjifa.com/pc/").execute().body(); Console.log(body); } + + @Test + @Ignore + public void getCookiesTest() { + // 检查在Connection关闭情况下Cookie是否可以正常获取 + HttpResponse res = HttpRequest.get("https://www.oschina.net/").execute(); + String body = res.body(); + Console.log(res.getCookies()); + } @Test @Ignore