|
|
|
@ -17,7 +17,6 @@ import org.apache.commons.codec.digest.DigestUtils;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.net.URISyntaxException;
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
@ -32,24 +31,7 @@ import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class CommonUtil {
|
|
|
|
|
//在独立的main函数中,使用下面的方式进行声明logback对象
|
|
|
|
|
private static Logger log = LoggerFactory.getLogger(CommonUtil.class);
|
|
|
|
|
/**
|
|
|
|
|
* 获取当前服务器的URL
|
|
|
|
|
* @param request
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getServerUrl(HttpServletRequest request) {
|
|
|
|
|
// 获取服务器端口
|
|
|
|
|
int serverPort = request.getLocalPort();
|
|
|
|
|
// 获取完整的访问地址(包含协议、主机名、端口)
|
|
|
|
|
String scheme = request.getScheme(); // 获取协议 (http 或 https)
|
|
|
|
|
// 获取服务器名称
|
|
|
|
|
String serverName = request.getServerName();
|
|
|
|
|
// 如果需要获取项目上下文路径
|
|
|
|
|
String contextPath = request.getContextPath();
|
|
|
|
|
return scheme + "://" + serverName + ":" + serverPort + contextPath;
|
|
|
|
|
}
|
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(CommonUtil.class);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:将jsonObject转换为Record
|
|
|
|
@ -67,80 +49,6 @@ public class CommonUtil {
|
|
|
|
|
return record;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:将List<JSONObject>转换为List<Record>
|
|
|
|
|
*
|
|
|
|
|
* @param listJsonObject
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static List<Record> convertListJsonObjectToListRecord(List<JSONObject> listJsonObject) {
|
|
|
|
|
List<Record> listRecord = new ArrayList<>();
|
|
|
|
|
for (JSONObject jsonObject : listJsonObject) {
|
|
|
|
|
listRecord.add(convertJsonObjectToRecord(jsonObject));
|
|
|
|
|
}
|
|
|
|
|
return listRecord;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void mergeJsonObjects(JSONObject j1, JSONObject j2) {
|
|
|
|
|
// 获取j2的所有键
|
|
|
|
|
Set<String> keys = j2.keySet();
|
|
|
|
|
for (String key : keys) {
|
|
|
|
|
// 确保j1也有相同的键
|
|
|
|
|
if (j1.containsKey(key)) {
|
|
|
|
|
// 累加数值
|
|
|
|
|
Object value1 = j1.get(key);
|
|
|
|
|
Object value2 = j2.get(key);
|
|
|
|
|
if (value1 instanceof Number && value2 instanceof Number) {
|
|
|
|
|
j1.put(key, ((Number) value1).doubleValue() + ((Number) value2).doubleValue());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:克隆Record对象
|
|
|
|
|
*
|
|
|
|
|
* @param r1 源对象
|
|
|
|
|
* @return 克隆出的对象
|
|
|
|
|
*/
|
|
|
|
|
public static Record cloneRecord(Record r1) {
|
|
|
|
|
// 复制字段
|
|
|
|
|
Record r2 = new Record();
|
|
|
|
|
for (Map.Entry<String, Object> entry : r1.getColumns().entrySet()) {
|
|
|
|
|
r2.set(entry.getKey(), entry.getValue());
|
|
|
|
|
}
|
|
|
|
|
return r2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:合并两个 Record 对象
|
|
|
|
|
*
|
|
|
|
|
* @param r1 第一个对象,也是最终合并后的对象
|
|
|
|
|
* @param r2 第二个对象
|
|
|
|
|
*/
|
|
|
|
|
public static void mergeRecord(Record r1, Record r2) {
|
|
|
|
|
// 获取 record1 的所有字段和值,设置到 mergedRecord 中
|
|
|
|
|
Set<String> fields1 = r1.getColumns().keySet();
|
|
|
|
|
// 获取 record2 的所有字段和值,设置到 mergedRecord 中,注意避免重复设置已经在 record1 中设置过的字段
|
|
|
|
|
Set<String> fields2 = r2.getColumns().keySet();
|
|
|
|
|
for (String field : fields2) {
|
|
|
|
|
if (!fields1.contains(field)) { // 检查字段是否已经在 record1 中设置过
|
|
|
|
|
r1.set(field, r2.get(field));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static <T> List<T> castList(Object obj, Class<T> clazz) {
|
|
|
|
|
List<T> result = new ArrayList<>();
|
|
|
|
|
if (obj instanceof List<?>) {
|
|
|
|
|
for (Object o : (List<?>) obj) {
|
|
|
|
|
result.add(clazz.cast(o));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:获取操作系统类型
|
|
|
|
|
* 作者:黄海
|
|
|
|
@ -157,24 +65,6 @@ public class CommonUtil {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:删除指定目录下所有的文件
|
|
|
|
|
* 作者:黄海
|
|
|
|
|
* 时间:2019-01-03
|
|
|
|
|
*
|
|
|
|
|
* @param tempPath
|
|
|
|
|
*/
|
|
|
|
|
public static void clearFile(String tempPath) {
|
|
|
|
|
File file = new File(tempPath);
|
|
|
|
|
File[] tempList = file.listFiles();
|
|
|
|
|
if (tempList != null) {
|
|
|
|
|
for (File value : tempList) {
|
|
|
|
|
if (value.isFile()) {
|
|
|
|
|
value.delete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:判断是不是合法的日期格式
|
|
|
|
@ -311,20 +201,6 @@ public class CommonUtil {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:判断一个字符串是不是小数
|
|
|
|
|
*
|
|
|
|
|
* @param str
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static boolean isDecimal(String str) {
|
|
|
|
|
try {
|
|
|
|
|
Double.parseDouble(str);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:封装一个返回json信息的函数
|
|
|
|
@ -406,79 +282,6 @@ public class CommonUtil {
|
|
|
|
|
return flag.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String generatePassword(int length) {
|
|
|
|
|
String upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
|
|
String lowerCase = upperCase.toLowerCase();
|
|
|
|
|
String numbers = "0123456789";
|
|
|
|
|
String symbols = "#$*";
|
|
|
|
|
|
|
|
|
|
List<Character> chars = new ArrayList<>();
|
|
|
|
|
for (char c : upperCase.toCharArray()) {
|
|
|
|
|
chars.add(c);
|
|
|
|
|
}
|
|
|
|
|
for (char c : lowerCase.toCharArray()) {
|
|
|
|
|
chars.add(c);
|
|
|
|
|
}
|
|
|
|
|
for (char c : numbers.toCharArray()) {
|
|
|
|
|
chars.add(c);
|
|
|
|
|
}
|
|
|
|
|
for (char c : symbols.toCharArray()) {
|
|
|
|
|
chars.add(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SecureRandom random = new SecureRandom();
|
|
|
|
|
StringBuilder password = new StringBuilder(length);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
|
char randomChar = chars.get(random.nextInt(chars.size()));
|
|
|
|
|
password.append(randomChar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确保密码包含至少一个字母、一个数字和一个符号
|
|
|
|
|
if (!password.toString().matches(".*[a-zA-Z].*")) {
|
|
|
|
|
password.setCharAt(random.nextInt(length), upperCase.charAt(random.nextInt(upperCase.length())));
|
|
|
|
|
}
|
|
|
|
|
if (!password.toString().matches(".*[0-9].*")) {
|
|
|
|
|
password.setCharAt(random.nextInt(length), numbers.charAt(random.nextInt(numbers.length())));
|
|
|
|
|
}
|
|
|
|
|
if (!password.toString().matches(".*[!@#$%^&*()_+\\-=\\[\\]{}|;:',.<>?].*")) {
|
|
|
|
|
password.setCharAt(random.nextInt(length), symbols.charAt(random.nextInt(symbols.length())));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return password.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:执行一个shell指令,直到结束
|
|
|
|
|
* 作者:黄海
|
|
|
|
|
* 时间:2019-01-19
|
|
|
|
|
*
|
|
|
|
|
* @param cmd
|
|
|
|
|
*/
|
|
|
|
|
public static void ExecShellWaitFinish(String cmd) {
|
|
|
|
|
Process process = null;
|
|
|
|
|
String ls_1;
|
|
|
|
|
try {
|
|
|
|
|
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
|
|
|
|
|
process = processBuilder.start();
|
|
|
|
|
|
|
|
|
|
BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
|
|
|
|
|
while ((ls_1 = bufferedReader1.readLine()) != null)
|
|
|
|
|
log.info(ls_1);
|
|
|
|
|
bufferedReader1.close();
|
|
|
|
|
process.getOutputStream().close();
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
if (process.waitFor() == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:验证是否为手机号
|
|
|
|
|
* 作者:黄海
|
|
|
|
@ -596,36 +399,6 @@ public class CommonUtil {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:获取查询总数量的SQL语句
|
|
|
|
|
* 作者:黄海
|
|
|
|
|
* 时间:2021-11-01
|
|
|
|
|
*
|
|
|
|
|
* @param findSql
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getTotalSql(String findSql) {
|
|
|
|
|
String totalRowSql = "select count(*) from (" + findSql + ") as t100";
|
|
|
|
|
return totalRowSql;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:接字符串,方便IN方式查询
|
|
|
|
|
* 作者:黄海
|
|
|
|
|
* 时间:2021-10-22
|
|
|
|
|
*
|
|
|
|
|
* @param list
|
|
|
|
|
* @param key
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getIds(List<Record> list, String key) {
|
|
|
|
|
String s = "";
|
|
|
|
|
if (list.isEmpty()) return "-1";
|
|
|
|
|
for (Record record1 : list) s += "'" + record1.getStr(key) + "',";
|
|
|
|
|
s = s.substring(0, s.length() - 1);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static boolean checkPass(String pass) {
|
|
|
|
|
//注释掉必须要有符号这个要求:&& pass.matches(".*[~!@#$%^&*\\.?]{1,}.*")
|
|
|
|
@ -697,123 +470,6 @@ public class CommonUtil {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static String connectionTestQuery = "select 1";
|
|
|
|
|
// 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
|
|
|
|
|
private static int maxPoolSize = 10;
|
|
|
|
|
// 一个连接 idle 状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟
|
|
|
|
|
private static long idleTimeoutMs = 600000;
|
|
|
|
|
private static long maxLifetimeMs = 1800000;
|
|
|
|
|
// 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生 SQLException, 缺省:30秒
|
|
|
|
|
private static long connectionTimeoutMs = 30000;
|
|
|
|
|
|
|
|
|
|
public static HikariCpPlugin createHikariCpPlugin(String url, String username, String password, String driverClass) {
|
|
|
|
|
HikariCpPlugin hp = new HikariCpPlugin(url, username, password, driverClass);
|
|
|
|
|
hp.setConnectionTestQuery(connectionTestQuery);
|
|
|
|
|
hp.setConnectionTimeout(connectionTimeoutMs);
|
|
|
|
|
hp.setIdleTimeout(idleTimeoutMs);
|
|
|
|
|
hp.setMaxLifetime(maxLifetimeMs);
|
|
|
|
|
hp.setMaximumPoolSize(maxPoolSize);
|
|
|
|
|
return hp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean isIP(String str) {
|
|
|
|
|
// IP地址的正则表达式
|
|
|
|
|
String ipPattern = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";
|
|
|
|
|
return Pattern.matches(ipPattern, str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean isDomain(String str) {
|
|
|
|
|
// 域名的正则表达式
|
|
|
|
|
String domainPattern = "^(?![0-9]+$)(?!-)[a-zA-Z0-9-]{1,63}(?<!-)(\\.[a-zA-Z]{2,})+$";
|
|
|
|
|
return Pattern.matches(domainPattern, str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:判断字符串是不是能转换为整数
|
|
|
|
|
*
|
|
|
|
|
* @param str
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static boolean isInteger(String str) {
|
|
|
|
|
try {
|
|
|
|
|
double doubleValue = Double.parseDouble(str);
|
|
|
|
|
int intValue = (int) doubleValue;
|
|
|
|
|
return true;
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:判断字符串是不是能转换为浮点数
|
|
|
|
|
*
|
|
|
|
|
* @param str
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static boolean isDouble(String str) {
|
|
|
|
|
try {
|
|
|
|
|
Double.parseDouble(str);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:判断字符串是不是能转换为日期
|
|
|
|
|
*
|
|
|
|
|
* @param str
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static boolean isDate(String str) {
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
|
|
try {
|
|
|
|
|
sdf.parse(str);
|
|
|
|
|
return true;
|
|
|
|
|
} catch (ParseException e) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:移除小括号,以及小括号内的文字内容
|
|
|
|
|
*
|
|
|
|
|
* @param str
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String removeKuoHao(String str) {
|
|
|
|
|
str = str.replace("\n", "");
|
|
|
|
|
String output = str.replaceAll("\\(.*?\\)", "");
|
|
|
|
|
output = output.replaceAll("\\(.*?\\)", "");
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:获取小写的uuid,去掉-线的
|
|
|
|
|
*
|
|
|
|
|
* @param bigUuid
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getSmallUuid(String bigUuid) {
|
|
|
|
|
return bigUuid.replace("-", "").toLowerCase();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:获取大写的uuid
|
|
|
|
|
*
|
|
|
|
|
* @param smallUuid
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getBigUuid(String smallUuid) {
|
|
|
|
|
//天喻的GUID号是去掉了-线的,我需要把它补全
|
|
|
|
|
StringBuilder sb = new StringBuilder(smallUuid);
|
|
|
|
|
sb.insert(8, "-");
|
|
|
|
|
sb.insert(13, "-");
|
|
|
|
|
sb.insert(18, "-");
|
|
|
|
|
sb.insert(23, "-");
|
|
|
|
|
return sb.toString().toUpperCase();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:从身份证号中提取出生日期
|
|
|
|
|
*
|
|
|
|
@ -831,13 +487,4 @@ public class CommonUtil {
|
|
|
|
|
|
|
|
|
|
return year + "-" + month + "-" + day;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取当前时间
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getCurrentTime() {
|
|
|
|
|
return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|