diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ba49b326..270e388e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,7 @@
-------------------------------------------------------------------------------------------------------------
-# 5.7.3 (2021-06-25)
+# 5.7.3 (2021-06-26)
### 🐣新特性
* 【core 】 增加Convert.toSet方法(issue#I3XFG2@Gitee)
@@ -11,6 +11,8 @@
* 【core 】 新增JAXBUtil(pr#346@Gitee)
* 【poi 】 ExcelWriter新增setColumnStyleIfHasData和setRowStyleIfHasData(pr#347@Gitee)
* 【json 】 用户自定义日期时间格式时,解析也读取此格式
+* 【core 】 增加可自定义日期格式GlobalCustomFormat
+* 【jwt 】 JWT修改默认有序,并规定payload日期格式为秒数
### 🐞Bug修复
* 【json 】 修复XML转义字符的问题(issue#I3XH09@Gitee)
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java
index aaff4101c..57fbfbb08 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/CalendarUtil.java
@@ -3,6 +3,7 @@ package cn.hutool.core.date;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.convert.NumberChineseFormatter;
import cn.hutool.core.date.format.FastDateParser;
+import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@@ -654,6 +655,15 @@ public class CalendarUtil {
calendar.setLenient(lenient);
for (final String parsePattern : parsePatterns) {
+ if(GlobalCustomFormat.isCustomFormat(parsePattern)){
+ final Date parse = GlobalCustomFormat.parse(str, parsePattern);
+ if(null == parse){
+ continue;
+ }
+ calendar.setTime(parse);
+ return calendar;
+ }
+
final FastDateParser fdp = new FastDateParser(parsePattern, tz, lcl);
calendar.clear();
try {
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 29f06a07f..d210cd049 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
@@ -3,6 +3,7 @@ package cn.hutool.core.date;
import cn.hutool.core.date.format.DateParser;
import cn.hutool.core.date.format.DatePrinter;
import cn.hutool.core.date.format.FastDateFormat;
+import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@@ -251,7 +252,9 @@ public class DateTime extends Date {
* @see DatePattern
*/
public DateTime(CharSequence dateStr, String format) {
- this(dateStr, DateUtil.newSimpleFormat(format));
+ this(GlobalCustomFormat.isCustomFormat(format)
+ ? GlobalCustomFormat.parse(dateStr, format)
+ : parse(dateStr, DateUtil.newSimpleFormat(format)));
}
/**
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 195fb831b..0db1342ac 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
@@ -5,6 +5,7 @@ import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.date.format.DateParser;
import cn.hutool.core.date.format.DatePrinter;
import cn.hutool.core.date.format.FastDateFormat;
+import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.util.CharUtil;
@@ -488,6 +489,11 @@ public class DateUtil extends CalendarUtil {
return null;
}
+ // 检查自定义格式
+ if(GlobalCustomFormat.isCustomFormat(format)){
+ return GlobalCustomFormat.format(date, format);
+ }
+
TimeZone timeZone = null;
if (date instanceof DateTime) {
timeZone = ((DateTime) date).getTimeZone();
@@ -696,6 +702,10 @@ public class DateUtil extends CalendarUtil {
* @since 4.5.18
*/
public static DateTime parse(CharSequence dateStr, String format, Locale locale) {
+ if(GlobalCustomFormat.isCustomFormat(format)){
+ // 自定义格式化器忽略Locale
+ return new DateTime(GlobalCustomFormat.parse(dateStr, format));
+ }
return new DateTime(dateStr, DateUtil.newSimpleFormat(format, locale, null));
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java
index 21407068d..a40065243 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/LocalDateTimeUtil.java
@@ -1,5 +1,6 @@
package cn.hutool.core.date;
+import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
@@ -139,7 +140,7 @@ public class LocalDateTimeUtil {
* 毫秒转{@link LocalDateTime},结果会产生时间偏移
*
* @param epochMilli 从1970-01-01T00:00:00Z开始计数的毫秒数
- * @param timeZone 时区
+ * @param timeZone 时区
* @return {@link LocalDateTime}
*/
public static LocalDateTime of(long epochMilli, TimeZone timeZone) {
@@ -174,8 +175,8 @@ public class LocalDateTimeUtil {
return null;
}
- if(temporalAccessor instanceof LocalDate){
- return ((LocalDate)temporalAccessor).atStartOfDay();
+ if (temporalAccessor instanceof LocalDate) {
+ return ((LocalDate) temporalAccessor).atStartOfDay();
}
return LocalDateTime.of(
@@ -201,8 +202,8 @@ public class LocalDateTimeUtil {
return null;
}
- if(temporalAccessor instanceof LocalDateTime){
- return ((LocalDateTime)temporalAccessor).toLocalDate();
+ if (temporalAccessor instanceof LocalDateTime) {
+ return ((LocalDateTime) temporalAccessor).toLocalDate();
}
return LocalDate.of(
@@ -215,11 +216,11 @@ public class LocalDateTimeUtil {
/**
* 解析日期时间字符串为{@link LocalDateTime},仅支持yyyy-MM-dd'T'HH:mm:ss格式,例如:2007-12-03T10:15:30
*
- * @param text 日期时间字符串
+ * @param text 日期时间字符串
* @return {@link LocalDateTime}
*/
public static LocalDateTime parse(CharSequence text) {
- return parse(text, (DateTimeFormatter)null);
+ return parse(text, (DateTimeFormatter) null);
}
/**
@@ -252,23 +253,27 @@ public class LocalDateTimeUtil {
return null;
}
+ if(GlobalCustomFormat.isCustomFormat(format)){
+ return of(GlobalCustomFormat.parse(text, format));
+ }
+
DateTimeFormatter formatter = null;
- if(StrUtil.isNotBlank(format)){
+ if (StrUtil.isNotBlank(format)) {
// 修复yyyyMMddHHmmssSSS格式不能解析的问题
// fix issue#1082
//see https://stackoverflow.com/questions/22588051/is-java-time-failing-to-parse-fraction-of-second
// jdk8 bug at: https://bugs.openjdk.java.net/browse/JDK-8031085
- if(StrUtil.startWithIgnoreEquals(format, DatePattern.PURE_DATETIME_PATTERN)){
+ if (StrUtil.startWithIgnoreEquals(format, DatePattern.PURE_DATETIME_PATTERN)) {
final String fraction = StrUtil.removePrefix(format, DatePattern.PURE_DATETIME_PATTERN);
- if(ReUtil.isMatch("[S]{1,2}", fraction)){
+ if (ReUtil.isMatch("[S]{1,2}", fraction)) {
//将yyyyMMddHHmmssS、yyyyMMddHHmmssSS的日期统一替换为yyyyMMddHHmmssSSS格式,用0补
- text += StrUtil.repeat('0', 3-fraction.length());
+ text += StrUtil.repeat('0', 3 - fraction.length());
}
formatter = new DateTimeFormatterBuilder()
.appendPattern(DatePattern.PURE_DATETIME_PATTERN)
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter();
- } else{
+ } else {
formatter = DateTimeFormatter.ofPattern(format);
}
}
@@ -279,12 +284,12 @@ public class LocalDateTimeUtil {
/**
* 解析日期时间字符串为{@link LocalDate},仅支持yyyy-MM-dd'T'HH:mm:ss格式,例如:2007-12-03T10:15:30
*
- * @param text 日期时间字符串
+ * @param text 日期时间字符串
* @return {@link LocalDate}
* @since 5.3.10
*/
public static LocalDate parseDate(CharSequence text) {
- return parseDate(text, (DateTimeFormatter)null);
+ return parseDate(text, (DateTimeFormatter) null);
}
/**
@@ -323,7 +328,7 @@ public class LocalDateTimeUtil {
/**
* 格式化日期时间为yyyy-MM-dd HH:mm:ss格式
*
- * @param time {@link LocalDateTime}
+ * @param time {@link LocalDateTime}
* @return 格式化后的字符串
* @since 5.3.11
*/
@@ -350,16 +355,13 @@ public class LocalDateTimeUtil {
* @return 格式化后的字符串
*/
public static String format(LocalDateTime time, String format) {
- if (null == time) {
- return null;
- }
- return format(time, DateTimeFormatter.ofPattern(format));
+ return TemporalAccessorUtil.format(time, format);
}
/**
* 格式化日期时间为yyyy-MM-dd格式
*
- * @param date {@link LocalDate}
+ * @param date {@link LocalDate}
* @return 格式化后的字符串
* @since 5.3.11
*/
@@ -478,8 +480,8 @@ public class LocalDateTimeUtil {
*
* @param temporalAccessor Date对象
* @return {@link Instant}对象
- * @since 5.4.1
* @see TemporalAccessorUtil#toEpochMilli(TemporalAccessor)
+ * @since 5.4.1
*/
public static long toEpochMilli(TemporalAccessor temporalAccessor) {
return TemporalAccessorUtil.toEpochMilli(temporalAccessor);
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/TemporalAccessorUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/TemporalAccessorUtil.java
index c2bca9c12..e6d33578a 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/TemporalAccessorUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/TemporalAccessorUtil.java
@@ -1,5 +1,6 @@
package cn.hutool.core.date;
+import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.StrUtil;
import java.time.Instant;
@@ -83,6 +84,11 @@ public class TemporalAccessorUtil extends TemporalUtil{
return null;
}
+ // 检查自定义格式
+ if(GlobalCustomFormat.isCustomFormat(format)){
+ return GlobalCustomFormat.format(time, format);
+ }
+
final DateTimeFormatter formatter = StrUtil.isBlank(format)
? null : DateTimeFormatter.ofPattern(format);
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java b/hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java
new file mode 100755
index 000000000..06ba30f00
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java
@@ -0,0 +1,119 @@
+package cn.hutool.core.date.format;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.lang.Assert;
+
+import java.time.temporal.TemporalAccessor;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+
+/**
+ * 全局自定义格式
+ * 用于定义用户指定的日期格式和输出日期的关系
+ *
+ * @author looly
+ * @since 5.7.2
+ */
+public class GlobalCustomFormat {
+
+ public static final String FORMAT_SECONDS = "#sss";
+ public static final String FORMAT_MILLISECONDS = "#SSS";
+
+ private static final Map> formatterMap;
+ private static final Map> parserMap;
+
+ static {
+ formatterMap = new ConcurrentHashMap<>();
+ parserMap = new ConcurrentHashMap<>();
+
+ // Hutool预设的几种自定义格式
+ putFormatter(FORMAT_SECONDS, (date) -> String.valueOf(Math.floorDiv(date.getTime(), 1000)));
+ putParser(FORMAT_SECONDS, (dateStr) -> DateUtil.date(Math.multiplyExact(Long.parseLong(dateStr.toString()), 1000)));
+
+ putFormatter(FORMAT_MILLISECONDS, (date) -> String.valueOf(date.getTime()));
+ putParser(FORMAT_MILLISECONDS, (dateStr) -> DateUtil.date(Long.parseLong(dateStr.toString())));
+ }
+
+ /**
+ * 加入日期格式化规则
+ *
+ * @param format 格式
+ * @param func 格式化函数
+ */
+ public static void putFormatter(String format, Function func) {
+ Assert.notNull(format, "Format must be not null !");
+ Assert.notNull(func, "Function must be not null !");
+ formatterMap.put(format, func);
+ }
+
+ /**
+ * 加入日期解析规则
+ *
+ * @param format 格式
+ * @param func 解析函数
+ */
+ public static void putParser(String format, Function func) {
+ Assert.notNull(format, "Format must be not null !");
+ Assert.notNull(func, "Function must be not null !");
+ parserMap.put(format, func);
+ }
+
+ /**
+ * 检查指定格式是否为自定义格式
+ *
+ * @param format 格式
+ * @return 是否为自定义格式
+ */
+ public static boolean isCustomFormat(String format) {
+ return formatterMap.containsKey(format);
+ }
+
+ /**
+ * 使用自定义格式格式化日期
+ *
+ * @param date 日期
+ * @param format 自定义格式
+ * @return 格式化后的日期
+ */
+ public static String format(Date date, CharSequence format) {
+ if (null != formatterMap) {
+ final Function func = formatterMap.get(format);
+ if (null != func) {
+ return func.apply(date);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * 使用自定义格式格式化日期
+ *
+ * @param temporalAccessor 日期
+ * @param format 自定义格式
+ * @return 格式化后的日期
+ */
+ public static String format(TemporalAccessor temporalAccessor, CharSequence format) {
+ return format(DateUtil.date(temporalAccessor), format);
+ }
+
+ /**
+ * 使用自定义格式解析日期
+ *
+ * @param dateStr 日期字符串
+ * @param format 自定义格式
+ * @return 格式化后的日期
+ */
+ public static Date parse(CharSequence dateStr, String format) {
+ if (null != parserMap) {
+ final Function func = parserMap.get(format);
+ if (null != func) {
+ return func.apply(dateStr);
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/JAXBUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/JAXBUtil.java
index 19101cd0e..024ddefd1 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/JAXBUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/JAXBUtil.java
@@ -62,6 +62,7 @@ public class JAXBUtil {
/**
* xml转换成JavaBean
*
+ * @param Bean类型
* @param xml XML字符串
* @param c Bean类型
* @return bean
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 6a8e29c02..1fdccbb56 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
@@ -72,6 +72,30 @@ public class DateUtilTest {
Assert.assertEquals("00:00:00", formatTime);
}
+ @Test
+ public void formatAndParseCustomTest() {
+ String dateStr = "2017-03-01";
+ Date date = DateUtil.parse(dateStr);
+
+ String format = DateUtil.format(date, "#sss");
+ Assert.assertEquals("1488297600", format);
+
+ final DateTime parse = DateUtil.parse(format, "#sss");
+ Assert.assertEquals(date, parse);
+ }
+
+ @Test
+ public void formatAndParseCustomTest2() {
+ String dateStr = "2017-03-01";
+ Date date = DateUtil.parse(dateStr);
+
+ String format = DateUtil.format(date, "#SSS");
+ Assert.assertEquals("1488297600000", format);
+
+ final DateTime parse = DateUtil.parse(format, "#SSS");
+ Assert.assertEquals(date, parse);
+ }
+
@Test
public void beginAndEndTest() {
String dateStr = "2017-03-01 00:33:23";
@@ -883,6 +907,6 @@ public class DateUtilTest {
public void parseNotFitTest(){
//https://github.com/looly/hutool/issues/1332
// 在日期格式不匹配的时候,测试是否正常报错
- final DateTime parse = DateUtil.parse("2020-12-23", DatePattern.PURE_DATE_PATTERN);
+ DateUtil.parse("2020-12-23", DatePattern.PURE_DATE_PATTERN);
}
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/date/TemporalAccessorUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/TemporalAccessorUtilTest.java
index ef2a296a0..0a9f97c61 100644
--- a/hutool-core/src/test/java/cn/hutool/core/date/TemporalAccessorUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/date/TemporalAccessorUtilTest.java
@@ -20,4 +20,15 @@ public class TemporalAccessorUtilTest {
final String format = TemporalAccessorUtil.format(LocalTime.MIN, DatePattern.NORM_DATETIME_PATTERN);
Assert.assertEquals(today + " 00:00:00", format);
}
+
+ @Test
+ public void formatCustomTest(){
+ final String today = TemporalAccessorUtil.format(
+ LocalDate.of(2021, 6, 26), "#sss");
+ Assert.assertEquals("1624636800", today);
+
+ final String today2 = TemporalAccessorUtil.format(
+ LocalDate.of(2021, 6, 26), "#SSS");
+ Assert.assertEquals("1624636800000", today2);
+ }
}
diff --git a/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java
index 8f4100c21..40d4e3a43 100644
--- a/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java
+++ b/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java
@@ -3,6 +3,7 @@ package cn.hutool.json;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TemporalAccessorUtil;
+import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -167,10 +168,6 @@ final class InternalJSONUtil {
try {
if (StrUtil.containsAnyIgnoreCase(string, ".", "e")) {
// pr#192@Gitee,Double会出现小数精度丢失问题,此处使用BigDecimal
- //double d = Double.parseDouble(string);
- //if (false == Double.isInfinite(d) && false == Double.isNaN(d)) {
- // return d;
- //}
return new BigDecimal(string);
} else {
final long myLong = Long.parseLong(string);
@@ -275,6 +272,12 @@ final class InternalJSONUtil {
} else{
dateStr = DateUtil.format(Convert.toDate(dateObj), format);
}
+
+ if(GlobalCustomFormat.FORMAT_SECONDS.equals(format)
+ || GlobalCustomFormat.FORMAT_MILLISECONDS.equals(format)){
+ // Hutool自定义的秒和毫秒表示,默认不包装双引号
+ return dateStr;
+ }
//用户定义了日期格式
return JSONUtil.quote(dateStr);
}
diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONGetter.java b/hutool-json/src/main/java/cn/hutool/json/JSONGetter.java
index 6d6337ad8..e1901bb41 100644
--- a/hutool-json/src/main/java/cn/hutool/json/JSONGetter.java
+++ b/hutool-json/src/main/java/cn/hutool/json/JSONGetter.java
@@ -113,21 +113,25 @@ public interface JSONGetter extends OptNullBasicTypeFromObjectGetter {
@Override
default Date getDate(K key, Date defaultValue){
+ // 默认转换
+ final Object obj = getObj(key);
+ if (null == obj) {
+ return defaultValue;
+ }
+ if(obj instanceof Date){
+ return (Date) obj;
+ }
+
String format = OptionalBean.ofNullable(getConfig()).getBean(JSONConfig::getDateFormat).get();
if(StrUtil.isNotBlank(format)){
// 用户指定了日期格式,获取日期属性时使用对应格式
- final String str = getStr(key);
+ final String str = Convert.toStr(obj);
if(null == str){
return defaultValue;
}
return DateUtil.parse(str, format);
}
- // 默认转换
- final Object obj = getObj(key);
- if (null == obj) {
- return defaultValue;
- }
return Convert.toDate(obj, defaultValue);
}
diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java
index 3161ab86f..2fb9d6373 100644
--- a/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java
+++ b/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java
@@ -450,6 +450,27 @@ public class JSONObjectTest {
Assert.assertEquals(DateUtil.beginOfDay(date), parse.getDate("date"));
}
+ @Test
+ public void setCustomDateFormatTest(){
+ JSONConfig jsonConfig = JSONConfig.create();
+ jsonConfig.setDateFormat("#sss");
+ jsonConfig.setOrder(true);
+
+ Date date = DateUtil.parse("2020-06-05 11:16:11");
+ JSONObject json = new JSONObject(jsonConfig);
+ json.set("date", date);
+ json.set("bbb", "222");
+ json.set("aaa", "123");
+
+ String jsonStr = "{\"date\":1591326971,\"bbb\":\"222\",\"aaa\":\"123\"}";
+
+ Assert.assertEquals(jsonStr, json.toString());
+
+ // 解析测试
+ final JSONObject parse = JSONUtil.parseObj(jsonStr, jsonConfig);
+ Assert.assertEquals(date, parse.getDate("date"));
+ }
+
@Test
public void getTimestampTest(){
String timeStr = "1970-01-01 00:00:00";
diff --git a/hutool-jwt/src/main/java/cn/hutool/jwt/Claims.java b/hutool-jwt/src/main/java/cn/hutool/jwt/Claims.java
index 7b851ce4c..0731a97ba 100644
--- a/hutool-jwt/src/main/java/cn/hutool/jwt/Claims.java
+++ b/hutool-jwt/src/main/java/cn/hutool/jwt/Claims.java
@@ -3,6 +3,7 @@ package cn.hutool.jwt;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
+import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
@@ -19,11 +20,9 @@ import java.util.Map;
public class Claims implements Serializable {
private static final long serialVersionUID = 1L;
- private JSONObject claimJSON;
+ private final JSONConfig CONFIG = JSONConfig.create().setDateFormat("#sss").setOrder(true);
- public Claims() {
- this.claimJSON = new JSONObject();
- }
+ private JSONObject claimJSON;
/**
* 增加Claims属性,如果属性值为{@code null},则移除这个属性
@@ -32,6 +31,7 @@ public class Claims implements Serializable {
* @param value 属性值
*/
protected void setClaim(String name, Object value) {
+ init();
Assert.notNull(name, "Name must be not null!");
if (value == null) {
claimJSON.remove(name);
@@ -59,6 +59,7 @@ public class Claims implements Serializable {
* @return 属性
*/
public Object getClaim(String name) {
+ init();
return this.claimJSON.getObj(name);
}
@@ -68,6 +69,7 @@ public class Claims implements Serializable {
* @return JSON字符串
*/
public JSONObject getClaimsJson() {
+ init();
return this.claimJSON;
}
@@ -78,11 +80,18 @@ public class Claims implements Serializable {
* @param charset 编码
*/
public void parse(String tokenPart, Charset charset) {
- this.claimJSON = JSONUtil.parseObj(Base64.decodeStr(tokenPart, charset));
+ this.claimJSON = JSONUtil.parseObj(Base64.decodeStr(tokenPart, charset), CONFIG);
}
@Override
public String toString() {
+ init();
return this.claimJSON.toString();
}
+
+ private void init(){
+ if(null == this.claimJSON){
+ this.claimJSON = new JSONObject(CONFIG);
+ }
+ }
}
diff --git a/hutool-jwt/src/test/java/cn/hutool/jwt/JWTSignerTest.java b/hutool-jwt/src/test/java/cn/hutool/jwt/JWTSignerTest.java
index 21205a9bf..02b60dbd3 100644
--- a/hutool-jwt/src/test/java/cn/hutool/jwt/JWTSignerTest.java
+++ b/hutool-jwt/src/test/java/cn/hutool/jwt/JWTSignerTest.java
@@ -1,5 +1,6 @@
package cn.hutool.jwt;
+import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.jwt.signers.AlgorithmUtil;
import cn.hutool.jwt.signers.JWTSigner;
@@ -113,6 +114,7 @@ public class JWTSignerTest {
.setPayload("sub", "1234567890")
.setPayload("name", "looly")
.setPayload("admin", true)
+ .setExpiresAt(DateUtil.tomorrow())
.setSigner(signer);
String token = jwt.sign();
diff --git a/hutool-jwt/src/test/java/cn/hutool/jwt/JWTTest.java b/hutool-jwt/src/test/java/cn/hutool/jwt/JWTTest.java
index 0ecef89f5..b3d34d6bd 100644
--- a/hutool-jwt/src/test/java/cn/hutool/jwt/JWTTest.java
+++ b/hutool-jwt/src/test/java/cn/hutool/jwt/JWTTest.java
@@ -1,5 +1,6 @@
package cn.hutool.jwt;
+import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.signers.JWTSignerUtil;
import org.junit.Assert;
@@ -14,11 +15,12 @@ public class JWTTest {
.setPayload("sub", "1234567890")
.setPayload("name", "looly")
.setPayload("admin", true)
+ .setPayload(RegisteredPayload.EXPIRES_AT, DateUtil.parse("2022-01-01"))
.setKey(key);
String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." +
- "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9." +
- "U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA";
+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxvb2x5IiwiYWRtaW4iOnRydWUsImV4cCI6IjE2NDA5NjY0MDAifQ." +
+ "c9qo9Z9vdN2gulvOEReU9iEi0bqgyVqjaNKbP1DmTL4";
String token = jwt.sign();
Assert.assertEquals(token, rightToken);