mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add /GlobalCustomFormat
This commit is contained in:
parent
85e9bc11c2
commit
613b6f3ac5
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
119
hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java
Executable file
119
hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java
Executable file
@ -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;
|
||||
|
||||
/**
|
||||
* 全局自定义格式<br>
|
||||
* 用于定义用户指定的日期格式和输出日期的关系
|
||||
*
|
||||
* @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<CharSequence, Function<Date, String>> formatterMap;
|
||||
private static final Map<CharSequence, Function<CharSequence, Date>> 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<Date, String> 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<CharSequence, Date> 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<Date, String> 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<CharSequence, Date> func = parserMap.get(format);
|
||||
if (null != func) {
|
||||
return func.apply(dateStr);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -62,6 +62,7 @@ public class JAXBUtil {
|
||||
/**
|
||||
* xml转换成JavaBean
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param xml XML字符串
|
||||
* @param c Bean类型
|
||||
* @return bean
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -113,21 +113,25 @@ public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user