From b38f40a6a392b6c7afed1c2b4465d9d52d327308 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 9 Jul 2021 20:11:25 +0800 Subject: [PATCH] add os version and methods --- CHANGELOG.md | 6 +- .../hutool/core/collection/CollUtilTest.java | 17 ++- .../java/cn/hutool/core/util/XmlUtilTest.java | 11 ++ .../cn/hutool/http/useragent/Browser.java | 38 ++++++- .../java/cn/hutool/http/useragent/Engine.java | 11 +- .../java/cn/hutool/http/useragent/OS.java | 107 +++++++++++++----- .../cn/hutool/http/useragent/Platform.java | 5 +- .../cn/hutool/http/useragent/UserAgent.java | 96 +++++++++++----- .../hutool/http/useragent/UserAgentInfo.java | 18 +-- .../http/useragent/UserAgentParser.java | 8 +- .../hutool/http/useragent/UserAgentUtil.java | 1 - .../http/useragent/UserAgentUtilTest.java | 16 +++ .../src/main/java/cn/hutool/jwt/JWT.java | 37 +++++- 13 files changed, 285 insertions(+), 86 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a7707cbf..465713eb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.7.4 (2021-07-08) +# 5.7.4 (2021-07-09) ### 🐣新特性 * 【crypto 】 SmUtil.sm4统一返回类型(issue#I3YKD4@Gitee) @@ -11,8 +11,10 @@ * 【core 】 HexUtil增加hexToLong、hexToInt(issue#I3YQEV@Gitee) * 【core 】 CsvWriter增加writer.write(csvData)的方法重载(pr#353@Gitee) * 【core 】 新增AbsCollValueMap(issue#I3YXF0@Gitee) -* 【crypto 】 HOPT缓存改为8位,新增方法(pr#356@Gitee) +* 【crypto 】 HOTP缓存改为8位,新增方法(pr#356@Gitee) * 【setting】 Props增加toProperties方法(issue#1701@Github) +* 【http 】 UserAgent增加getOsVersion方法(issue#I3YZUQ@Gitee) +* 【jwt 】 JWT增加validate方法(issue#I3YDM4@Gitee) ### 🐞Bug修复 * 【core 】 修复RadixUtil.decode非static问题(issue#I3YPEH@Gitee) diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java index 76b6474b4..5a015e08b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java @@ -343,7 +343,8 @@ public class CollUtilTest { @Test public void sortByPropertyTest() { - List list = CollUtil.newArrayList(new TestBean("张三", 12, DateUtil.parse("2018-05-01")), // + List list = CollUtil.newArrayList( + new TestBean("张三", 12, DateUtil.parse("2018-05-01")), // new TestBean("李四", 13, DateUtil.parse("2018-03-01")), // new TestBean("王五", 12, DateUtil.parse("2018-04-01"))// ); @@ -354,6 +355,20 @@ public class CollUtilTest { Assert.assertEquals("张三", list.get(2).getName()); } + @Test + public void sortByPropertyTest2() { + List list = CollUtil.newArrayList( + new TestBean("张三", 0, DateUtil.parse("2018-05-01")), // + new TestBean("李四", -12, DateUtil.parse("2018-03-01")), // + new TestBean("王五", 23, DateUtil.parse("2018-04-01"))// + ); + + CollUtil.sortByProperty(list, "age"); + Assert.assertEquals("李四", list.get(0).getName()); + Assert.assertEquals("张三", list.get(1).getName()); + Assert.assertEquals("王五", list.get(2).getName()); + } + @Test public void fieldValueMapTest() { List list = CollUtil.newArrayList(new TestBean("张三", 12, DateUtil.parse("2018-05-01")), // diff --git a/hutool-core/src/test/java/cn/hutool/core/util/XmlUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/XmlUtilTest.java index 30015eec3..eb90e3e21 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/XmlUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/XmlUtilTest.java @@ -293,4 +293,15 @@ public class XmlUtilTest { final String escape = XmlUtil.escape(a); Console.log(escape); } + + @Test + public void getParamTest(){ + String xml = "\n" + + " 222222\n" + + ""; + + final Document doc = XmlUtil.parseXml(xml); + final String name = doc.getDocumentElement().getAttribute("name"); + Assert.assertEquals("aaaa", name); + } } diff --git a/hutool-http/src/main/java/cn/hutool/http/useragent/Browser.java b/hutool-http/src/main/java/cn/hutool/http/useragent/Browser.java index c6ab83069..570ccc20d 100644 --- a/hutool-http/src/main/java/cn/hutool/http/useragent/Browser.java +++ b/hutool-http/src/main/java/cn/hutool/http/useragent/Browser.java @@ -13,10 +13,15 @@ import java.util.regex.Pattern; * @since 4.2.1 */ public class Browser extends UserAgentInfo { + private static final long serialVersionUID = 1L; - /** 未知 */ + /** + * 未知 + */ public static final Browser Unknown = new Browser(NameUnknown, null, null); - /** 其它版本 */ + /** + * 其它版本 + */ public static final String Other_Version = "[\\/ ]([\\d\\w\\.\\-]+)"; /** @@ -56,14 +61,25 @@ public class Browser extends UserAgentInfo { new Browser("DingTalk", "DingTalk", "AliApp\\(DingTalk\\/([\\d\\w\\.\\-]+)\\)") ); - private Pattern versionPattern; + /** + * 添加自定义的浏览器类型 + * + * @param name 浏览器名称 + * @param regex 关键字或表达式 + * @param versionRegex 匹配版本的正则 + * @since 5.7.4 + */ + synchronized public static void addCustomBrowser(String name, String regex, String versionRegex) { + browers.add(new Browser(name, regex, versionRegex)); + } + private Pattern versionPattern; /** * 构造 * - * @param name 浏览器名称 - * @param regex 关键字或表达式 + * @param name 浏览器名称 + * @param regex 关键字或表达式 * @param versionRegex 匹配版本的正则 */ public Browser(String name, String regex, String versionRegex) { @@ -83,6 +99,9 @@ public class Browser extends UserAgentInfo { * @return 版本 */ public String getVersion(String userAgentString) { + if(isUnknown()){ + return null; + } return ReUtil.getGroup1(this.versionPattern, userAgentString); } @@ -92,6 +111,13 @@ public class Browser extends UserAgentInfo { * @return 是否移动浏览器 */ public boolean isMobile() { - return "PSP".equals(this.getName()); + final String name = this.getName(); + return "PSP".equals(name) || + "Yammer Mobile".equals(name) || + "Android Browser".equals(name) || + "IEMobile".equals(name) || + "MicroMessenger".equals(name) || + "miniProgram".equals(name) || + "DingTalk".equals(name); } } diff --git a/hutool-http/src/main/java/cn/hutool/http/useragent/Engine.java b/hutool-http/src/main/java/cn/hutool/http/useragent/Engine.java index ab135018b..ed6e57b2d 100644 --- a/hutool-http/src/main/java/cn/hutool/http/useragent/Engine.java +++ b/hutool-http/src/main/java/cn/hutool/http/useragent/Engine.java @@ -13,6 +13,7 @@ import java.util.regex.Pattern; * @since 4.2.1 */ public class Engine extends UserAgentInfo { + private static final long serialVersionUID = 1L; /** 未知 */ public static final Engine Unknown = new Engine(NameUnknown, null); @@ -32,6 +33,8 @@ public class Engine extends UserAgentInfo { new Engine("MIDP", "MIDP")// ); + private final Pattern versionPattern; + /** * 构造 * @@ -40,6 +43,7 @@ public class Engine extends UserAgentInfo { */ public Engine(String name, String regex) { super(name, regex); + this.versionPattern = Pattern.compile(name + "[/\\- ]([\\d\\w.\\-]+)", Pattern.CASE_INSENSITIVE); } /** @@ -50,8 +54,9 @@ public class Engine extends UserAgentInfo { * @since 5.7.4 */ public String getVersion(String userAgentString) { - final String regexp = getName() + "[/\\- ]([\\d\\w.\\-]+)"; - final Pattern pattern = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE); - return ReUtil.getGroup1(pattern, userAgentString); + if(isUnknown()){ + return null; + } + return ReUtil.getGroup1(this.versionPattern, userAgentString); } } diff --git a/hutool-http/src/main/java/cn/hutool/http/useragent/OS.java b/hutool-http/src/main/java/cn/hutool/http/useragent/OS.java index 14b380b9d..2e6bb9f0f 100644 --- a/hutool-http/src/main/java/cn/hutool/http/useragent/OS.java +++ b/hutool-http/src/main/java/cn/hutool/http/useragent/OS.java @@ -1,59 +1,106 @@ package cn.hutool.http.useragent; -import java.util.List; - import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ReUtil; + +import java.util.List; +import java.util.regex.Pattern; /** * 系统对象 - * + * * @author looly * @since 4.2.1 */ public class OS extends UserAgentInfo { - - /** 未知 */ + private static final long serialVersionUID = 1L; + + /** + * 未知 + */ public static final OS Unknown = new OS(NameUnknown, null); /** * 支持的引擎类型 */ public static final List oses = CollUtil.newArrayList(// - new OS("Windows 10 or Windows Server 2016","windows nt 10\\.0"),// - new OS("Windows 8.1 or Winsows Server 2012R2","windows nt 6\\.3"),// - new OS("Windows 8 or Winsows Server 2012","windows nt 6\\.2"),// - new OS("Windows Vista", "windows nt 6\\.0"), // - new OS("Windows 7 or Windows Server 2008R2", "windows nt 6\\.1"), // - new OS("Windows 2003", "windows nt 5\\.2"), // - new OS("Windows XP", "windows nt 5\\.1"), // - new OS("Windows 2000", "windows nt 5\\.0"), // - new OS("Windows Phone", "windows (ce|phone|mobile)( os)?"), // + new OS("Windows 10 or Windows Server 2016", "windows nt 10\\.0", "windows nt (10\\.0)"),// + new OS("Windows 8.1 or Winsows Server 2012R2", "windows nt 6\\.3", "windows nt (6\\.3)"),// + new OS("Windows 8 or Winsows Server 2012", "windows nt 6\\.2", "windows nt (6\\.2)"),// + new OS("Windows Vista", "windows nt 6\\.0", "windows nt (6\\.0)"), // + new OS("Windows 7 or Windows Server 2008R2", "windows nt 6\\.1", "windows nt (6\\.1)"), // + new OS("Windows 2003", "windows nt 5\\.2", "windows nt (5\\.2)"), // + new OS("Windows XP", "windows nt 5\\.1", "windows nt (5\\.1)"), // + new OS("Windows 2000", "windows nt 5\\.0", "windows nt (5\\.0)"), // + new OS("Windows Phone", "windows (ce|phone|mobile)( os)?", "windows (?:ce|phone|mobile) (\\d+([._]\\d+)*)"), // new OS("Windows", "windows"), // - new OS("OSX", "os x (\\d+)[._](\\d+)"), // - new OS("Android","Android"),// + new OS("OSX", "os x (\\d+)[._](\\d+)", "os x (\\d+([._]\\d+)*)"), // + new OS("Android", "Android", "Android (\\d+([._]\\d+)*)"),// new OS("Linux", "linux"), // - new OS("Wii", "wii"), // - new OS("PS3", "playstation 3"), // - new OS("PSP", "playstation portable"), // - new OS("iPad", "\\(iPad.*os (\\d+)[._](\\d+)"), // - new OS("iPhone", "\\(iPhone.*os (\\d+)[._](\\d+)"), // - new OS("YPod", "iPod touch[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)"), // - new OS("YPad", "iPad[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)"), // - new OS("YPhone", "iPhone[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)"), // + new OS("Wii", "wii", "wii libnup/(\\d+([._]\\d+)*)"), // + new OS("PS3", "playstation 3", "playstation 3; (\\d+([._]\\d+)*)"), // + new OS("PSP", "playstation portable", "Portable\\); (\\d+([._]\\d+)*)"), // + new OS("iPad", "\\(iPad.*os (\\d+)[._](\\d+)", "\\(iPad.*os (\\d+([._]\\d+)*)"), // + new OS("iPhone", "\\(iPhone.*os (\\d+)[._](\\d+)", "\\(iPhone.*os (\\d+([._]\\d+)*)"), // + new OS("YPod", "iPod touch[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)", "iPod touch[\\s\\;]+iPhone.*os (\\d+([._]\\d+)*)"), // + new OS("YPad", "iPad[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)", "iPad[\\s\\;]+iPhone.*os (\\d+([._]\\d+)*)"), // + new OS("YPhone", "iPhone[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)", "iPhone[\\s\\;]+iPhone.*os (\\d+([._]\\d+)*)"), // new OS("Symbian", "symbian(os)?"), // - new OS("Darwin", "Darwin\\/([\\d\\w\\.\\-]+)"), // - new OS("Adobe Air", "AdobeAir\\/([\\d\\w\\.\\-]+)"), // - new OS("Java", "Java[\\s]+([\\d\\w\\.\\-]+)")// + new OS("Darwin", "Darwin\\/([\\d\\w\\.\\-]+)", "Darwin\\/([\\d\\w\\.\\-]+)"), // + new OS("Adobe Air", "AdobeAir\\/([\\d\\w\\.\\-]+)", "AdobeAir\\/([\\d\\w\\.\\-]+)"), // + new OS("Java", "Java[\\s]+([\\d\\w\\.\\-]+)", "Java[\\s]+([\\d\\w\\.\\-]+)")// ); + /** + * 添加自定义的系统类型 + * + * @param name 浏览器名称 + * @param regex 关键字或表达式 + * @param versionRegex 匹配版本的正则 + * @since 5.7.4 + */ + synchronized public static void addCustomOs(String name, String regex, String versionRegex) { + oses.add(new OS(name, regex, versionRegex)); + } + + private Pattern versionPattern; + /** * 构造 - * - * @param name 系统名称 + * + * @param name 系统名称 * @param regex 关键字或表达式 */ public OS(String name, String regex) { - super(name, regex); + this(name, regex, null); } + /** + * 构造 + * + * @param name 系统名称 + * @param regex 关键字或表达式 + * @param versionRegex 版本正则表达式 + * @since 5.7.4 + */ + public OS(String name, String regex, String versionRegex) { + super(name, regex); + if (null != versionRegex) { + this.versionPattern = Pattern.compile(versionRegex, Pattern.CASE_INSENSITIVE); + } + } + + /** + * 获取浏览器版本 + * + * @param userAgentString User-Agent字符串 + * @return 版本 + */ + public String getVersion(String userAgentString) { + if(isUnknown() || null == this.versionPattern){ + // 无版本信息 + return null; + } + return ReUtil.getGroup1(this.versionPattern, userAgentString); + } } diff --git a/hutool-http/src/main/java/cn/hutool/http/useragent/Platform.java b/hutool-http/src/main/java/cn/hutool/http/useragent/Platform.java index 70956ae4c..71d46033c 100644 --- a/hutool-http/src/main/java/cn/hutool/http/useragent/Platform.java +++ b/hutool-http/src/main/java/cn/hutool/http/useragent/Platform.java @@ -1,10 +1,10 @@ package cn.hutool.http.useragent; +import cn.hutool.core.collection.CollUtil; + import java.util.ArrayList; import java.util.List; -import cn.hutool.core.collection.CollUtil; - /** * 平台对象 * @@ -12,6 +12,7 @@ import cn.hutool.core.collection.CollUtil; * @since 4.2.1 */ public class Platform extends UserAgentInfo { + private static final long serialVersionUID = 1L; /** * 未知 diff --git a/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgent.java b/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgent.java index 891237b5a..6d9e961ec 100644 --- a/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgent.java +++ b/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgent.java @@ -1,31 +1,55 @@ package cn.hutool.http.useragent; +import java.io.Serializable; + /** * User-Agent信息对象 - * + * * @author looly * @since 4.2.1 */ -public class UserAgent { +public class UserAgent implements Serializable { + private static final long serialVersionUID = 1L; - /** 是否为移动平台 */ + /** + * 是否为移动平台 + */ private boolean mobile; - /** 浏览器类型 */ + /** + * 浏览器类型 + */ private Browser browser; - /** 平台类型 */ - private Platform platform; - /** 系统类型 */ - private OS os; - /** 引擎类型 */ - private Engine engine; - /** 浏览器版本 */ + /** + * 浏览器版本 + */ private String version; - /** 引擎版本 */ + + /** + * 平台类型 + */ + private Platform platform; + + /** + * 系统类型 + */ + private OS os; + /** + * 系统版本 + */ + private String osVersion; + + /** + * 引擎类型 + */ + private Engine engine; + /** + * 引擎版本 + */ private String engineVersion; /** * 是否为移动平台 - * + * * @return 是否为移动平台 */ public boolean isMobile() { @@ -34,7 +58,7 @@ public class UserAgent { /** * 设置是否为移动平台 - * + * * @param mobile 是否为移动平台 */ public void setMobile(boolean mobile) { @@ -43,7 +67,7 @@ public class UserAgent { /** * 获取浏览器类型 - * + * * @return 浏览器类型 */ public Browser getBrowser() { @@ -52,7 +76,7 @@ public class UserAgent { /** * 设置浏览器类型 - * + * * @param browser 浏览器类型 */ public void setBrowser(Browser browser) { @@ -61,7 +85,7 @@ public class UserAgent { /** * 获取平台类型 - * + * * @return 平台类型 */ public Platform getPlatform() { @@ -70,7 +94,7 @@ public class UserAgent { /** * 设置平台类型 - * + * * @param platform 平台类型 */ public void setPlatform(Platform platform) { @@ -79,7 +103,7 @@ public class UserAgent { /** * 获取系统类型 - * + * * @return 系统类型 */ public OS getOs() { @@ -88,16 +112,36 @@ public class UserAgent { /** * 设置系统类型 - * + * * @param os 系统类型 */ public void setOs(OS os) { this.os = os; } + /** + * 获取系统版本 + * + * @return 系统版本 + * @since 5.7.4 + */ + public String getOsVersion() { + return this.osVersion; + } + + /** + * 设置系统版本 + * + * @param osVersion 系统版本 + * @since 5.7.4 + */ + public void setOsVersion(String osVersion) { + this.osVersion = osVersion; + } + /** * 获取引擎类型 - * + * * @return 引擎类型 */ public Engine getEngine() { @@ -106,7 +150,7 @@ public class UserAgent { /** * 设置引擎类型 - * + * * @param engine 引擎类型 */ public void setEngine(Engine engine) { @@ -115,7 +159,7 @@ public class UserAgent { /** * 获取浏览器版本 - * + * * @return 浏览器版本 */ public String getVersion() { @@ -124,7 +168,7 @@ public class UserAgent { /** * 设置浏览器版本 - * + * * @param version 浏览器版本 */ public void setVersion(String version) { @@ -133,7 +177,7 @@ public class UserAgent { /** * 获取引擎版本 - * + * * @return 引擎版本 */ public String getEngineVersion() { @@ -142,7 +186,7 @@ public class UserAgent { /** * 设置引擎版本 - * + * * @param engineVersion 引擎版本 */ public void setEngineVersion(String engineVersion) { diff --git a/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentInfo.java b/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentInfo.java index 391367b3f..c77ccbb8b 100644 --- a/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentInfo.java +++ b/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentInfo.java @@ -2,15 +2,17 @@ package cn.hutool.http.useragent; import cn.hutool.core.util.ReUtil; +import java.io.Serializable; import java.util.regex.Pattern; /** * User-agent信息 - * + * * @author looly * @since 4.2.1 */ -public class UserAgentInfo { +public class UserAgentInfo implements Serializable { + private static final long serialVersionUID = 1L; public static final String NameUnknown = "Unknown"; @@ -21,7 +23,7 @@ public class UserAgentInfo { /** * 构造 - * + * * @param name 名字 * @param regex 表达式 */ @@ -31,7 +33,7 @@ public class UserAgentInfo { /** * 构造 - * + * * @param name 名字 * @param pattern 匹配模式 */ @@ -42,7 +44,7 @@ public class UserAgentInfo { /** * 获取信息名称 - * + * * @return 信息名称 */ public String getName() { @@ -51,7 +53,7 @@ public class UserAgentInfo { /** * 获取匹配模式 - * + * * @return 匹配模式 */ public Pattern getPattern() { @@ -60,7 +62,7 @@ public class UserAgentInfo { /** * 指定内容中是否包含匹配此信息的内容 - * + * * @param content User-Agent字符串 * @return 是否包含匹配此信息的内容 */ @@ -70,7 +72,7 @@ public class UserAgentInfo { /** * 是否为Unknown - * + * * @return 是否为Unknown */ public boolean isUnknown() { diff --git a/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentParser.java b/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentParser.java index 6a083741a..d0f2a7fc3 100644 --- a/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentParser.java +++ b/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentParser.java @@ -30,12 +30,12 @@ public class UserAgentParser { // 浏览器引擎 final Engine engine = parseEngine(userAgentString); userAgent.setEngine(engine); - if (false == engine.isUnknown()) { - userAgent.setEngineVersion(engine.getVersion(userAgentString)); - } + userAgent.setEngineVersion(engine.getVersion(userAgentString)); // 操作系统 - userAgent.setOs(parseOS(userAgentString)); + final OS os = parseOS(userAgentString); + userAgent.setOs(os); + userAgent.setOsVersion(os.getVersion(userAgentString)); // 平台 final Platform platform = parsePlatform(userAgentString); diff --git a/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentUtil.java b/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentUtil.java index de4153478..d6f04bbda 100644 --- a/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentUtil.java +++ b/hutool-http/src/main/java/cn/hutool/http/useragent/UserAgentUtil.java @@ -18,5 +18,4 @@ public class UserAgentUtil { return UserAgentParser.parse(userAgentString); } - } diff --git a/hutool-http/src/test/java/cn/hutool/http/useragent/UserAgentUtilTest.java b/hutool-http/src/test/java/cn/hutool/http/useragent/UserAgentUtilTest.java index a20c60fb0..143bc0063 100644 --- a/hutool-http/src/test/java/cn/hutool/http/useragent/UserAgentUtilTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/useragent/UserAgentUtilTest.java @@ -15,6 +15,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("535.1", ua.getEngineVersion()); Assert.assertEquals("Windows 7 or Windows Server 2008R2", ua.getOs().toString()); + Assert.assertEquals("6.1", ua.getOsVersion()); Assert.assertEquals("Windows", ua.getPlatform().toString()); Assert.assertFalse(ua.isMobile()); } @@ -29,6 +30,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("533.17.9", ua.getEngineVersion()); Assert.assertEquals("iPhone", ua.getOs().toString()); + Assert.assertEquals("4_3_3", ua.getOsVersion()); Assert.assertEquals("iPhone", ua.getPlatform().toString()); Assert.assertTrue(ua.isMobile()); } @@ -42,6 +44,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("537.36", ua.getEngineVersion()); Assert.assertEquals("Android", ua.getOs().toString()); + Assert.assertEquals("9", ua.getOsVersion()); Assert.assertEquals("Android", ua.getPlatform().toString()); Assert.assertTrue(ua.isMobile()); } @@ -55,6 +58,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("537.36", ua.getEngineVersion()); Assert.assertEquals("Android", ua.getOs().toString()); + Assert.assertEquals("10", ua.getOsVersion()); Assert.assertEquals("Android", ua.getPlatform().toString()); Assert.assertTrue(ua.isMobile()); } @@ -68,6 +72,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Unknown", ua.getEngine().toString()); Assert.assertNull(ua.getEngineVersion()); Assert.assertEquals("Android", ua.getOs().toString()); + Assert.assertEquals("9", ua.getOsVersion()); Assert.assertEquals("Android", ua.getPlatform().toString()); Assert.assertTrue(ua.isMobile()); } @@ -81,6 +86,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("537.36", ua.getEngineVersion()); Assert.assertEquals("Windows 10 or Windows Server 2016", ua.getOs().toString()); + Assert.assertEquals("10.0", ua.getOsVersion()); Assert.assertEquals("Windows", ua.getPlatform().toString()); Assert.assertFalse(ua.isMobile()); } @@ -94,6 +100,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Trident", ua.getEngine().toString()); Assert.assertEquals("7.0", ua.getEngineVersion()); Assert.assertEquals("Windows 10 or Windows Server 2016", ua.getOs().toString()); + Assert.assertEquals("10.0", ua.getOsVersion()); Assert.assertEquals("Windows", ua.getPlatform().toString()); Assert.assertFalse(ua.isMobile()); } @@ -107,6 +114,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Trident", ua.getEngine().toString()); Assert.assertEquals("7.0", ua.getEngineVersion()); Assert.assertEquals("Windows Phone", ua.getOs().toString()); + Assert.assertEquals("8.1", ua.getOsVersion()); Assert.assertEquals("Windows Phone", ua.getPlatform().toString()); Assert.assertTrue(ua.isMobile()); } @@ -120,6 +128,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Trident", ua.getEngine().toString()); Assert.assertEquals("4.0", ua.getEngineVersion()); Assert.assertEquals("Windows 7 or Windows Server 2008R2", ua.getOs().toString()); + Assert.assertEquals("6.1", ua.getOsVersion()); Assert.assertEquals("Windows", ua.getPlatform().toString()); Assert.assertFalse(ua.isMobile()); } @@ -133,6 +142,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("537.36", ua.getEngineVersion()); Assert.assertEquals("Windows 10 or Windows Server 2016", ua.getOs().toString()); + Assert.assertEquals("10.0", ua.getOsVersion()); Assert.assertEquals("Windows", ua.getPlatform().toString()); Assert.assertFalse(ua.isMobile()); } @@ -146,6 +156,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("537.36", ua.getEngineVersion()); Assert.assertEquals("Windows Phone", ua.getOs().toString()); + Assert.assertEquals("10.0", ua.getOsVersion()); Assert.assertEquals("Windows Phone", ua.getPlatform().toString()); Assert.assertTrue(ua.isMobile()); } @@ -159,6 +170,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("537.36", ua.getEngineVersion()); Assert.assertEquals("Windows 8.1 or Winsows Server 2012R2", ua.getOs().toString()); + Assert.assertEquals("6.3", ua.getOsVersion()); Assert.assertEquals("Windows", ua.getPlatform().toString()); Assert.assertFalse(ua.isMobile()); } @@ -172,6 +184,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Trident", ua.getEngine().toString()); Assert.assertEquals("7.0", ua.getEngineVersion()); Assert.assertEquals("Windows 7 or Windows Server 2008R2", ua.getOs().toString()); + Assert.assertEquals("6.1", ua.getOsVersion()); Assert.assertEquals("Windows", ua.getPlatform().toString()); Assert.assertFalse(ua.isMobile()); } @@ -185,6 +198,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("537.36", ua.getEngineVersion()); Assert.assertEquals("Windows 10 or Windows Server 2016", ua.getOs().toString()); + Assert.assertEquals("10.0", ua.getOsVersion()); Assert.assertEquals("Windows", ua.getPlatform().toString()); Assert.assertFalse(ua.isMobile()); } @@ -201,6 +215,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("604.1.38", ua.getEngineVersion()); Assert.assertEquals("iPhone", ua.getOs().toString()); + Assert.assertEquals("11_0", ua.getOsVersion()); Assert.assertEquals("iPhone", ua.getPlatform().toString()); Assert.assertTrue(ua.isMobile()); } @@ -227,6 +242,7 @@ public class UserAgentUtilTest { Assert.assertEquals("Webkit", ua.getEngine().toString()); Assert.assertEquals("605.1.15", ua.getEngineVersion()); Assert.assertEquals("iPhone", ua.getOs().toString()); + Assert.assertEquals("14_0", ua.getOsVersion()); Assert.assertEquals("iPhone", ua.getPlatform().toString()); Assert.assertTrue(ua.isMobile()); } diff --git a/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java b/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java index 40c4aea79..88c479d2e 100644 --- a/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java +++ b/hutool-jwt/src/main/java/cn/hutool/jwt/JWT.java @@ -2,6 +2,8 @@ package cn.hutool.jwt; import cn.hutool.core.codec.Base64; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.exceptions.ValidateException; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.CharsetUtil; @@ -35,7 +37,7 @@ import java.util.Map; * @author looly * @since 5.7.0 */ -public class JWT implements RegisteredPayload{ +public class JWT implements RegisteredPayload { private final JWTHeader header; private final JWTPayload payload; @@ -169,7 +171,7 @@ public class JWT implements RegisteredPayload{ * * @return JWT算法签名器 */ - public JWTSigner getSigner(){ + public JWTSigner getSigner() { return this.signer; } @@ -329,6 +331,35 @@ public class JWT implements RegisteredPayload{ return verify(this.signer); } + /** + * 验证JWT是否有效,验证包括: + * + *
    + *
  • Token是否正确
  • + *
  • {@link JWTPayload#NOT_BEFORE}:生效时间不能晚于当前时间
  • + *
  • {@link JWTPayload#EXPIRES_AT}:失效时间不能早于当前时间
  • + *
  • {@link JWTPayload#ISSUED_AT}: 签发时间不能晚于当前时间
  • + *
+ * + * @return 是否有效 + * @see JWTValidator + * @since 5.7.4 + */ + public boolean validate(long leeway) { + if (false == verify()) { + return false; + } + + // 校验时间字段 + try { + JWTValidator.of(tokens.get(2)).validateDate(DateUtil.date(), leeway); + } catch (ValidateException e) { + return false; + } + + return true; + } + /** * 验证JWT Token是否有效 * @@ -336,7 +367,7 @@ public class JWT implements RegisteredPayload{ * @return 是否有效 */ public boolean verify(JWTSigner signer) { - if(null == signer){ + if (null == signer) { // 如果无签名器提供,默认认为是无签名JWT信息 signer = NoneJWTSigner.NONE; }