mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-04 12:47:59 +08:00
add parseCST and fix cookie bug
This commit is contained in:
parent
476285b302
commit
a4515e218b
@ -8,10 +8,14 @@
|
|||||||
### 新特性
|
### 新特性
|
||||||
* 【all】 修复注释中的错别字(issue#I12XE6@Gitee)
|
* 【all】 修复注释中的错别字(issue#I12XE6@Gitee)
|
||||||
* 【core】 CsvWriter支持其它类型的参数(issue#I12XE3@Gitee)
|
* 【core】 CsvWriter支持其它类型的参数(issue#I12XE3@Gitee)
|
||||||
* 【core】 ClassScaner支持自定义ClassLoader
|
* 【core】 ClassScanner支持自定义ClassLoader
|
||||||
|
* 【core】 修改错别字(pr#568@Github)
|
||||||
|
* 【core】 增加DateUtil.parseCST方法(issue#570@Github)
|
||||||
|
|
||||||
### Bug修复
|
### Bug修复
|
||||||
* 【all】 修复阶乘计算错误bug(issue#I12XE4@Gitee)
|
* 【all】 修复阶乘计算错误bug(issue#I12XE4@Gitee)
|
||||||
|
* 【http】 修复disableCookie无效问题(issue#572@Github)
|
||||||
|
* 【http】 修复HttpResponse.getCookies导致的问题(issue#572@Github)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ public class DateTime extends Date {
|
|||||||
*/
|
*/
|
||||||
public DateTime(Calendar calendar) {
|
public DateTime(Calendar calendar) {
|
||||||
this(calendar.getTime(), calendar.getTimeZone());
|
this(calendar.getTime(), calendar.getTimeZone());
|
||||||
|
this.setFirstDayOfWeek(Week.of(calendar.getFirstDayOfWeek()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -757,6 +757,24 @@ public class DateUtil {
|
|||||||
throw new DateException("No format fit for date String [{}] !", utcString);
|
throw new DateException("No format fit for date String [{}] !", utcString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析CST时间,格式:<br>
|
||||||
|
* <ol>
|
||||||
|
* <li>EEE MMM dd HH:mm:ss z yyyy(例如:Wed Aug 01 00:00:00 CST 2012)</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* @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}对象,格式:<br>
|
* 将日期字符串转换为{@link DateTime}对象,格式:<br>
|
||||||
* <ol>
|
* <ol>
|
||||||
@ -808,8 +826,11 @@ public class DateUtil {
|
|||||||
// HH:mm:ss 或者 HH:mm 时间格式匹配单独解析
|
// HH:mm:ss 或者 HH:mm 时间格式匹配单独解析
|
||||||
return parseTimeToday(dateStr);
|
return parseTimeToday(dateStr);
|
||||||
} else if (StrUtil.containsAnyIgnoreCase(dateStr, wtb)) {
|
} 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
|
// JDK的Date对象toString默认格式,类似于:
|
||||||
return parse(dateStr, DatePattern.JDK_DATETIME_FORMAT);
|
// 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')) {
|
} else if (StrUtil.contains(dateStr, 'T')) {
|
||||||
// UTC时间
|
// UTC时间
|
||||||
return parseUTC(dateStr);
|
return parseUTC(dateStr);
|
||||||
|
@ -23,9 +23,9 @@ import java.util.jar.JarFile;
|
|||||||
* 类扫描器
|
* 类扫描器
|
||||||
*
|
*
|
||||||
* @author looly
|
* @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;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,13 +124,13 @@ public class ClassScaner implements Serializable {
|
|||||||
* @return 类集合
|
* @return 类集合
|
||||||
*/
|
*/
|
||||||
public static Set<Class<?>> scanPackage(String packageName, Filter<Class<?>> classFilter) {
|
public static Set<Class<?>> scanPackage(String packageName, Filter<Class<?>> classFilter) {
|
||||||
return new ClassScaner(packageName, classFilter).scan();
|
return new ClassScanner(packageName, classFilter).scan();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造,默认UTF-8编码
|
* 构造,默认UTF-8编码
|
||||||
*/
|
*/
|
||||||
public ClassScaner() {
|
public ClassScanner() {
|
||||||
this(null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ public class ClassScaner implements Serializable {
|
|||||||
*
|
*
|
||||||
* @param packageName 包名,所有包传入""或者null
|
* @param packageName 包名,所有包传入""或者null
|
||||||
*/
|
*/
|
||||||
public ClassScaner(String packageName) {
|
public ClassScanner(String packageName) {
|
||||||
this(packageName, null);
|
this(packageName, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ public class ClassScaner implements Serializable {
|
|||||||
* @param packageName 包名,所有包传入""或者null
|
* @param packageName 包名,所有包传入""或者null
|
||||||
* @param classFilter 过滤器,无需传入null
|
* @param classFilter 过滤器,无需传入null
|
||||||
*/
|
*/
|
||||||
public ClassScaner(String packageName, Filter<Class<?>> classFilter) {
|
public ClassScanner(String packageName, Filter<Class<?>> classFilter) {
|
||||||
this(packageName, classFilter, CharsetUtil.CHARSET_UTF_8);
|
this(packageName, classFilter, CharsetUtil.CHARSET_UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ public class ClassScaner implements Serializable {
|
|||||||
* @param classFilter 过滤器,无需传入null
|
* @param classFilter 过滤器,无需传入null
|
||||||
* @param charset 编码
|
* @param charset 编码
|
||||||
*/
|
*/
|
||||||
public ClassScaner(String packageName, Filter<Class<?>> classFilter, Charset charset) {
|
public ClassScanner(String packageName, Filter<Class<?>> classFilter, Charset charset) {
|
||||||
packageName = StrUtil.nullToEmpty(packageName);
|
packageName = StrUtil.nullToEmpty(packageName);
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
this.packageNameWithDot = StrUtil.addSuffixIfNot(packageName, StrUtil.DOT);
|
this.packageNameWithDot = StrUtil.addSuffixIfNot(packageName, StrUtil.DOT);
|
@ -26,7 +26,7 @@ public class NamedThreadFactory implements ThreadFactory {
|
|||||||
/** 线程组 */
|
/** 线程组 */
|
||||||
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||||
/** 是否守护线程 */
|
/** 是否守护线程 */
|
||||||
private final boolean isDeamon;
|
private final boolean isDaemon;
|
||||||
/** 无法捕获的异常统一处理 */
|
/** 无法捕获的异常统一处理 */
|
||||||
private final UncaughtExceptionHandler handler;
|
private final UncaughtExceptionHandler handler;
|
||||||
|
|
||||||
@ -34,10 +34,10 @@ public class NamedThreadFactory implements ThreadFactory {
|
|||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param prefix 线程名前缀
|
* @param prefix 线程名前缀
|
||||||
* @param isDeamon 是否守护线程
|
* @param isDaemon 是否守护线程
|
||||||
*/
|
*/
|
||||||
public NamedThreadFactory(String prefix, boolean isDeamon) {
|
public NamedThreadFactory(String prefix, boolean isDaemon) {
|
||||||
this(prefix, null, isDeamon);
|
this(prefix, null, isDaemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,10 +45,10 @@ public class NamedThreadFactory implements ThreadFactory {
|
|||||||
*
|
*
|
||||||
* @param prefix 线程名前缀
|
* @param prefix 线程名前缀
|
||||||
* @param threadGroup 线程组,可以为null
|
* @param threadGroup 线程组,可以为null
|
||||||
* @param isDeamon 是否守护线程
|
* @param isDaemon 是否守护线程
|
||||||
*/
|
*/
|
||||||
public NamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDeamon) {
|
public NamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon) {
|
||||||
this(prefix, threadGroup, isDeamon, null);
|
this(prefix, threadGroup, isDaemon, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,16 +56,16 @@ public class NamedThreadFactory implements ThreadFactory {
|
|||||||
*
|
*
|
||||||
* @param prefix 线程名前缀
|
* @param prefix 线程名前缀
|
||||||
* @param threadGroup 线程组,可以为null
|
* @param threadGroup 线程组,可以为null
|
||||||
* @param isDeamon 是否守护线程
|
* @param isDaemon 是否守护线程
|
||||||
* @param handler 未捕获异常处理
|
* @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;
|
this.prefix = StrUtil.isBlank(prefix) ? "Hutool" : prefix;
|
||||||
if (null == threadGroup) {
|
if (null == threadGroup) {
|
||||||
threadGroup = ThreadUtil.currentThreadGroup();
|
threadGroup = ThreadUtil.currentThreadGroup();
|
||||||
}
|
}
|
||||||
this.group = threadGroup;
|
this.group = threadGroup;
|
||||||
this.isDeamon = isDeamon;
|
this.isDaemon = isDaemon;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,11 +75,11 @@ public class NamedThreadFactory implements ThreadFactory {
|
|||||||
|
|
||||||
//守护线程
|
//守护线程
|
||||||
if (false == t.isDaemon()) {
|
if (false == t.isDaemon()) {
|
||||||
if (isDeamon) {
|
if (isDaemon) {
|
||||||
// 原线程为非守护则设置为守护
|
// 原线程为非守护则设置为守护
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
}
|
}
|
||||||
} else if (false == isDeamon) {
|
} else if (false == isDaemon) {
|
||||||
// 原线程为守护则还原为非守护
|
// 原线程为守护则还原为非守护
|
||||||
t.setDaemon(false);
|
t.setDaemon(false);
|
||||||
}
|
}
|
||||||
|
@ -98,17 +98,17 @@ public class ThreadUtil {
|
|||||||
* 执行异步方法
|
* 执行异步方法
|
||||||
*
|
*
|
||||||
* @param runnable 需要执行的方法体
|
* @param runnable 需要执行的方法体
|
||||||
* @param isDeamon 是否守护线程。守护线程会在主线程结束后自动结束
|
* @param isDaemon 是否守护线程。守护线程会在主线程结束后自动结束
|
||||||
* @return 执行的方法体
|
* @return 执行的方法体
|
||||||
*/
|
*/
|
||||||
public static Runnable excAsync(final Runnable runnable, boolean isDeamon) {
|
public static Runnable excAsync(final Runnable runnable, boolean isDaemon) {
|
||||||
Thread thread = new Thread() {
|
Thread thread = new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
thread.setDaemon(isDeamon);
|
thread.setDaemon(isDaemon);
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
return runnable;
|
return runnable;
|
||||||
@ -192,13 +192,13 @@ public class ThreadUtil {
|
|||||||
*
|
*
|
||||||
* @param runnable {@link Runnable}
|
* @param runnable {@link Runnable}
|
||||||
* @param name 线程名
|
* @param name 线程名
|
||||||
* @param isDeamon 是否守护线程
|
* @param isDaemon 是否守护线程
|
||||||
* @return {@link Thread}
|
* @return {@link Thread}
|
||||||
* @since 4.1.2
|
* @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);
|
final Thread t = new Thread(null, runnable, name);
|
||||||
t.setDaemon(isDeamon);
|
t.setDaemon(isDaemon);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,11 +396,11 @@ public class ThreadUtil {
|
|||||||
* 创建线程工厂
|
* 创建线程工厂
|
||||||
*
|
*
|
||||||
* @param prefix 线程名前缀
|
* @param prefix 线程名前缀
|
||||||
* @param isDeamon 是否守护线程
|
* @param isDaemon 是否守护线程
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
public static ThreadFactory newNamedThreadFactory(String prefix, boolean isDeamon) {
|
public static ThreadFactory newNamedThreadFactory(String prefix, boolean isDaemon) {
|
||||||
return new NamedThreadFactory(prefix, isDeamon);
|
return new NamedThreadFactory(prefix, isDaemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -408,11 +408,11 @@ public class ThreadUtil {
|
|||||||
*
|
*
|
||||||
* @param prefix 线程名前缀
|
* @param prefix 线程名前缀
|
||||||
* @param threadGroup 线程组,可以为null
|
* @param threadGroup 线程组,可以为null
|
||||||
* @param isDeamon 是否守护线程
|
* @param isDaemon 是否守护线程
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDeamon) {
|
public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon) {
|
||||||
return new NamedThreadFactory(prefix, threadGroup, isDeamon);
|
return new NamedThreadFactory(prefix, threadGroup, isDaemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -420,12 +420,12 @@ public class ThreadUtil {
|
|||||||
*
|
*
|
||||||
* @param prefix 线程名前缀
|
* @param prefix 线程名前缀
|
||||||
* @param threadGroup 线程组,可以为null
|
* @param threadGroup 线程组,可以为null
|
||||||
* @param isDeamon 是否守护线程
|
* @param isDaemon 是否守护线程
|
||||||
* @param handler 未捕获异常处理
|
* @param handler 未捕获异常处理
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDeamon, UncaughtExceptionHandler handler) {
|
public static ThreadFactory newNamedThreadFactory(String prefix, ThreadGroup threadGroup, boolean isDaemon, UncaughtExceptionHandler handler) {
|
||||||
return new NamedThreadFactory(prefix, threadGroup, isDeamon, handler);
|
return new NamedThreadFactory(prefix, threadGroup, isDaemon, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,7 +21,7 @@ import cn.hutool.core.io.FileUtil;
|
|||||||
import cn.hutool.core.io.IORuntimeException;
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
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.Filter;
|
||||||
import cn.hutool.core.lang.Singleton;
|
import cn.hutool.core.lang.Singleton;
|
||||||
|
|
||||||
@ -176,10 +176,10 @@ public class ClassUtil {
|
|||||||
* @param packageName 包路径
|
* @param packageName 包路径
|
||||||
* @param annotationClass 注解类
|
* @param annotationClass 注解类
|
||||||
* @return 类集合
|
* @return 类集合
|
||||||
* @see ClassScaner#scanPackageByAnnotation(String, Class)
|
* @see ClassScanner#scanPackageByAnnotation(String, Class)
|
||||||
*/
|
*/
|
||||||
public static Set<Class<?>> scanPackageByAnnotation(String packageName, final Class<? extends Annotation> annotationClass) {
|
public static Set<Class<?>> scanPackageByAnnotation(String packageName, final Class<? extends Annotation> annotationClass) {
|
||||||
return ClassScaner.scanPackageByAnnotation(packageName, annotationClass);
|
return ClassScanner.scanPackageByAnnotation(packageName, annotationClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,20 +188,20 @@ public class ClassUtil {
|
|||||||
* @param packageName 包路径
|
* @param packageName 包路径
|
||||||
* @param superClass 父类或接口
|
* @param superClass 父类或接口
|
||||||
* @return 类集合
|
* @return 类集合
|
||||||
* @see ClassScaner#scanPackageBySuper(String, Class)
|
* @see ClassScanner#scanPackageBySuper(String, Class)
|
||||||
*/
|
*/
|
||||||
public static Set<Class<?>> scanPackageBySuper(String packageName, final Class<?> superClass) {
|
public static Set<Class<?>> scanPackageBySuper(String packageName, final Class<?> superClass) {
|
||||||
return ClassScaner.scanPackageBySuper(packageName, superClass);
|
return ClassScanner.scanPackageBySuper(packageName, superClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫面该包路径下所有class文件
|
* 扫面该包路径下所有class文件
|
||||||
*
|
*
|
||||||
* @return 类集合
|
* @return 类集合
|
||||||
* @see ClassScaner#scanPackage()
|
* @see ClassScanner#scanPackage()
|
||||||
*/
|
*/
|
||||||
public static Set<Class<?>> scanPackage() {
|
public static Set<Class<?>> scanPackage() {
|
||||||
return ClassScaner.scanPackage();
|
return ClassScanner.scanPackage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,10 +209,10 @@ public class ClassUtil {
|
|||||||
*
|
*
|
||||||
* @param packageName 包路径 com | com. | com.abs | com.abs.
|
* @param packageName 包路径 com | com. | com.abs | com.abs.
|
||||||
* @return 类集合
|
* @return 类集合
|
||||||
* @see ClassScaner#scanPackage(String)
|
* @see ClassScanner#scanPackage(String)
|
||||||
*/
|
*/
|
||||||
public static Set<Class<?>> scanPackage(String packageName) {
|
public static Set<Class<?>> scanPackage(String packageName) {
|
||||||
return ClassScaner.scanPackage(packageName);
|
return ClassScanner.scanPackage(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,7 +225,7 @@ public class ClassUtil {
|
|||||||
* @return 类集合
|
* @return 类集合
|
||||||
*/
|
*/
|
||||||
public static Set<Class<?>> scanPackage(String packageName, Filter<Class<?>> classFilter) {
|
public static Set<Class<?>> scanPackage(String packageName, Filter<Class<?>> classFilter) {
|
||||||
return ClassScaner.scanPackage(packageName, classFilter);
|
return ClassScanner.scanPackage(packageName, classFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------- Method
|
// ----------------------------------------------------------------------------------------- Method
|
||||||
|
@ -585,10 +585,7 @@ public class StrUtil {
|
|||||||
*/
|
*/
|
||||||
public static boolean startWith(CharSequence str, CharSequence prefix, boolean isIgnoreCase) {
|
public static boolean startWith(CharSequence str, CharSequence prefix, boolean isIgnoreCase) {
|
||||||
if (null == str || null == prefix) {
|
if (null == str || null == prefix) {
|
||||||
if (null == str && null == prefix) {
|
return null == str && null == prefix;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isIgnoreCase) {
|
if (isIgnoreCase) {
|
||||||
@ -664,10 +661,7 @@ public class StrUtil {
|
|||||||
*/
|
*/
|
||||||
public static boolean endWith(CharSequence str, CharSequence suffix, boolean isIgnoreCase) {
|
public static boolean endWith(CharSequence str, CharSequence suffix, boolean isIgnoreCase) {
|
||||||
if (null == str || null == suffix) {
|
if (null == str || null == suffix) {
|
||||||
if (null == str && null == suffix) {
|
return null == str && null == suffix;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isIgnoreCase) {
|
if (isIgnoreCase) {
|
||||||
@ -3831,7 +3825,7 @@ public class StrUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int preIndex = fromIndex;
|
int preIndex = fromIndex;
|
||||||
int index = fromIndex;
|
int index;
|
||||||
while ((index = indexOf(str, searchStr, preIndex, ignoreCase)) > -1) {
|
while ((index = indexOf(str, searchStr, preIndex, ignoreCase)) > -1) {
|
||||||
result.append(str.subSequence(preIndex, index));
|
result.append(str.subSequence(preIndex, index));
|
||||||
result.append(replacement);
|
result.append(replacement);
|
||||||
@ -3985,7 +3979,7 @@ public class StrUtil {
|
|||||||
*
|
*
|
||||||
* @param str1 字符串1
|
* @param str1 字符串1
|
||||||
* @param str2 字符串2
|
* @param str2 字符串2
|
||||||
* @param scale
|
* @param scale 相似度
|
||||||
* @return 相似度百分比
|
* @return 相似度百分比
|
||||||
* @since 3.2.3
|
* @since 3.2.3
|
||||||
*/
|
*/
|
||||||
|
@ -213,6 +213,20 @@ public class URLUtil {
|
|||||||
return urls;
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 补全相对路径
|
* 补全相对路径
|
||||||
*
|
*
|
||||||
|
@ -2,6 +2,7 @@ package cn.hutool.core.date;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.BetweenFormater.Level;
|
import cn.hutool.core.date.BetweenFormater.Level;
|
||||||
|
import cn.hutool.core.lang.Console;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -472,6 +473,16 @@ public class DateUtilTest {
|
|||||||
Assert.assertEquals("2018-09-13 13:34:39.999", dateStr);
|
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
|
@Test
|
||||||
public void parseJDkTest() {
|
public void parseJDkTest() {
|
||||||
String dateStr = "Thu May 16 17:57:18 GMT+08:00 2019";
|
String dateStr = "Thu May 16 17:57:18 GMT+08:00 2019";
|
||||||
|
@ -10,7 +10,7 @@ public class ClassScanerTest {
|
|||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void scanTest() {
|
public void scanTest() {
|
||||||
ClassScaner scaner = new ClassScaner("cn.hutool.core.util", null);
|
ClassScanner scaner = new ClassScanner("cn.hutool.core.util", null);
|
||||||
Set<Class<?>> set = scaner.scan();
|
Set<Class<?>> set = scaner.scan();
|
||||||
for (Class<?> clazz : set) {
|
for (Class<?> clazz : set) {
|
||||||
Console.log(clazz.getName());
|
Console.log(clazz.getName());
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package cn.hutool.core.util;
|
package cn.hutool.core.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Console;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URLUtil单元测试
|
* URLUtil单元测试
|
||||||
*
|
*
|
||||||
@ -55,6 +60,14 @@ public class URLUtilTest {
|
|||||||
Assert.assertEquals("http://www.hutool.cn/aaa/bbb?a=1&b=2", normalize);
|
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
|
@Test
|
||||||
public void encodeTest() {
|
public void encodeTest() {
|
||||||
String body = "366466 - 副本.jpg";
|
String body = "366466 - 副本.jpg";
|
||||||
|
@ -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()) {
|
if (scheduler.isStarted()) {
|
||||||
throw new UtilException("Scheduler has been started, please stop it first!");
|
throw new UtilException("Scheduler has been started, please stop it first!");
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ public class CronUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
schedule(crontabSetting);
|
schedule(crontabSetting);
|
||||||
scheduler.start(isDeamon);
|
scheduler.start(isDaemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,7 +126,7 @@ public class Scheduler implements Serializable {
|
|||||||
*
|
*
|
||||||
* @return 是否为守护线程
|
* @return 是否为守护线程
|
||||||
*/
|
*/
|
||||||
public boolean isDeamon() {
|
public boolean isDaemon() {
|
||||||
return this.daemon;
|
return this.daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,11 +362,11 @@ public class Scheduler implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 启动
|
* 启动
|
||||||
*
|
*
|
||||||
* @param isDeamon 是否以守护线程方式启动,如果为true,则在调用{@link #stop()}方法后执行的定时任务立即结束,否则等待执行完毕才结束。
|
* @param isDaemon 是否以守护线程方式启动,如果为true,则在调用{@link #stop()}方法后执行的定时任务立即结束,否则等待执行完毕才结束。
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public Scheduler start(boolean isDeamon) {
|
public Scheduler start(boolean isDaemon) {
|
||||||
this.daemon = isDeamon;
|
this.daemon = isDaemon;
|
||||||
return start();
|
return start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +50,12 @@ import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
|
|||||||
public class KeyUtil {
|
public class KeyUtil {
|
||||||
|
|
||||||
/** Java密钥库(Java Key Store,JKS)KEY_STORE */
|
/** Java密钥库(Java Key Store,JKS)KEY_STORE */
|
||||||
public static final String KEY_STORE = "JKS";
|
public static final String KEY_TYPE_JKS = "JKS";
|
||||||
public static final String X509 = "X.509";
|
/** 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) {
|
public static SecretKey generateKey(String algorithm, byte[] key) {
|
||||||
Assert.notBlank(algorithm, "Algorithm is blank!");
|
Assert.notBlank(algorithm, "Algorithm is blank!");
|
||||||
SecretKey secretKey = null;
|
SecretKey secretKey;
|
||||||
if (algorithm.startsWith("PBE")) {
|
if (algorithm.startsWith("PBE")) {
|
||||||
// PBE密钥
|
// PBE密钥
|
||||||
secretKey = generatePBEKey(algorithm, (null == key) ? null : StrUtil.str(key, CharsetUtil.CHARSET_UTF_8).toCharArray());
|
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!");
|
throw new CryptoException("Algorithm [{}] is not a DES algorithm!");
|
||||||
}
|
}
|
||||||
|
|
||||||
SecretKey secretKey = null;
|
SecretKey secretKey;
|
||||||
if (null == key) {
|
if (null == key) {
|
||||||
secretKey = generateKey(algorithm);
|
secretKey = generateKey(algorithm);
|
||||||
} else {
|
} else {
|
||||||
@ -608,7 +612,7 @@ public class KeyUtil {
|
|||||||
* @return {@link KeyStore}
|
* @return {@link KeyStore}
|
||||||
*/
|
*/
|
||||||
public static KeyStore readJKSKeyStore(InputStream in, char[] password) {
|
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 type 类型
|
||||||
* @param in {@link InputStream} 如果想从文件读取.keystore文件,使用 {@link FileUtil#getInputStream(java.io.File)} 读取
|
* @param in {@link InputStream} 如果想从文件读取.keystore文件,使用 {@link FileUtil#getInputStream(java.io.File)} 读取
|
||||||
* @param password 密码
|
* @param password 密码,null表示无密码
|
||||||
* @return {@link KeyStore}
|
* @return {@link KeyStore}
|
||||||
*/
|
*/
|
||||||
public static KeyStore readKeyStore(String type, InputStream in, char[] password) {
|
public static KeyStore readKeyStore(String type, InputStream in, char[] password) {
|
||||||
KeyStore keyStore = null;
|
KeyStore keyStore;
|
||||||
try {
|
try {
|
||||||
keyStore = KeyStore.getInstance(type);
|
keyStore = KeyStore.getInstance(type);
|
||||||
keyStore.load(in, password);
|
keyStore.load(in, password);
|
||||||
@ -680,7 +684,7 @@ public class KeyUtil {
|
|||||||
* @since 4.4.1
|
* @since 4.4.1
|
||||||
*/
|
*/
|
||||||
public static Certificate readX509Certificate(InputStream in, char[] password, String alias) {
|
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
|
* @since 4.4.1
|
||||||
*/
|
*/
|
||||||
public static Certificate readX509Certificate(InputStream in) {
|
public static Certificate readX509Certificate(InputStream in) {
|
||||||
return readCertificate(X509, in);
|
return readCertificate(KEY_TYPE_X509, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,7 @@ public abstract class HttpBase<T> {
|
|||||||
public static final String HTTP_1_1 = "HTTP/1.1";
|
public static final String HTTP_1_1 = "HTTP/1.1";
|
||||||
|
|
||||||
/**存储头信息*/
|
/**存储头信息*/
|
||||||
protected Map<String, List<String>> headers = new HashMap<String, List<String>>();
|
protected Map<String, List<String>> headers = new HashMap<>();
|
||||||
/**编码*/
|
/**编码*/
|
||||||
protected Charset charset = CharsetUtil.CHARSET_UTF_8;
|
protected Charset charset = CharsetUtil.CHARSET_UTF_8;
|
||||||
/**http版本*/
|
/**http版本*/
|
||||||
@ -90,7 +90,7 @@ public abstract class HttpBase<T> {
|
|||||||
if(null != name && null != value){
|
if(null != name && null != value){
|
||||||
final List<String> values = headers.get(name.trim());
|
final List<String> values = headers.get(name.trim());
|
||||||
if(isOverride || CollectionUtil.isEmpty(values)) {
|
if(isOverride || CollectionUtil.isEmpty(values)) {
|
||||||
final ArrayList<String> valueList = new ArrayList<String>();
|
final ArrayList<String> valueList = new ArrayList<>();
|
||||||
valueList.add(value);
|
valueList.add(value);
|
||||||
headers.put(name.trim(), valueList);
|
headers.put(name.trim(), valueList);
|
||||||
}else {
|
}else {
|
||||||
|
@ -1,44 +1,31 @@
|
|||||||
package cn.hutool.http;
|
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.codec.Base64;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.io.IORuntimeException;
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
import cn.hutool.core.io.resource.BytesResource;
|
import cn.hutool.core.io.resource.*;
|
||||||
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.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.*;
|
||||||
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.http.cookie.GlobalCookieManager;
|
import cn.hutool.http.cookie.GlobalCookieManager;
|
||||||
import cn.hutool.http.ssl.SSLSocketFactoryBuilder;
|
import cn.hutool.http.ssl.SSLSocketFactoryBuilder;
|
||||||
import cn.hutool.json.JSON;
|
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请求类<br>
|
* http请求类<br>
|
||||||
* Http请求类用于构建Http请求并同步获取结果,此类通过CookieManager持有域名对应的Cookie值,再次请求时会自动附带Cookie信息
|
* Http请求类用于构建Http请求并同步获取结果,此类通过CookieManager持有域名对应的Cookie值,再次请求时会自动附带Cookie信息
|
||||||
@ -987,8 +974,6 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
.setHttpsInfo(this.hostnameVerifier, this.ssf)//
|
.setHttpsInfo(this.hostnameVerifier, this.ssf)//
|
||||||
.setConnectTimeout(this.connectionTimeout)//
|
.setConnectTimeout(this.connectionTimeout)//
|
||||||
.setReadTimeout(this.readTimeout)//
|
.setReadTimeout(this.readTimeout)//
|
||||||
// 自定义Cookie
|
|
||||||
.setCookie(this.cookie)
|
|
||||||
// 定义转发
|
// 定义转发
|
||||||
.setInstanceFollowRedirects(this.maxRedirectCount > 0)
|
.setInstanceFollowRedirects(this.maxRedirectCount > 0)
|
||||||
// 流方式上传数据
|
// 流方式上传数据
|
||||||
@ -996,8 +981,13 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
// 覆盖默认Header
|
// 覆盖默认Header
|
||||||
.header(this.headers, true);
|
.header(this.headers, true);
|
||||||
|
|
||||||
|
if (null != this.cookie) {
|
||||||
|
// 当用户自定义Cookie时,全局Cookie自动失效
|
||||||
|
this.httpConnection.setCookie(this.cookie);
|
||||||
|
} else {
|
||||||
// 读取全局Cookie信息并附带到请求中
|
// 读取全局Cookie信息并附带到请求中
|
||||||
GlobalCookieManager.add(this.httpConnection);
|
GlobalCookieManager.add(this.httpConnection);
|
||||||
|
}
|
||||||
|
|
||||||
// 是否禁用缓存
|
// 是否禁用缓存
|
||||||
if (this.isDisableCache) {
|
if (this.isDisableCache) {
|
||||||
@ -1193,8 +1183,6 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置表单类型为Multipart(文件上传)
|
* 设置表单类型为Multipart(文件上传)
|
||||||
*
|
|
||||||
* @return HttpConnection HTTP连接对象
|
|
||||||
*/
|
*/
|
||||||
private void setMultipart() {
|
private void setMultipart() {
|
||||||
this.httpConnection.header(Header.CONTENT_TYPE, CONTENT_TYPE_MULTIPART_PREFIX + BOUNDARY, true);
|
this.httpConnection.header(Header.CONTENT_TYPE, CONTENT_TYPE_MULTIPART_PREFIX + BOUNDARY, true);
|
||||||
|
@ -151,10 +151,9 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
|||||||
*
|
*
|
||||||
* @return Cookie列表
|
* @return Cookie列表
|
||||||
* @since 3.1.1
|
* @since 3.1.1
|
||||||
* @see GlobalCookieManager#getCookieManager()
|
|
||||||
*/
|
*/
|
||||||
public List<HttpCookie> getCookies() {
|
public List<HttpCookie> getCookies() {
|
||||||
return GlobalCookieManager.getCookieManager().getCookieStore().getCookies();
|
return GlobalCookieManager.getCookies(this.httpConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -374,11 +373,10 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
|||||||
try {
|
try {
|
||||||
this.status = httpConnection.responseCode();
|
this.status = httpConnection.responseCode();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (e instanceof FileNotFoundException) {
|
if (false == (e instanceof FileNotFoundException)) {
|
||||||
// 服务器无返回内容,忽略之
|
|
||||||
} else {
|
|
||||||
throw new HttpException(e);
|
throw new HttpException(e);
|
||||||
}
|
}
|
||||||
|
// 服务器无返回内容,忽略之
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取响应头信息
|
// 读取响应头信息
|
||||||
@ -410,7 +408,6 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
|||||||
* 读取主体,忽略EOFException异常
|
* 读取主体,忽略EOFException异常
|
||||||
*
|
*
|
||||||
* @param in 输入流
|
* @param in 输入流
|
||||||
* @return 自身
|
|
||||||
* @throws IORuntimeException IO异常
|
* @throws IORuntimeException IO异常
|
||||||
*/
|
*/
|
||||||
private void readBody(InputStream in) throws IORuntimeException {
|
private void readBody(InputStream in) throws IORuntimeException {
|
||||||
|
@ -7,6 +7,8 @@ import cn.hutool.http.HttpConnection;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.CookieManager;
|
import java.net.CookieManager;
|
||||||
import java.net.CookiePolicy;
|
import java.net.CookiePolicy;
|
||||||
|
import java.net.HttpCookie;
|
||||||
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -43,6 +45,17 @@ public class GlobalCookieManager {
|
|||||||
return cookieManager;
|
return cookieManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定域名下所有Cookie信息
|
||||||
|
*
|
||||||
|
* @param conn HTTP连接
|
||||||
|
* @return Cookie信息列表
|
||||||
|
* @since 4.6.9
|
||||||
|
*/
|
||||||
|
public static List<HttpCookie> getCookies(HttpConnection conn){
|
||||||
|
return cookieManager.getCookieStore().get(getDomain(conn));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将本地存储的Cookie信息附带到Http请求中,不覆盖用户定义好的Cookie
|
* 将本地存储的Cookie信息附带到Http请求中,不覆盖用户定义好的Cookie
|
||||||
*
|
*
|
||||||
@ -56,7 +69,7 @@ public class GlobalCookieManager {
|
|||||||
|
|
||||||
Map<String, List<String>> cookieHeader;
|
Map<String, List<String>> cookieHeader;
|
||||||
try {
|
try {
|
||||||
cookieHeader = cookieManager.get(URLUtil.toURI(conn.getUrl()), new HashMap<String, List<String>>(0));
|
cookieHeader = cookieManager.get(getDomain(conn), new HashMap<String, List<String>>(0));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IORuntimeException(e);
|
throw new IORuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -77,9 +90,18 @@ public class GlobalCookieManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cookieManager.put(URLUtil.toURI(conn.getUrl()), conn.headers());
|
cookieManager.put(getDomain(conn), conn.headers());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IORuntimeException(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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,15 @@ public class HttpRequestTest {
|
|||||||
Console.log(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
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void getWithParamsTest() {
|
public void getWithParamsTest() {
|
||||||
|
Loading…
Reference in New Issue
Block a user