!196 StringBuffer替换为为StringBuilder

Merge pull request !196 from z.h.z/dev
This commit is contained in:
孔明 2022-11-19 13:57:33 +00:00 committed by Gitee
commit 6b8dcbc42f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 226 additions and 229 deletions

View File

@ -10,86 +10,86 @@ import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.util.SaFoxUtil; import cn.dev33.satoken.util.SaFoxUtil;
/** /**
* Cookie Model * Cookie Model
* @author kong * @author kong
* *
*/ */
public class SaCookie { public class SaCookie {
/** /**
* 写入响应头时使用的key * 写入响应头时使用的key
*/ */
public static final String HEADER_NAME = "Set-Cookie"; public static final String HEADER_NAME = "Set-Cookie";
/** /**
* 名称 * 名称
*/ */
private String name; private String name;
/** /**
* *
*/ */
private String value; private String value;
/** /**
* 有效时长 单位-1代表为临时Cookie 浏览器关闭后自动删除 * 有效时长 单位-1代表为临时Cookie 浏览器关闭后自动删除
*/ */
private int maxAge = -1; private int maxAge = -1;
/** /**
* *
*/ */
private String domain; private String domain;
/** /**
* 路径 * 路径
*/ */
private String path; private String path;
/** /**
* 是否只在 https 协议下有效 * 是否只在 https 协议下有效
*/ */
private Boolean secure = false; private Boolean secure = false;
/** /**
* 是否禁止 js 操作 Cookie * 是否禁止 js 操作 Cookie
*/ */
private Boolean httpOnly = false; private Boolean httpOnly = false;
/** /**
* 第三方限制级别Strict=完全禁止Lax=部分允许None=不限制 * 第三方限制级别Strict=完全禁止Lax=部分允许None=不限制
*/ */
private String sameSite; private String sameSite;
/** /**
* 构造一个 * 构造一个
*/ */
public SaCookie() { public SaCookie() {
} }
/** /**
* 构造一个 * 构造一个
* @param name 名字 * @param name 名字
* @param value * @param value
*/ */
public SaCookie(String name, String value) { public SaCookie(String name, String value) {
this.name = name; this.name = name;
this.value = value; this.value = value;
} }
/** /**
* @return 名称 * @return 名称
*/ */
public String getName() { public String getName() {
return name; return name;
} }
/** /**
* @param name 名称 * @param name 名称
* @return 对象自身 * @return 对象自身
*/ */
public SaCookie setName(String name) { public SaCookie setName(String name) {
this.name = name; this.name = name;
@ -97,15 +97,15 @@ public class SaCookie {
} }
/** /**
* @return * @return
*/ */
public String getValue() { public String getValue() {
return value; return value;
} }
/** /**
* @param value * @param value
* @return 对象自身 * @return 对象自身
*/ */
public SaCookie setValue(String value) { public SaCookie setValue(String value) {
this.value = value; this.value = value;
@ -113,15 +113,15 @@ public class SaCookie {
} }
/** /**
* @return 有效时长 单位-1代表为临时Cookie 浏览器关闭后自动删除 * @return 有效时长 单位-1代表为临时Cookie 浏览器关闭后自动删除
*/ */
public int getMaxAge() { public int getMaxAge() {
return maxAge; return maxAge;
} }
/** /**
* @param maxAge 有效时长 单位-1代表为临时Cookie 浏览器关闭后自动删除 * @param maxAge 有效时长 单位-1代表为临时Cookie 浏览器关闭后自动删除
* @return 对象自身 * @return 对象自身
*/ */
public SaCookie setMaxAge(int maxAge) { public SaCookie setMaxAge(int maxAge) {
this.maxAge = maxAge; this.maxAge = maxAge;
@ -129,15 +129,15 @@ public class SaCookie {
} }
/** /**
* @return * @return
*/ */
public String getDomain() { public String getDomain() {
return domain; return domain;
} }
/** /**
* @param domain * @param domain
* @return 对象自身 * @return 对象自身
*/ */
public SaCookie setDomain(String domain) { public SaCookie setDomain(String domain) {
this.domain = domain; this.domain = domain;
@ -145,15 +145,15 @@ public class SaCookie {
} }
/** /**
* @return 路径 * @return 路径
*/ */
public String getPath() { public String getPath() {
return path; return path;
} }
/** /**
* @param path 路径 * @param path 路径
* @return 对象自身 * @return 对象自身
*/ */
public SaCookie setPath(String path) { public SaCookie setPath(String path) {
this.path = path; this.path = path;
@ -161,15 +161,15 @@ public class SaCookie {
} }
/** /**
* @return 是否只在 https 协议下有效 * @return 是否只在 https 协议下有效
*/ */
public Boolean getSecure() { public Boolean getSecure() {
return secure; return secure;
} }
/** /**
* @param secure 是否只在 https 协议下有效 * @param secure 是否只在 https 协议下有效
* @return 对象自身 * @return 对象自身
*/ */
public SaCookie setSecure(Boolean secure) { public SaCookie setSecure(Boolean secure) {
this.secure = secure; this.secure = secure;
@ -177,15 +177,15 @@ public class SaCookie {
} }
/** /**
* @return 是否禁止 js 操作 Cookie * @return 是否禁止 js 操作 Cookie
*/ */
public Boolean getHttpOnly() { public Boolean getHttpOnly() {
return httpOnly; return httpOnly;
} }
/** /**
* @param httpOnly 是否禁止 js 操作 Cookie * @param httpOnly 是否禁止 js 操作 Cookie
* @return 对象自身 * @return 对象自身
*/ */
public SaCookie setHttpOnly(Boolean httpOnly) { public SaCookie setHttpOnly(Boolean httpOnly) {
this.httpOnly = httpOnly; this.httpOnly = httpOnly;
@ -201,7 +201,7 @@ public class SaCookie {
/** /**
* @param sameSite 第三方限制级别Strict=完全禁止Lax=部分允许None=不限制 * @param sameSite 第三方限制级别Strict=完全禁止Lax=部分允许None=不限制
* @return 对象自身 * @return 对象自身
*/ */
public SaCookie setSameSite(String sameSite) { public SaCookie setSameSite(String sameSite) {
this.sameSite = sameSite; this.sameSite = sameSite;
@ -209,57 +209,57 @@ public class SaCookie {
} }
// toString // toString
@Override @Override
public String toString() { public String toString() {
return "SaCookie [name=" + name + ", value=" + value + ", maxAge=" + maxAge + ", domain=" + domain + ", path=" + path return "SaCookie [name=" + name + ", value=" + value + ", maxAge=" + maxAge + ", domain=" + domain + ", path=" + path
+ ", secure=" + secure + ", httpOnly=" + httpOnly + ", sameSite=" + ", secure=" + secure + ", httpOnly=" + httpOnly + ", sameSite="
+ sameSite + "]"; + sameSite + "]";
} }
/** /**
* 构建一下 * 构建一下
*/ */
public void builde() { public void builde() {
if(path == null) { if(path == null) {
path = "/"; path = "/";
} }
} }
/** /**
* 转换为响应头 Set-Cookie 参数需要的值 * 转换为响应头 Set-Cookie 参数需要的值
* @return / * @return /
*/ */
public String toHeaderValue() { public String toHeaderValue() {
this.builde(); this.builde();
if(SaFoxUtil.isEmpty(name)) { if(SaFoxUtil.isEmpty(name)) {
throw new SaTokenException("name不能为空").setCode(SaErrorCode.CODE_12002); throw new SaTokenException("name不能为空").setCode(SaErrorCode.CODE_12002);
} }
if(value != null && value.indexOf(";") > -1) { if(value != null && value.contains(";")) {
throw new SaTokenException("无效Value" + value).setCode(SaErrorCode.CODE_12003); throw new SaTokenException("无效Value" + value).setCode(SaErrorCode.CODE_12003);
} }
// Set-Cookie: name=value; Max-Age=100000; Expires=Tue, 05-Oct-2021 20:28:17 GMT; Domain=localhost; Path=/; Secure; HttpOnly; SameSite=Lax // Set-Cookie: name=value; Max-Age=100000; Expires=Tue, 05-Oct-2021 20:28:17 GMT; Domain=localhost; Path=/; Secure; HttpOnly; SameSite=Lax
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
sb.append(name + "=" + value); sb.append(name).append("=").append(value);
if(maxAge >= 0) { if(maxAge >= 0) {
sb.append("; Max-Age=" + maxAge); sb.append("; Max-Age=").append(maxAge);
String expires; String expires;
if(maxAge == 0) { if(maxAge == 0) {
expires = Instant.EPOCH.atOffset(ZoneOffset.UTC).format(DateTimeFormatter.RFC_1123_DATE_TIME); expires = Instant.EPOCH.atOffset(ZoneOffset.UTC).format(DateTimeFormatter.RFC_1123_DATE_TIME);
} else { } else {
expires = OffsetDateTime.now().plusSeconds(maxAge).format(DateTimeFormatter.RFC_1123_DATE_TIME); expires = OffsetDateTime.now().plusSeconds(maxAge).format(DateTimeFormatter.RFC_1123_DATE_TIME);
} }
sb.append("; Expires=" + expires); sb.append("; Expires=").append(expires);
} }
if(!SaFoxUtil.isEmpty(domain)) { if(!SaFoxUtil.isEmpty(domain)) {
sb.append("; Domain=" + domain); sb.append("; Domain=").append(domain);
} }
if(!SaFoxUtil.isEmpty(path)) { if(!SaFoxUtil.isEmpty(path)) {
sb.append("; Path=" + path); sb.append("; Path=").append(path);
} }
if(secure) { if(secure) {
sb.append("; Secure"); sb.append("; Secure");
@ -268,10 +268,10 @@ public class SaCookie {
sb.append("; HttpOnly"); sb.append("; HttpOnly");
} }
if(!SaFoxUtil.isEmpty(sameSite)) { if(!SaFoxUtil.isEmpty(sameSite)) {
sb.append("; SameSite=" + sameSite); sb.append("; SameSite=").append(sameSite);
} }
return sb.toString(); return sb.toString();
} }
} }

View File

@ -1,5 +1,6 @@
package cn.dev33.satoken.secure; package cn.dev33.satoken.secure;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.KeyPairGenerator; import java.security.KeyPairGenerator;
@ -27,7 +28,7 @@ import cn.dev33.satoken.exception.SaTokenException;
/** /**
* Sa-Token 常见加密算法工具类 * Sa-Token 常见加密算法工具类
* *
* @author kong * @author kong
* *
*/ */
@ -35,7 +36,7 @@ public class SaSecureUtil {
private SaSecureUtil() { private SaSecureUtil() {
} }
/** /**
* Base64编码 * Base64编码
*/ */
@ -45,11 +46,11 @@ public class SaSecureUtil {
* Base64解码 * Base64解码
*/ */
private static Base64.Decoder decoder = Base64.getDecoder(); private static Base64.Decoder decoder = Base64.getDecoder();
// ----------------------- 摘要加密 ----------------------- // ----------------------- 摘要加密 -----------------------
/** /**
* md5加密 * md5加密
* @param str 指定字符串 * @param str 指定字符串
* @return 加密后的字符串 * @return 加密后的字符串
*/ */
@ -75,8 +76,8 @@ public class SaSecureUtil {
} }
/** /**
* sha1加密 * sha1加密
* *
* @param str 指定字符串 * @param str 指定字符串
* @return 加密后的字符串 * @return 加密后的字符串
*/ */
@ -103,8 +104,8 @@ public class SaSecureUtil {
} }
/** /**
* sha256加密 * sha256加密
* *
* @param str 指定字符串 * @param str 指定字符串
* @return 加密后的字符串 * @return 加密后的字符串
*/ */
@ -112,8 +113,8 @@ public class SaSecureUtil {
try { try {
str = (str == null ? "" : str); str = (str == null ? "" : str);
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes("UTF-8")); messageDigest.update(str.getBytes(StandardCharsets.UTF_8));
byte[] bytes = messageDigest.digest(); byte[] bytes = messageDigest.digest();
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
String temp; String temp;
@ -124,7 +125,7 @@ public class SaSecureUtil {
} }
builder.append(temp); builder.append(temp);
} }
return builder.toString(); return builder.toString();
} catch (Exception e) { } catch (Exception e) {
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12113); throw new SaTokenException(e).setCode(SaErrorCode.CODE_12113);
@ -132,20 +133,20 @@ public class SaSecureUtil {
} }
/** /**
* md5加盐加密: md5(md5(str) + md5(salt)) * md5加盐加密: md5(md5(str) + md5(salt))
* @param str 字符串 * @param str 字符串
* @param salt * @param salt
* @return 加密后的字符串 * @return 加密后的字符串
*/ */
public static String md5BySalt(String str, String salt) { public static String md5BySalt(String str, String salt) {
return md5(md5(str) + md5(salt)); return md5(md5(str) + md5(salt));
} }
// ----------------------- 对称加密 AES ----------------------- // ----------------------- 对称加密 AES -----------------------
/** /**
* 默认密码算法 * 默认密码算法
*/ */
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
@ -159,7 +160,7 @@ public class SaSecureUtil {
public static String aesEncrypt(String key, String text) { public static String aesEncrypt(String key, String text) {
try { try {
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
byte[] byteContent = text.getBytes("utf-8"); byte[] byteContent = text.getBytes(StandardCharsets.UTF_8);
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key)); cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
byte[] result = cipher.doFinal(byteContent); byte[] result = cipher.doFinal(byteContent);
return encoder.encodeToString(result); return encoder.encodeToString(result);
@ -169,7 +170,7 @@ public class SaSecureUtil {
} }
/** /**
* AES解密 * AES解密
* @param key 加密的密钥 * @param key 加密的密钥
* @param text 已加密的密文 * @param text 已加密的密文
* @return 返回解密后的数据 * @return 返回解密后的数据
@ -179,16 +180,16 @@ public class SaSecureUtil {
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key)); cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
byte[] result = cipher.doFinal(decoder.decode(text)); byte[] result = cipher.doFinal(decoder.decode(text));
return new String(result, "utf-8"); return new String(result, StandardCharsets.UTF_8);
} catch (Exception e) { } catch (Exception e) {
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12115); throw new SaTokenException(e).setCode(SaErrorCode.CODE_12115);
} }
} }
/** /**
* 生成加密秘钥 * 生成加密秘钥
* @param password 秘钥 * @param password 秘钥
* @return SecretKeySpec * @return SecretKeySpec
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
*/ */
private static SecretKeySpec getSecretKey(final String password) throws NoSuchAlgorithmException { private static SecretKeySpec getSecretKey(final String password) throws NoSuchAlgorithmException {
@ -204,14 +205,14 @@ public class SaSecureUtil {
// ----------------------- 非对称加密 RSA ----------------------- // ----------------------- 非对称加密 RSA -----------------------
private static final String ALGORITHM = "RSA"; private static final String ALGORITHM = "RSA";
private static final int KEY_SIZE = 1024; private static final int KEY_SIZE = 1024;
// ---------- 5个常用方法 // ---------- 5个常用方法
/** /**
* 生成密钥对 * 生成密钥对
* @return Map对象 (private=私钥, public=公钥) * @return Map对象 (private=私钥, public=公钥)
* @throws Exception 异常 * @throws Exception 异常
*/ */
@ -242,24 +243,24 @@ public class SaSecureUtil {
public static String rsaEncryptByPublic(String publicKeyString, String content) { public static String rsaEncryptByPublic(String publicKeyString, String content) {
try { try {
// 获得公钥对象 // 获得公钥对象
PublicKey publicKey = getPublicKeyFromString(publicKeyString); PublicKey publicKey = getPublicKeyFromString(publicKeyString);
Cipher cipher = Cipher.getInstance("RSA"); Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey); cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 该密钥能够加密的最大字节长度 // 该密钥能够加密的最大字节长度
int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8 - 11; int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8 - 11;
byte[][] arrays = splitBytes(content.getBytes(), splitLength); byte[][] arrays = splitBytes(content.getBytes(), splitLength);
StringBuffer stringBuffer = new StringBuffer(); StringBuilder stringBuilder = new StringBuilder();
for (byte[] array : arrays) { for (byte[] array : arrays) {
stringBuffer.append(bytesToHexString(cipher.doFinal(array))); stringBuilder.append(bytesToHexString(cipher.doFinal(array)));
} }
return stringBuffer.toString(); return stringBuilder.toString();
} catch (Exception e) { } catch (Exception e) {
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12116); throw new SaTokenException(e).setCode(SaErrorCode.CODE_12116);
} }
} }
/** /**
* RSA私钥加密 * RSA私钥加密
* @param privateKeyString 私钥 * @param privateKeyString 私钥
* @param content 内容 * @param content 内容
@ -274,17 +275,17 @@ public class SaSecureUtil {
// 该密钥能够加密的最大字节长度 // 该密钥能够加密的最大字节长度
int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8 - 11; int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8 - 11;
byte[][] arrays = splitBytes(content.getBytes(), splitLength); byte[][] arrays = splitBytes(content.getBytes(), splitLength);
StringBuffer stringBuffer = new StringBuffer(); StringBuilder stringBuilder = new StringBuilder();
for (byte[] array : arrays) { for (byte[] array : arrays) {
stringBuffer.append(bytesToHexString(cipher.doFinal(array))); stringBuilder.append(bytesToHexString(cipher.doFinal(array)));
} }
return stringBuffer.toString(); return stringBuilder.toString();
} catch (Exception e) { } catch (Exception e) {
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12117); throw new SaTokenException(e).setCode(SaErrorCode.CODE_12117);
} }
} }
/** /**
* RSA公钥解密 * RSA公钥解密
* @param publicKeyString 公钥 * @param publicKeyString 公钥
* @param content 已加密内容 * @param content 已加密内容
@ -301,11 +302,11 @@ public class SaSecureUtil {
int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8; int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8;
byte[] contentBytes = hexStringToBytes(content); byte[] contentBytes = hexStringToBytes(content);
byte[][] arrays = splitBytes(contentBytes, splitLength); byte[][] arrays = splitBytes(contentBytes, splitLength);
StringBuffer stringBuffer = new StringBuffer(); StringBuilder stringBuilder = new StringBuilder();
for (byte[] array : arrays) { for (byte[] array : arrays) {
stringBuffer.append(new String(cipher.doFinal(array))); stringBuilder.append(new String(cipher.doFinal(array)));
} }
return stringBuffer.toString(); return stringBuilder.toString();
} catch (Exception e) { } catch (Exception e) {
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12118); throw new SaTokenException(e).setCode(SaErrorCode.CODE_12118);
} }
@ -327,18 +328,18 @@ public class SaSecureUtil {
int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8; int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8;
byte[] contentBytes = hexStringToBytes(content); byte[] contentBytes = hexStringToBytes(content);
byte[][] arrays = splitBytes(contentBytes, splitLength); byte[][] arrays = splitBytes(contentBytes, splitLength);
StringBuffer stringBuffer = new StringBuffer(); StringBuilder stringBuilder = new StringBuilder();
for (byte[] array : arrays) { for (byte[] array : arrays) {
stringBuffer.append(new String(cipher.doFinal(array))); stringBuilder.append(new String(cipher.doFinal(array)));
} }
return stringBuffer.toString(); return stringBuilder.toString();
} catch (Exception e) { } catch (Exception e) {
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12119); throw new SaTokenException(e).setCode(SaErrorCode.CODE_12119);
} }
} }
// ---------- 获取* // ---------- 获取*
/** 根据公钥字符串获取 公钥对象 */ /** 根据公钥字符串获取 公钥对象 */
private static PublicKey getPublicKeyFromString(String key) private static PublicKey getPublicKeyFromString(String key)
@ -352,9 +353,7 @@ public class SaSecureUtil {
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); return keyFactory.generatePublic(x509KeySpec);
return publicKey;
} }
/** 根据私钥字符串获取 私钥对象 */ /** 根据私钥字符串获取 私钥对象 */
@ -369,9 +368,7 @@ public class SaSecureUtil {
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(x509KeySpec); return keyFactory.generatePrivate(x509KeySpec);
return privateKey;
} }
@ -435,5 +432,5 @@ public class SaSecureUtil {
return (byte) "0123456789ABCDEF".indexOf(c); return (byte) "0123456789ABCDEF".indexOf(c);
} }
} }

View File

@ -22,8 +22,8 @@ import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException; import cn.dev33.satoken.exception.SaTokenException;
/** /**
* Sa-Token 内部工具类 * Sa-Token 内部工具类
* *
* @author kong * @author kong
* *
*/ */
@ -31,20 +31,20 @@ public class SaFoxUtil {
private SaFoxUtil() { private SaFoxUtil() {
} }
/** /**
* 打印 Sa-Token 版本字符画 * 打印 Sa-Token 版本字符画
*/ */
public static void printSaToken() { public static void printSaToken() {
String str = "" String str = ""
+ "____ ____ ___ ____ _ _ ____ _ _ \r\n" + "____ ____ ___ ____ _ _ ____ _ _ \r\n"
+ "[__ |__| __ | | | |_/ |___ |\\ | \r\n" + "[__ |__| __ | | | |_/ |___ |\\ | \r\n"
+ "___] | | | |__| | \\_ |___ | \\| " + "___] | | | |__| | \\_ |___ | \\| "
// + SaTokenConsts.VERSION_NO // + SaTokenConsts.VERSION_NO
// + "sa-token" // + "sa-token"
// + "\r\n" + "DevDoc" + SaTokenConsts.DEV_DOC_URL // + "\r\n"; // + "\r\n" + "DevDoc" + SaTokenConsts.DEV_DOC_URL // + "\r\n";
+ "\r\n" + SaTokenConsts.DEV_DOC_URL // + "\r\n"; + "\r\n" + SaTokenConsts.DEV_DOC_URL // + "\r\n";
+ " (" + SaTokenConsts.VERSION_NO + ")" + " (" + SaTokenConsts.VERSION_NO + ")"
// + "\r\n" + "GitHub" + SaTokenConsts.GITHUB_URL // + "\r\n"; // + "\r\n" + "GitHub" + SaTokenConsts.GITHUB_URL // + "\r\n";
; ;
System.out.println(str); System.out.println(str);
@ -52,13 +52,13 @@ public class SaFoxUtil {
/** /**
* 生成指定长度的随机字符串 * 生成指定长度的随机字符串
* *
* @param length 字符串的长度 * @param length 字符串的长度
* @return 一个随机字符串 * @return 一个随机字符串
*/ */
public static String getRandomString(int length) { public static String getRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
int number = ThreadLocalRandom.current().nextInt(62); int number = ThreadLocalRandom.current().nextInt(62);
sb.append(str.charAt(number)); sb.append(str.charAt(number));
@ -68,7 +68,7 @@ public class SaFoxUtil {
/** /**
* 指定元素是否为null或者空字符串 * 指定元素是否为null或者空字符串
* @param str 指定元素 * @param str 指定元素
* @return 是否为null或者空字符串 * @return 是否为null或者空字符串
*/ */
public static boolean isEmpty(Object str) { public static boolean isEmpty(Object str) {
@ -77,7 +77,7 @@ public class SaFoxUtil {
/** /**
* 指定元素是否不为 (null或者空字符串) * 指定元素是否不为 (null或者空字符串)
* @param str 指定元素 * @param str 指定元素
* @return 是否为null或者空字符串 * @return 是否为null或者空字符串
*/ */
public static boolean isNotEmpty(Object str) { public static boolean isNotEmpty(Object str) {
@ -95,18 +95,18 @@ public class SaFoxUtil {
} }
/** /**
* 比较两个对象是否相等 * 比较两个对象是否相等
* @param a 第一个对象 * @param a 第一个对象
* @param b 第二个对象 * @param b 第二个对象
* @return 两个对象是否相等 * @return 两个对象是否相等
*/ */
public static boolean equals(Object a, Object b) { public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b)); return (a == b) || (a != null && a.equals(b));
} }
/** /**
* 以当前时间戳和随机int数字拼接一个随机字符串 * 以当前时间戳和随机int数字拼接一个随机字符串
* *
* @return 随机字符串 * @return 随机字符串
*/ */
public static String getMarking28() { public static String getMarking28() {
@ -116,7 +116,7 @@ public class SaFoxUtil {
/** /**
* 将日期格式化 yyyy-MM-dd HH:mm:ss * 将日期格式化 yyyy-MM-dd HH:mm:ss
* @param date 日期 * @param date 日期
* @return 格式化后的时间 * @return 格式化后的时间
*/ */
public static String formatDate(Date date){ public static String formatDate(Date date){
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
@ -141,17 +141,17 @@ public class SaFoxUtil {
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
return formatDate(zonedDateTime); return formatDate(zonedDateTime);
} }
/** /**
* 从集合里查询数据 * 从集合里查询数据
* *
* @param dataList 数据集合 * @param dataList 数据集合
* @param prefix 前缀 * @param prefix 前缀
* @param keyword 关键字 * @param keyword 关键字
* @param start 起始位置 (-1代表查询所有) * @param start 起始位置 (-1代表查询所有)
* @param size 获取条数 * @param size 获取条数
* @param sortType 排序类型true=正序false=反序 * @param sortType 排序类型true=正序false=反序
* *
* @return 符合条件的新数据集合 * @return 符合条件的新数据集合
*/ */
public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start, int size, boolean sortType) { public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start, int size, boolean sortType) {
@ -176,34 +176,34 @@ public class SaFoxUtil {
/** /**
* 从集合里查询数据 * 从集合里查询数据
* *
* @param list 数据集合 * @param list 数据集合
* @param start 起始位置 * @param start 起始位置
* @param size 获取条数 (-1代表从start处一直取到末尾) * @param size 获取条数 (-1代表从start处一直取到末尾)
* @param sortType 排序类型true=正序false=反序 * @param sortType 排序类型true=正序false=反序
* *
* @return 符合条件的新数据集合 * @return 符合条件的新数据集合
*/ */
public static List<String> searchList(List<String> list, int start, int size, boolean sortType) { public static List<String> searchList(List<String> list, int start, int size, boolean sortType) {
// 如果是反序的话 // 如果是反序的话
if(sortType == false) { if(sortType == false) {
Collections.reverse(list); Collections.reverse(list);
} }
// start 至少为0 // start 至少为0
if (start < 0) { if (start < 0) {
start = 0; start = 0;
} }
// size为-1时代表一直取到末尾否则取到 start + size // size为-1时代表一直取到末尾否则取到 start + size
int end; int end;
if(size == -1) { if(size == -1) {
end = list.size(); end = list.size();
} else { } else {
end = start + size; end = start + size;
} }
// 取出的数据放到新集合中 // 取出的数据放到新集合中
List<String> list2 = new ArrayList<String>(); List<String> list2 = new ArrayList<String>();
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
// 如果已经取到list的末尾则直接退出 // 如果已经取到list的末尾则直接退出
if (i >= list.size()) { if (i >= list.size()) {
return list2; return list2;
} }
@ -211,62 +211,62 @@ public class SaFoxUtil {
} }
return list2; return list2;
} }
/** /**
* 字符串模糊匹配 * 字符串模糊匹配
* <p>example: * <p>example:
* <p> user* user-add -- true * <p> user* user-add -- true
* <p> user* art-add -- false * <p> user* art-add -- false
* @param patt 表达式 * @param patt 表达式
* @param str 待匹配的字符串 * @param str 待匹配的字符串
* @return 是否可以匹配 * @return 是否可以匹配
*/ */
public static boolean vagueMatch(String patt, String str) { public static boolean vagueMatch(String patt, String str) {
// 两者均为 null 直接返回 true // 两者均为 null 直接返回 true
if(patt == null && str == null) { if(patt == null && str == null) {
return true; return true;
} }
// 两者其一为 null 直接返回 false // 两者其一为 null 直接返回 false
if(patt == null || str == null) { if(patt == null || str == null) {
return false; return false;
} }
// 如果表达式不带有*则只需简单equals即可 (这样可以使速度提升200倍左右) // 如果表达式不带有*则只需简单equals即可 (这样可以使速度提升200倍左右)
if(patt.indexOf("*") == -1) { if(patt.indexOf("*") == -1) {
return patt.equals(str); return patt.equals(str);
} }
// 正则匹配 // 正则匹配
return Pattern.matches(patt.replaceAll("\\*", ".*"), str); return Pattern.matches(patt.replaceAll("\\*", ".*"), str);
} }
/** /**
* 判断类型是否为8大包装类型 * 判断类型是否为8大包装类型
* @param cs / * @param cs /
* @return / * @return /
*/ */
public static boolean isWrapperType(Class<?> cs) { public static boolean isWrapperType(Class<?> cs) {
return cs == Integer.class || cs == Short.class || cs == Long.class || cs == Byte.class return cs == Integer.class || cs == Short.class || cs == Long.class || cs == Byte.class
|| cs == Float.class || cs == Double.class || cs == Boolean.class || cs == Character.class; || cs == Float.class || cs == Double.class || cs == Boolean.class || cs == Character.class;
} }
/** /**
* 判断类型是否为基础类型8大基本数据类型8大包装类String * 判断类型是否为基础类型8大基本数据类型8大包装类String
* @param cs / * @param cs /
* @return / * @return /
*/ */
public static boolean isBasicType(Class<?> cs) { public static boolean isBasicType(Class<?> cs) {
return cs.isPrimitive() || isWrapperType(cs) || cs == String.class; return cs.isPrimitive() || isWrapperType(cs) || cs == String.class;
} }
/** /**
* 将指定值转化为指定类型 * 将指定值转化为指定类型
* @param <T> 泛型 * @param <T> 泛型
* @param obj * @param obj
* @param cs 类型 * @param cs 类型
* @return 转换后的值 * @return 转换后的值
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T getValueByType(Object obj, Class<T> cs) { public static <T> T getValueByType(Object obj, Class<T> cs) {
// 如果 obj null 或者本来就是 cs 类型 // 如果 obj null 或者本来就是 cs 类型
if(obj == null || obj.getClass().equals(cs)) { if(obj == null || obj.getClass().equals(cs)) {
return (T)obj; return (T)obj;
} }
@ -296,15 +296,15 @@ public class SaFoxUtil {
} }
return (T)obj3; return (T)obj3;
} }
/** /**
* 在url上拼接上kv参数并返回 * 在url上拼接上kv参数并返回
* @param url url * @param url url
* @param parameStr 参数, 例如 id=1001 * @param parameStr 参数, 例如 id=1001
* @return 拼接后的url字符串 * @return 拼接后的url字符串
*/ */
public static String joinParam(String url, String parameStr) { public static String joinParam(String url, String parameStr) {
// 如果参数为空, 直接返回 // 如果参数为空, 直接返回
if(parameStr == null || parameStr.length() == 0) { if(parameStr == null || parameStr.length() == 0) {
return url; return url;
} }
@ -330,19 +330,19 @@ public class SaFoxUtil {
return url + parameStr; return url + parameStr;
} }
} }
// 正常情况下, 代码不可能执行到此 // 正常情况下, 代码不可能执行到此
return url; return url;
} }
/** /**
* 在url上拼接上kv参数并返回 * 在url上拼接上kv参数并返回
* @param url url * @param url url
* @param key 参数名称 * @param key 参数名称
* @param value 参数值 * @param value 参数值
* @return 拼接后的url字符串 * @return 拼接后的url字符串
*/ */
public static String joinParam(String url, String key, Object value) { public static String joinParam(String url, String key, Object value) {
// 如果url或者key为空, 直接返回 // 如果url或者key为空, 直接返回
if(isEmpty(url) || isEmpty(key)) { if(isEmpty(url) || isEmpty(key)) {
return url; return url;
} }
@ -350,13 +350,13 @@ public class SaFoxUtil {
} }
/** /**
* 在url上拼接锚参数 * 在url上拼接锚参数
* @param url url * @param url url
* @param parameStr 参数, 例如 id=1001 * @param parameStr 参数, 例如 id=1001
* @return 拼接后的url字符串 * @return 拼接后的url字符串
*/ */
public static String joinSharpParam(String url, String parameStr) { public static String joinSharpParam(String url, String parameStr) {
// 如果参数为空, 直接返回 // 如果参数为空, 直接返回
if(parameStr == null || parameStr.length() == 0) { if(parameStr == null || parameStr.length() == 0) {
return url; return url;
} }
@ -382,19 +382,19 @@ public class SaFoxUtil {
return url + parameStr; return url + parameStr;
} }
} }
// 正常情况下, 代码不可能执行到此 // 正常情况下, 代码不可能执行到此
return url; return url;
} }
/** /**
* 在url上拼接锚参数 * 在url上拼接锚参数
* @param url url * @param url url
* @param key 参数名称 * @param key 参数名称
* @param value 参数值 * @param value 参数值
* @return 拼接后的url字符串 * @return 拼接后的url字符串
*/ */
public static String joinSharpParam(String url, String key, Object value) { public static String joinSharpParam(String url, String key, Object value) {
// 如果url或者key为空, 直接返回 // 如果url或者key为空, 直接返回
if(isEmpty(url) || isEmpty(key)) { if(isEmpty(url) || isEmpty(key)) {
return url; return url;
} }
@ -402,31 +402,31 @@ public class SaFoxUtil {
} }
/** /**
* 拼接两个url * 拼接两个url
* <p> 例如url1=http://domain.cnurl2=/sso/auth则返回http://domain.cn/sso/auth </p> * <p> 例如url1=http://domain.cnurl2=/sso/auth则返回http://domain.cn/sso/auth </p>
* *
* @param url1 第一个url * @param url1 第一个url
* @param url2 第二个url * @param url2 第二个url
* @return 拼接完成的url * @return 拼接完成的url
*/ */
public static String spliceTwoUrl(String url1, String url2) { public static String spliceTwoUrl(String url1, String url2) {
// q1任意一个为空则直接返回另一个 // q1任意一个为空则直接返回另一个
if(url1 == null) { if(url1 == null) {
return url2; return url2;
} }
if(url2 == null) { if(url2 == null) {
return url1; return url1;
} }
// q2如果 url2 http 开头将其视为一个完整地址 // q2如果 url2 http 开头将其视为一个完整地址
if(url2.startsWith("http")) { if(url2.startsWith("http")) {
return url2; return url2;
} }
// q3将两个地址拼接在一起 // q3将两个地址拼接在一起
return url1 + url2; return url1 + url2;
} }
/** /**
* 将数组的所有元素使用逗号拼接在一起 * 将数组的所有元素使用逗号拼接在一起
* @param arr 数组 * @param arr 数组
@ -445,16 +445,16 @@ public class SaFoxUtil {
} }
return str; return str;
} }
/** /**
* 验证URL的正则表达式 * 验证URL的正则表达式
*/ */
public static final String URL_REGEX = "(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]"; public static final String URL_REGEX = "(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]";
/** /**
* 使用正则表达式判断一个字符串是否为URL * 使用正则表达式判断一个字符串是否为URL
* @param str 字符串 * @param str 字符串
* @return 拼接后的url字符串 * @return 拼接后的url字符串
*/ */
public static boolean isUrl(String str) { public static boolean isUrl(String str) {
if(isEmpty(str)) { if(isEmpty(str)) {
@ -462,11 +462,11 @@ public class SaFoxUtil {
} }
return str.toLowerCase().matches(URL_REGEX); return str.toLowerCase().matches(URL_REGEX);
} }
/** /**
* URL编码 * URL编码
* @param url see note * @param url see note
* @return see note * @return see note
*/ */
public static String encodeUrl(String url) { public static String encodeUrl(String url) {
try { try {
@ -477,9 +477,9 @@ public class SaFoxUtil {
} }
/** /**
* URL解码 * URL解码
* @param url see note * @param url see note
* @return see note * @return see note
*/ */
public static String decoderUrl(String url) { public static String decoderUrl(String url) {
try { try {
@ -488,11 +488,11 @@ public class SaFoxUtil {
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12104); throw new SaTokenException(e).setCode(SaErrorCode.CODE_12104);
} }
} }
/** /**
* 将指定字符串按照逗号分隔符转化为字符串集合 * 将指定字符串按照逗号分隔符转化为字符串集合
* @param str 字符串 * @param str 字符串
* @return 分割后的字符串集合 * @return 分割后的字符串集合
*/ */
public static List<String> convertStringToList(String str) { public static List<String> convertStringToList(String str) {
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<String>();
@ -510,9 +510,9 @@ public class SaFoxUtil {
} }
/** /**
* 将指定集合按照逗号连接成一个字符串 * 将指定集合按照逗号连接成一个字符串
* @param list 集合 * @param list 集合
* @return 字符串 * @return 字符串
*/ */
public static String convertListToString(List<?> list) { public static String convertListToString(List<?> list) {
if(list == null || list.size() == 0) { if(list == null || list.size() == 0) {
@ -527,11 +527,11 @@ public class SaFoxUtil {
} }
return str; return str;
} }
/** /**
* String Array按照逗号切割 * String Array按照逗号切割
* @param str 字符串 * @param str 字符串
* @return 数组 * @return 数组
*/ */
public static String[] convertStringToArray(String str) { public static String[] convertStringToArray(String str) {
List<String> list = convertStringToList(str); List<String> list = convertStringToList(str);
@ -539,9 +539,9 @@ public class SaFoxUtil {
} }
/** /**
* Array String按照逗号连接 * Array String按照逗号连接
* @param arr 数组 * @param arr 数组
* @return 字符串 * @return 字符串
*/ */
public static String convertArrayToString(String[] arr) { public static String convertArrayToString(String[] arr) {
if(arr == null || arr.length == 0) { if(arr == null || arr.length == 0) {
@ -549,20 +549,20 @@ public class SaFoxUtil {
} }
return String.join(",", arr); return String.join(",", arr);
} }
/** /**
* 返回一个空集合 * 返回一个空集合
* @param <T> 集合类型 * @param <T> 集合类型
* @return 空集合 * @return 空集合
*/ */
public static <T>List<T> emptyList() { public static <T>List<T> emptyList() {
return new ArrayList<>(); return new ArrayList<>();
} }
/** /**
* String数组转集合 * String数组转集合
* @param strs String数组 * @param strs String数组
* @return 集合 * @return 集合
*/ */
public static List<String> toList(String... strs) { public static List<String> toList(String... strs) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
@ -571,9 +571,9 @@ public class SaFoxUtil {
} }
return list; return list;
} }
public static List<String> logLevelList = Arrays.asList("", "trace", "debug", "info", "warn", "error", "fatal"); public static List<String> logLevelList = Arrays.asList("", "trace", "debug", "info", "warn", "error", "fatal");
/** /**
* 将日志等级从 String 格式转化为 int 格式 * 将日志等级从 String 格式转化为 int 格式
* @param level / * @param level /
@ -598,5 +598,5 @@ public class SaFoxUtil {
} }
return logLevelList.get(level); return logLevelList.get(level);
} }
} }