一、不同类型数据
1.1 Json
1.2 字符串
package com.gemenyaofei.integration.domain.common.utils;
import cn.hutool.core.text.StrFormatter;
import com.alibaba.fastjson.JSON;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Author ljh
* @Date 2022/11/8
* @Desc StringUtils
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils {
private static String EMAIL = "^([a-zA-Z0-9]*[-_.]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$";
private static Pattern P_EMAIL;
private static Pattern P_MOBILE;
private static Pattern P_USERNAME;
private static final String NULLSTR = "";
private static final char SEPARATOR = '_';
private static final String START = "*";
private static final String QUESTION = "?";
private static final String COMMA = ",";
public StringUtils() {
}
public static <T> T nvl(T value, T defaultValue) {
return value != null ? value : defaultValue;
}
public static boolean isEmpty(Collection<?> coll) {
return isNull(coll) || coll.isEmpty();
}
public static boolean isNotEmpty(Collection<?> coll) {
return !isEmpty(coll);
}
public static boolean isEmpty(Object[] objects) {
return isNull(objects) || objects.length == 0;
}
public static boolean isNotEmpty(Object[] objects) {
return !isEmpty(objects);
}
public static boolean isEmpty(Map<?, ?> map) {
return isNull(map) || map.isEmpty();
}
public static boolean isNotEmpty(Map<?, ?> map) {
return !isEmpty(map);
}
public static boolean isEmpty(String str) {
return isNull(str) || "".equals(str.trim());
}
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
public static boolean isNull(Object object) {
return object == null;
}
public static boolean isNotNull(Object object) {
return !isNull(object);
}
public static boolean isArray(Object object) {
return isNotNull(object) && object.getClass().isArray();
}
public static String trim(String str) {
return str == null ? "" : str.trim();
}
public static String substring(String str, int start) {
if (str == null) {
return "";
} else {
if (start < 0) {
start += str.length();
}
if (start < 0) {
start = 0;
}
return start > str.length() ? "" : str.substring(start);
}
}
public static String substring(String str, int start, int end) {
if (str == null) {
return "";
} else {
if (end < 0) {
end += str.length();
}
if (start < 0) {
start += str.length();
}
if (end > str.length()) {
end = str.length();
}
if (start > end) {
return "";
} else {
if (start < 0) {
start = 0;
}
if (end < 0) {
end = 0;
}
return str.substring(start, end);
}
}
}
public static String format(String template, Object... params) {
return !isEmpty(params) && !isEmpty(template) ? StrFormatter.format(template, params) : template;
}
public static String toUnderScoreCase(String str) {
if (str == null) {
return null;
} else {
StringBuilder sb = new StringBuilder();
boolean preCharIsUpperCase = true;
boolean curreCharIsUpperCase = true;
boolean nexteCharIsUpperCase = true;
for(int i = 0; i < str.length(); ++i) {
char c = str.charAt(i);
if (i > 0) {
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
} else {
preCharIsUpperCase = false;
}
curreCharIsUpperCase = Character.isUpperCase(c);
if (i < str.length() - 1) {
nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
}
if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
sb.append('_');
} else if (i != 0 && !preCharIsUpperCase && curreCharIsUpperCase) {
sb.append('_');
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
}
public static <T> T cast(Object obj) {
return (T) obj;
}
public static String upperCaseFirst(String name) {
return isBlank(name) ? name : name.substring(0, 1).toUpperCase() + name.substring(1);
}
public static String lowerCaseFirst(String name) {
return isBlank(name) ? name : name.substring(0, 1).toLowerCase() + name.substring(1);
}
public static Boolean isEmail(String email) {
Matcher m = P_EMAIL.matcher(email);
return m.matches();
}
public static boolean isMobileNO(String mobiles) {
Matcher m = P_MOBILE.matcher(mobiles);
return m.matches();
}
public static String humpToUnderline(String string) {
StringBuilder stringBuilder = new StringBuilder(string);
int num = 0;
for(int i = 0; i < string.length(); ++i) {
if (Character.isUpperCase(string.charAt(i))) {
stringBuilder.insert(i + num, "_");
++num;
}
}
return stringBuilder.toString();
}
public static boolean isHttpUrl(String path) {
return startsWithIgnoreCase(path, "http");
}
public static String numberAfterFillZero(String str, int length) {
return str + String.format("%0" + (length - str.length()) + "d", 0);
}
public static String numberBeforeFillZero(String str, int length) {
return String.format("%0" + length + "d", str);
}
public static String toJson(Object obj) {
return JSON.toJSONString(obj);
}
public static boolean inStringIgnoreCase(String str, String... strs) {
if (str != null && strs != null) {
String[] var2 = strs;
int var3 = strs.length;
for(int var4 = 0; var4 < var3; ++var4) {
String s = var2[var4];
if (str.equalsIgnoreCase(trim(s))) {
return true;
}
}
}
return false;
}
public static String convertToCamelCase(String name) {
StringBuilder result = new StringBuilder();
if (name != null && !name.isEmpty()) {
if (!name.contains("_")) {
return name.substring(0, 1).toUpperCase() + name.substring(1);
} else {
String[] camels = name.split("_");
String[] var3 = camels;
int var4 = camels.length;
for(int var5 = 0; var5 < var4; ++var5) {
String camel = var3[var5];
if (!camel.isEmpty()) {
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
}
return result.toString();
}
} else {
return "";
}
}
public static String toCamelCase(String s) {
if (s == null) {
return null;
} else {
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for(int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if (c == '_') {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}
}
public static boolean matches(String str, List<String> strs) {
if (!isEmpty(str) && !isEmpty((Collection)strs)) {
Iterator var2 = strs.iterator();
String testStr;
do {
if (!var2.hasNext()) {
return false;
}
testStr = (String)var2.next();
} while(!matches(str, testStr));
return true;
} else {
return false;
}
}
public static boolean matches(String str, String... strs) {
if (!isEmpty(str) && !isEmpty((Object[])strs)) {
String[] var2 = strs;
int var3 = strs.length;
for(int var4 = 0; var4 < var3; ++var4) {
String testStr = var2[var4];
if (matches(str, testStr)) {
return true;
}
}
return false;
} else {
return false;
}
}
public static boolean matches(String str, String pattern) {
if (!isEmpty(pattern) && !isEmpty(str)) {
pattern = pattern.replaceAll("\\s*", "");
int beginOffset = 0;
String remainingURI = str;
String prefixPattern = "";
String suffixPattern = "";
boolean result = false;
do {
int formerStarOffset = indexOf(pattern, "*", beginOffset);
prefixPattern = substring(pattern, beginOffset, formerStarOffset > -1 ? formerStarOffset : pattern.length());
result = remainingURI.contains(prefixPattern);
if (formerStarOffset == -1) {
return result;
}
if (!result) {
return false;
}
if (!isEmpty(prefixPattern)) {
remainingURI = substringAfter(str, prefixPattern);
}
int latterStarOffset = indexOf(pattern, "*", formerStarOffset + 1);
suffixPattern = substring(pattern, formerStarOffset + 1, latterStarOffset > -1 ? latterStarOffset : pattern.length());
result = remainingURI.contains(suffixPattern);
if (!result) {
return false;
}
if (!isEmpty(suffixPattern)) {
remainingURI = substringAfter(str, suffixPattern);
}
beginOffset = latterStarOffset + 1;
} while(!isEmpty(suffixPattern) && !isEmpty(remainingURI));
return true;
} else {
return false;
}
}
static {
P_EMAIL = Pattern.compile(EMAIL);
P_MOBILE = Pattern.compile("^((1[3-8][0-9]))\\d{8}$");
P_USERNAME = Pattern.compile("^([a-zA-Z][a-zA-Z0-9]*[-_.]?[a-zA-Z0-9]+)*$");
}
}
1.3 集合
1.4 时间日期
package com.gemenyaofei.integration.app.utils;
import com.gemenyaofei.common.core.utils.StringUtils;
import com.gemenyaofei.integration.domain.common.exception.BizException;
import com.gemenyaofei.integration.domain.common.exception.ErrorCodeEnum;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Stream;
/**
* @Author ljh
* @Date 2021/8/26
* @Desc 时间, 日期相关工具类
*/
public class DateTimeUtils {
/**
* yyyy-MM-dd HH:mm:ss
*/
public static final String DATE_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
/**
* yyyyMMddHHmmss
*/
public static final String DATE_FORMAT_FULL_CODE = "yyyyMMddHHmmss";
/**
* yyyy/MM/dd HH:mm:ss
*/
public static final String DATE_FORMAT_FULL_SLASH = "yyyy/MM/dd HH:mm:ss";
/**
* yyyy-MM-dd
*/
public static final String DATE_FORMAT_YMD = "yyyy-MM-dd";
/**
* yyyy-MM-dd
*/
public static final String DATE_FORMAT_YM = "yyyy-MM";
/**
* yyyy/MM/dd
*/
public static final String DATE_FORMAT_YMD_SLASH = "yyyy/MM/dd";
/**
* yyyyMMdd
*/
public static final String DATE_FORMAT_YMD_CODE = "yyyyMMdd";
/**
* yyyy-MM
*/
public static final String DATE_FORMAT_YYMM = "yyyy-MM";
/**
* yyyy/MM
*/
public static final String DATE_FORMAT_YYMM_SLASH = "yyyy/MM";
/**
* yyyy
*/
public static final String DATE_FORMAT_YY = "yyyy";
/**
* MM
*/
public static final String DATE_FORMAT_MM = "MM";
/**
* HH:mm:ss
*/
public static final String DATE_FORMAT_HMS = "HH:mm:ss";
/**
* HH:mm
*/
public static final String DATE_FORMAT_HHMM = "HH:mm";
/**
* mm:ss
*/
public static final String DATE_FORMAT_MMSS = "mm:ss";
/**
* HH
*/
public static final String DATE_FORMAT_HH = "HH";
/**
* yyyy-MM-dd'T'HH:mm:ss.SSSXXX 2001-07-04T12:08:56.235-07:00
*/
public static final String DATE_FORMAT_FULL_UTCSX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
/**
* yyyy-MM-dd'T'HH:mm:ss.SSSZ 2001-07-04T12:08:56.235-0700
*/
public static final String DATE_FORMAT_FULL_UTCSZ = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";
/**
* 13位时间戳(毫秒级)
*/
public static final String DATE_FORMAT_LONG_MS = "longms";
/**
* 10位时间戳(秒级)
*/
public static final String DATE_FORMAT_LONG_S = "longs";
/**
* 正则匹配日期时间表达式
*/
public static final String REGEX_YMD = "[0-9]{4}-[0-9]{2}-[0-9]{2}";
public static final String REGEX_YMD_HMS = "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}";
public static final String REGEX_YMD_HMS_SSSXXX = "[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}[\\+\\-][0-9]{2}[\\:][0-9]{2}";
public static final String REGEX_YMD_HMS_SSSZ = "[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}[\\+\\-][0-9]{4}";
public static final String REGEX_YMD_SLASH = "[0-9]{4}/[0-9]{2}/[0-9]{2}";
public static final String REGEX_YMD_HMS_SLASH = "[0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}";
public static final String REGEX_YMD_CODE = "[0-9]{8}";
public static final String REGEX_YMD_HMS_CODE = "[0-9]{14}";
public static final String REGEX_TIMESTAMP_MS = "[0-9]{13}";
public static final String REGEX_TIMESTAMP_S = "[0-9]{10}";
/**
* 获得今日时间戳 yyyyMMddHHmmss格式字符串
*
* @return String
*/
public static String getCurrentTimeStamp() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_FULL_CODE);
LocalDateTime today = LocalDateTime.now();
return today.format(df);
}
/**
* 将Date转换为yyyyMMddHHmmss格式字符串
*
* @return String
*/
public static String dateFormatFull(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT_FULL_CODE);
return simpleDateFormat.format(date);
}
/**
* 将Date转换为字符串
*
* @return String
*/
public static String dateToStr(Date date, String format) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
return simpleDateFormat.format(date);
}
/**
* 将yyyyMMddHHmmss转换Date为格式字符串
*
* @return String
*/
public static Date fullToDate(String timestamp) {
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT_FULL_CODE);
Date date = null;
try {
date = format.parse(timestamp);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
/**
* 字符串去掉符号,转换为14位yyyyMMddHHmmss时间字符串,补充时间为最开始
*
* @param time 必须是年份日期开头的日期时间类型
* @return
*/
public static String strFormatStartTime(String time) {
String regEx = "[^0-9]";
time = time.replaceAll(regEx, "");
if (time.length() < 14) {
return StringUtils.numberAfterFillZero(time, 14);
}
return time;
}
/**
* 字符串去掉符号,转换为14位时间yyyyMMddHHmmss时间字符串,补充时间为最后
*
* @param time 必须是年份日期开头的日期时间类型
* @return
*/
public static String strFormatEndTime(String time) {
String regEx = "[^0-9]";
time = time.replaceAll(regEx, "");
if (time.length() < 8) {
time = StringUtils.numberAfterFillZero(time, 8);
time = time + "595959";
return time;
}
return StringUtils.numberAfterFillZero(time, 14);
}
/**
* 获得今日日期 yyyy-MM-dd格式字符串
*
* @return String
*/
public static String getToday() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_YMD);
LocalDate today = LocalDate.now();
String nowDate = today.format(df);
return nowDate;
}
/**
* 获得当前日期时间 yyyy-MM-dd HH:mm:ss格式字符串
*
* @return String
*/
public static String getCurrentDateTime() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_FULL);
LocalDateTime dateTime = LocalDateTime.now();
String nowDateTime = dateTime.format(df);
return nowDateTime;
}
/**
* 获得当前日期时间 yyyy-MM-dd HH:mm:ss格式字符串
*
* @return String
*/
public static String getDateFormatStrFromDate(String dateFormat, Date date) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(dateFormat);
Instant instant = date.toInstant();
LocalDateTime dateTime = LocalDateTime.ofInstant(instant,ZoneId.systemDefault());
return dateTime.format(df);
}
/**
* 获取当天开始时间 2019-06-12 00:00:00 LocalDateTime类型
*
* @return LocalDateTime
*/
public static LocalDateTime getTodayBeginTime() {
LocalDate currentDay = LocalDate.now();
return LocalDateTime.of(currentDay, LocalTime.MIN);
}
/**
* localdatetime转换为13位时间戳
*
* @param localDateTime 转换格式
* @return
*/
public static Long localDateTimeToLong(LocalDateTime localDateTime) {
return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* localdatetime转换为10位时间戳
*
* @param localDateTime 转换格式
* @return
*/
public static Long localDateTimeToLongs(LocalDateTime localDateTime) {
return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
}
/**
* 获取当天时间的前一天
*
* @param dateFormat 转换格式
* @return
*/
public static String getYesterdayByFormat(String dateFormat) {
return LocalDateTime.now().plusDays(-1).format(DateTimeFormatter.ofPattern(dateFormat));
}
/**
* 根据localDateTime获取前一天
*
* @param localDateTime 时间
* @return
*/
public static Long getYesterdayToLong(LocalDateTime localDateTime) {
return localDateTime.plusDays(-1).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* 根据localDateTime获取前一天
*
* @param localDateTime 时间
* @return
*/
public static Long getYesterdayToLongs(LocalDateTime localDateTime) {
return localDateTime.plusDays(-1).atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
}
/**
* 获取当天时间的前一天开始时间
*
* @param dateFormat 转换格式
* @return
*/
public static String getYesterdayBeginByFormat(String dateFormat) {
return getTodayBeginTime().plusDays(-1).format(DateTimeFormatter.ofPattern(dateFormat));
}
/**
* 获取当天时间的前一天结束时间
*
* @param dateFormat 转换格式
* @return
*/
public static String getYesterdayEndByFormat(String dateFormat) {
return getTodayEndTime().plusDays(-1).format(DateTimeFormatter.ofPattern(dateFormat));
}
/**
* 获取当天结束时间 2019-06-12 23:59:59
*
* @return LocalDateTime
*/
public static LocalDateTime getTodayEndTime() {
LocalDate currentDay = LocalDate.now();
return LocalDateTime.of(currentDay, LocalTime.MAX);
}
/**
* LocalDate转化为指定格式字符串
*
* @param fromDate
* @param dateFormat yyyy-MM-dd | yyyy/MM/dd | yyyyMMdd | yyyy-MM | yyyy/MM | yyyyMM
* @return
*/
public static String localDate2Str(LocalDate fromDate, String dateFormat) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(dateFormat);
String dateStr = fromDate.format(df);
return dateStr;
}
/**
* LocalDateTime转化为指定格式字符串
*
* @param fromDateTime
* @param dateTimeFormat yyyy-MM-dd HH:mm:ss | yyyy/MM/dd HH:mm:ss | yyyyMMdd HH:mm:ss | ...
* @return
*/
public static String localDateTime2Str(LocalDateTime fromDateTime, String dateTimeFormat) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(dateTimeFormat);
String localTime = fromDateTime.format(df);
return localTime;
}
/**
* 日期格式字符串转化为指定格式的LocalDate日期
*
* @param beginDate yyyy-MM-dd | yyyy/MM/dd | yyyyMMdd
* @param dateFormat yyyy-MM-dd | yyyy/MM/dd | yyyyMMdd
* @return
*/
public static LocalDate str2LocalDate(String beginDate, String dateFormat) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(dateFormat);
try {
LocalDate fromDate = LocalDate.parse(beginDate, df);
return fromDate;
} catch (Exception e) {
return null;
}
}
/**
* 时间格式字符串转化为指定格式的LocalDateTime时间
*
* @param beginDateTime yyyy-MM-dd HH:mm:ss | yyyy/MM/dd HH:mm:ss | yyyyMMdd HH:mm:ss
* @param dateFormat yyyy-MM-dd HH:mm:ss | yyyy/MM/dd HH:mm:ss | yyyyMMdd HH:mm:ss
* @return
*/
public static LocalDateTime str2LocalDateTime(String beginDateTime, String dateFormat) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(dateFormat);
try {
LocalDateTime fromDateTime = LocalDateTime.parse(beginDateTime, df);
return fromDateTime;
} catch (Exception e) {
return null;
}
}
/**
* Date转为LocalDateTime
*
* @param date Date类型
* @return LocalDateTime
*/
public static LocalDateTime date2LocalDateTime(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
/**
* Long 毫秒级 类型时间戳转化为LocalDateTime
*
* @param dateTimeLong 毫秒数
* @return LocalDateTime
*/
public static LocalDateTime longms2LocalDateTime(Long dateTimeLong) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTimeLong), ZoneId.systemDefault());
}
/**
* Long 秒级 类型时间戳转化为LocalDateTime
*
* @param dateTimeLong 毫秒数
* @return LocalDateTime
*/
public static LocalDateTime longs2LocalDateTime(Long dateTimeLong) {
return LocalDateTime.ofInstant(Instant.ofEpochSecond(dateTimeLong), ZoneId.systemDefault());
}
/**
* Long类型时间戳转化为时间字符串
*
* @param dateTimeLong 毫秒数
* @return string
*/
public static String longToStr(Long dateTimeLong, String dateFormat) {
if (dateTimeLong == null) {
return null;
}
DateTimeFormatter ftf = DateTimeFormatter.ofPattern(dateFormat);
return ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(dateTimeLong), ZoneId.systemDefault()));
}
/**
* Long类型时间戳转化为时间字符串
*
* @param dateTimeLong 秒数
* @return string
*/
public static String intTimeToStr(Integer dateTimeLong, String dateFormat) {
if (dateTimeLong == null) {
return null;
}
DateTimeFormatter ftf = DateTimeFormatter.ofPattern(dateFormat);
return ftf.format(LocalDateTime.ofInstant(Instant.ofEpochSecond(dateTimeLong), ZoneId.systemDefault()));
}
/**
* 日期时间str转为日期str (yyyy-MM-dd HH:mm:ss -> yyyy-MM-dd)
*
* @param fullDate yyyy-MM-dd HH:mm:ss格式字符串
* @return yyyy-MM-dd格式字符串
*/
public static String fullDate2Date(String fullDate) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_FULL);
LocalDate localDate = LocalDateTime.parse(fullDate, df).toLocalDate();
return localDate2Str(localDate, DATE_FORMAT_YMD);
}
/**
* 日期格式转换
*
* @param day 年月日格式字符串
* @param fmt1 当前格式 yyyy-MM-dd | yyyy/MM/dd | yyyyMMdd
* @param fmt2 期望转换的格式 yyyy-MM-dd | yyyy/MM/dd | yyyyMMdd
* @return String
*/
public static String dateFormatConvert(String day, String fmt1, String fmt2) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(fmt2);
return str2LocalDate(day, fmt1).format(dtf);
}
/**
* 日期时间格式转换
*
* @param dayTime 年月日时分秒格式字符串
* @param fmt1 当前格式 yyyy-MM-dd HH:mm:ss | yyyy/MM/dd HH:mm:ss | yyyyMMddHHmmss
* @param fmt2 期望转换的格式 yyyy-MM-dd HH:mm:ss | yyyy/MM/dd HH:mm:ss | yyyyMMddHHmmss
* @return String
*/
public static String dateTimeFormatConvert(String dayTime, String fmt1, String fmt2) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(fmt2);
return str2LocalDateTime(dayTime, fmt1).format(dtf);
}
/**
* 日期加减天数
*
* @param day yyyy-MM-dd格式字符串
* @param d 整数(正为加,负为减)
* @return String
*/
public static String addDays(String day, int d) {
LocalDate localDate = str2LocalDate(day, DATE_FORMAT_YMD).plusDays(d);
return localDate2Str(localDate, DATE_FORMAT_YMD);
}
/**
* 日期时间加减天数
*
* @param dayTime yyyy-MM-dd HH:mm:ss格式字符串
* @param d 天数(正为加,负为减)
* @return String
*/
public static String addTimeDays(String dayTime, int d) {
LocalDateTime localDateTime = str2LocalDateTime(dayTime, DATE_FORMAT_FULL).plusDays(d);
return localDateTime2Str(localDateTime, DATE_FORMAT_FULL);
}
/**
* 时间加减分钟数
*
* @param dayTime yyyy-MM-dd HH:mm:ss格式字符串
* @param min 分钟数(正为加,负为减)
* @return String
*/
public static String addMinutes(String dayTime, long min) {
LocalDateTime localDateTime = str2LocalDateTime(dayTime, DATE_FORMAT_FULL).plusMinutes(min);
return localDateTime2Str(localDateTime, DATE_FORMAT_FULL);
}
/**
* 日期加减周数 获取某日前几周或后几周的日期
*
* @param day yyyy-MM-dd格式字符串
* @param week 周数(正为加,负为减)
* @return String
*/
public static String addWeeks(String day, long week) {
LocalDate localDate = str2LocalDate(day, DATE_FORMAT_YMD).plusWeeks(week);
return localDate2Str(localDate, DATE_FORMAT_YMD);
}
/**
* 日期加减月数
*
* @param day yyyy-MM-dd格式字符串
* @param month 月数(正为加,负为减)
* @return String
*/
public static String addMonths(String day, long month) {
LocalDate localDate = str2LocalDate(day, DATE_FORMAT_YMD).plusMonths(month);
return localDate2Str(localDate, DATE_FORMAT_YMD);
}
/**
* 日期加减年数
*
* @param day yyyy-MM-dd格式字符串
* @param year 年数(正为加,负为减)
* @return String
*/
public static String addYears(String day, long year) {
LocalDate localDate = str2LocalDate(day, DATE_FORMAT_YMD).plusYears(year);
return localDate2Str(localDate, DATE_FORMAT_YMD);
}
/**
* 获取两日期的间隔天数
*
* @param start yyyy-MM-dd格式字符串
* @param end yyyy-MM-dd格式字符串
* @return long
*/
public static long getDaysInterval(String start, String end) {
return (str2LocalDate(end, DATE_FORMAT_YMD).toEpochDay() - str2LocalDate(start, DATE_FORMAT_YMD).toEpochDay());
}
/**
* 获取两日期时间的间隔秒数
*
* @param start yyyy-MM-dd HH:mm:ss格式字符串
* @param end yyyy-MM-dd HH:mm:ss格式字符串
* @return long
*/
public static long getSecondsInterval(String start, String end) {
Duration between = Duration.between(str2LocalDateTime(start, DATE_FORMAT_FULL), str2LocalDateTime(end, DATE_FORMAT_FULL));
return between.getSeconds();
}
/**
* 获取两个日期间隔的所有日期
*
* @param start yyyy-MM-dd格式字符串
* @param end yyyy-MM-dd格式字符串
* @return List<String>
*/
public static List<String> getDayArrayBetween(String start, String end) {
List<String> list = new ArrayList<>();
LocalDate localDateStart = str2LocalDate(start, DATE_FORMAT_YMD);
LocalDate localDate1End = str2LocalDate(end, DATE_FORMAT_YMD);
long distance = ChronoUnit.DAYS.between(localDateStart, localDate1End);
if (distance < 1) {
return list;
}
Stream.iterate(localDateStart, d -> d.plusDays(1)).limit(distance + 1).forEach(x -> list.add(localDate2Str(x, DATE_FORMAT_YMD)));
return list;
}
/**
* 获取日期一定范围内的所有日期
*
* @param day yyyy-MM-dd格式字符串
* @param range 负数代表前几天 正数代表后几天
* @return List<String>
*/
public static List<String> getDayArrayRange(String day, int range) {
List<String> list = new ArrayList<>();
LocalDate localDateStart = str2LocalDate(day, DATE_FORMAT_YMD);
LocalDate localDate1End = str2LocalDate(addDays(day, range), DATE_FORMAT_YMD);
if (range > 0) {
long distance = ChronoUnit.DAYS.between(localDateStart, localDate1End);
if (distance < 1) {
return list;
}
Stream.iterate(localDateStart, d -> d.plusDays(1)).limit(distance + 1).forEach(x -> list.add(localDate2Str(x, DATE_FORMAT_YMD)));
return list;
} else {
long distance = ChronoUnit.DAYS.between(localDate1End, localDateStart);
if (distance < 1) {
return list;
}
Stream.iterate(localDateStart, d -> d.minusDays(1)).limit(distance + 1).forEach(x -> list.add(localDate2Str(x, DATE_FORMAT_YMD)));
Collections.reverse(list);
return list;
}
}
/**
* 日期时间比较大小
*
* @param start yyyy-MM-dd HH:mm:ss格式字符串
* @param end yyyy-MM-dd HH:mm:ss格式字符串
* @return true: start > end | false: start < end
*/
public static boolean compareDateTime(String start, String end) {
return str2LocalDateTime(start, DATE_FORMAT_FULL).isAfter(str2LocalDateTime(end, DATE_FORMAT_FULL));
}
/**
* 日期比较大小
*
* @param start yyyy-MM-dd格式字符串
* @param end yyyy-MM-dd格式字符串
* @return true: start > end | false: start < end
*/
public static boolean compareDate(String start, String end) {
return str2LocalDate(start, DATE_FORMAT_YMD).isAfter(str2LocalDate(end, DATE_FORMAT_YMD));
}
/**
* 获得一年后的日期字符串
*/
public static String getOneYearLaterDate(String beginDate, String dateFormat) {
LocalDate fromDate = str2LocalDate(beginDate, dateFormat);
if (fromDate != null) {
LocalDate toDate = fromDate.plus(1, ChronoUnit.YEARS);
return localDate2Str(toDate, dateFormat);
}
return null;
}
/**
* 获得一年后的日期时间字符串
*/
public static String getOneYearLaterDateTime(String beginDate, String dateFormat) {
LocalDateTime fromDate = str2LocalDateTime(beginDate, dateFormat);
if (fromDate != null) {
LocalDateTime toDate = fromDate.plus(1, ChronoUnit.YEARS);
return localDateTime2Str(toDate, dateFormat);
}
return null;
}
/**
* 获取本周第一天(周一) yyyy-MM-dd格式字符串
*
* @return String
*/
public static String getFirstDayOfCurrentWeek() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_YMD);
LocalDate d1 = LocalDate.now().plusWeeks(0).with(DayOfWeek.MONDAY);
String nowDate = d1.format(df);
return nowDate;
}
/**
* 获取本周开始时间 2019-06-10 00:00:00 LocalDateTime类型
*
* @return LocalDateTime
*/
public static LocalDateTime getWeekBeginTime() {
LocalDateTime currentDateTime = LocalDateTime.now();
int currentOrdinal = currentDateTime.getDayOfWeek().ordinal();
return currentDateTime.minusDays(currentOrdinal)
.withHour(0).withMinute(0).withSecond(0).withNano(0);
}
/**
* 获取本周最后一天(周日) yyyy-MM-dd格式字符串
*
* @return String
*/
public static String getLastDayOfCurrentWeek() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_YMD);
LocalDate d2 = LocalDate.now().plusWeeks(0).with(DayOfWeek.SUNDAY);
String nowDate = d2.format(df);
return nowDate;
}
/**
* 获取本周结束时间 2019-06-16 23:59:59
*
* @return LocalDateTime
*/
public static LocalDateTime getWeekEndTime() {
LocalDateTime currentDateTime = LocalDateTime.now();
int currentOrdinal = currentDateTime.getDayOfWeek().ordinal();
return currentDateTime.plusDays(6 - currentOrdinal)
.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
}
/**
* 获取本周 周几所在的日期 yyyy-MM-dd格式字符串
*
* @return String
* @desc 参数w值范围1~7, 如:w=2 返回本周周二的日期
*/
public static String getWeekDay(int w) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_YMD);
LocalDate d2 = LocalDate.now().plusWeeks(0).with(DayOfWeek.of(w));
return d2.format(df);
}
/**
* 返回今天是周几
*
* @return 1 | 2 | 3 | 4 | 5 | 6 | 7
*/
public static Integer getTodayIndexOfWeek() {
return LocalDate.now().getDayOfWeek().getValue();
}
/**
* 返回某日是周几
*
* @param day yyyy-MM-dd格式
* @return 1 | 2 | 3 | 4 | 5 | 6 | 7
*/
public static Integer getDayIndexOfWeek(String day) {
return str2LocalDate(day, DATE_FORMAT_YMD).getDayOfWeek().getValue();
}
/**
* 返回本周周一至周日日期数组
*
* @return [yyyy-MM-dd, ... ,yyyy-MM-dd]
*/
public static List<String> getArrayOfCurrentWeek() {
List<String> list = new ArrayList<>();
Stream.iterate(1, n -> n + 1).limit(7).forEach(x -> list.add(getWeekDay(x)));
return list;
}
/**
* 返回本周周一至今日日期数组
*
* @return [yyyy-MM-dd, ... ,yyyy-MM-dd]
*/
public static List<String> getTodayArrayOfCurrentWeek() {
List<String> list = new ArrayList<>();
Integer week = LocalDate.now().getDayOfWeek().getValue();
Stream.iterate(1, n -> n + 1).limit(week).forEach(x -> list.add(getWeekDay(x)));
return list;
}
/**
* 获取本月第一天 yyyy-MM-dd格式字符串
*
* @return
*/
public static String getFirstDayOfCurrentMonth() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_YMD);
LocalDate first = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
String date = first.format(df);
return date;
}
/**
* 获取本月最后一天 yyyy-MM-dd格式字符串
*
* @return
*/
public static String getLastDayOfCurrentMonth() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_YMD);
LocalDate last = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
String date = last.format(df);
return date;
}
/**
* 获取本年第一天 yyyy-MM-dd格式字符串
*
* @return
*/
public static String getFirstDayOfCurrentYear() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_YMD);
LocalDate first = LocalDate.now().plusYears(0).with(TemporalAdjusters.firstDayOfYear());
String date = first.format(df);
return date;
}
/**
* 获取本年最后一天 yyyy-MM-dd格式字符串
*
* @return
*/
public static String getLastDayOfCurrentYear() {
DateTimeFormatter df = DateTimeFormatter.ofPattern(DATE_FORMAT_YMD);
LocalDate last = LocalDate.now().plusYears(0).with(TemporalAdjusters.lastDayOfYear());
String date = last.format(df);
return date;
}
/**
* 获得毫秒数
*
* @param localDateTime
* @return
*/
public static long getTimestampOfDateTime(LocalDateTime localDateTime) {
ZoneId zone = ZoneId.systemDefault();
Instant instant = localDateTime.atZone(zone).toInstant();
return instant.toEpochMilli();
}
/**
* 根据出生日期(yyyy-MM-dd)字符串计算年龄
*
* @param birthDay
* @return
*/
public static Integer getAgeByBirthDay(String birthDay) {
LocalDate birthDate = str2LocalDate(birthDay, DATE_FORMAT_YMD);
LocalDate currentDate = LocalDate.now();
if (birthDate != null) {
if (currentDate.isBefore(birthDate)) {
return 0;
} else {
return birthDate.until(currentDate).getYears();
}
}
return null;
}
/**
* 判断闰年平年
* 闰年算法: 四年一闰,百年不闰,四百年再闰
*
* @param year yyyy-MM-dd格式字符串
* @return true闰年 | false平年
*/
public static boolean checkLeapYear(String year) {
return str2LocalDate(year, DATE_FORMAT_YMD).isLeapYear();
}
/**
* 获取当前日期所在季度的开始日期 或 结束日期
* 一年四季, 第一季度:1月-3月, 第二季度:4月-6月, 第三季度:7月-9月, 第四季度:10月-12月
*
* @param first true表示查询本季度开始日期 false表示查询本季度结束日期
* @return
*/
public static LocalDate getStartOrEndDayOfQuarter(boolean first) {
LocalDate today = LocalDate.now();
Month month = today.getMonth();
Month firstMonthOfQuarter = month.firstMonthOfQuarter();
Month endMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
if (first) {
return LocalDate.of(today.getYear(), firstMonthOfQuarter, 1);
} else {
return LocalDate.of(today.getYear(), endMonthOfQuarter, endMonthOfQuarter.length(today.isLeapYear()));
}
}
/**
* 获取某日所在季度的开始日期 或 结束日期
* 一年四季, 第一季度:1月-3月, 第二季度:4月-6月, 第三季度:7月-9月, 第四季度:10月-12月
*
* @param day yyyy-MM-dd格式字符串
* @param first true表示查询本季度开始日期 false表示查询本季度结束日期
* @return
*/
public static LocalDate getSomedayStartOrEndOfQuarter(String day, boolean first) {
LocalDate date = str2LocalDate(day, DATE_FORMAT_YMD);
Month month = date.getMonth();
Month firstMonthOfQuarter = month.firstMonthOfQuarter();
Month endMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
if (first) {
return LocalDate.of(date.getYear(), firstMonthOfQuarter, 1);
} else {
return LocalDate.of(date.getYear(), endMonthOfQuarter, endMonthOfQuarter.length(date.isLeapYear()));
}
}
public static LocalDateTime paraStartTime(List<String> times) {
if (times == null || times.isEmpty()) {
return null;
}
return str2LocalDateTime(strFormatStartTime(times.get(0)), DATE_FORMAT_FULL_CODE);
}
public static LocalDateTime paraEndTime(List<String> times) {
if (times == null || times.isEmpty() || times.size() <= 1) {
return null;
}
return str2LocalDateTime(strFormatEndTime(times.get(1)), DATE_FORMAT_FULL_CODE);
}
/**
* 国际时间转换为时间戳
*
* @param dateTime 格式: yyyy-MM-dd'T'HH:mm:ss.SSSXXX, 例:2022-01-06T12:12:26.000+00:00
* @param isMs true 是毫秒级, false是秒级
* @return
*/
public static Long internationalToTimeStamp(String dateTime, boolean isMs) {
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT_FULL_UTCSX);
try {
Date date = format.parse(dateTime);
if (isMs) {
return date.getTime();
} else {
return date.getTime() / 1000;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 时间戳字符串转换为long时间戳
*
* @param dateTime
* @return
*/
public static Long longTimeStrToLong(String dateTime) {
try {
return Long.valueOf(dateTime);
} catch (Exception e) {
return DateTimeUtils.internationalToTimeStamp(dateTime, true);
}
}
/**
* yyyy-MM-dd HH:mm:ss 转换为时间戳 毫秒级
*
* @param dateTime 格式: 2022-01-06 20:02:00
* @return
*/
public static Long formatfullToLong(String dateTime) {
LocalDateTime localDateTime = str2LocalDateTime(dateTime, DATE_FORMAT_FULL);
if (localDateTime != null) {
return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
return null;
}
/**
* 根据时间字符串判断时间格式
*
* @param date
* @return
*/
public static String getDatetimeFormat(String date) throws BizException {
date = date.trim();
//yyyy-MM-dd HH:mm:ss
if (Pattern.compile(REGEX_YMD_HMS).matcher(date).matches()) {
return DATE_FORMAT_FULL;
}
//yyyy/MM/dd HH:mm:ss
if (Pattern.compile(REGEX_YMD_HMS_SLASH).matcher(date).matches()) {
return DATE_FORMAT_FULL_SLASH;
}
//yyyyMMddHHmmss
if (Pattern.compile(REGEX_YMD_HMS_CODE).matcher(date).matches()) {
return DATE_FORMAT_FULL_CODE;
}
//yyyy-MM-dd
if (Pattern.compile(REGEX_YMD).matcher(date).matches()) {
return DATE_FORMAT_YMD;
}
//yyyy/MM/dd
if (Pattern.compile(REGEX_YMD_SLASH).matcher(date).matches()) {
return DATE_FORMAT_YMD_SLASH;
}
//yyyyMMdd
if (Pattern.compile(REGEX_YMD_CODE).matcher(date).matches()) {
return DATE_FORMAT_YMD_CODE;
}
//yyyy-MM-dd'T'HH:mm:ss.SSSXXX
if (Pattern.compile(REGEX_YMD_HMS_SSSXXX).matcher(date).matches()) {
return DATE_FORMAT_FULL_UTCSX;
}
//yyyy-MM-dd'T'HH:mm:ss.SSS Z
if (Pattern.compile(REGEX_YMD_HMS_SSSZ).matcher(date).matches()) {
return DATE_FORMAT_FULL_UTCSZ;
}
//13位时间戳
if (Pattern.compile(REGEX_TIMESTAMP_MS).matcher(date).matches()) {
return DATE_FORMAT_LONG_MS;
}
//10位时间戳
if (Pattern.compile(REGEX_TIMESTAMP_S).matcher(date).matches()) {
return DATE_FORMAT_LONG_S;
}
throw new BizException(ErrorCodeEnum.SYS_ERR, "无法识别的日期时间格式");
}
/**
* LocalDateTime时间类转换为时间格式字符串
*
* @param dateTime 时间
* @param format 转换格式
* @return
*/
public static String localDateTimeToStr(LocalDateTime dateTime, String format) {
switch (format) {
case DATE_FORMAT_LONG_MS:
return localDateTimeToLong(dateTime).toString();
case DATE_FORMAT_LONG_S:
return localDateTimeToLongs(dateTime).toString();
default:
return localDateTime2Str(dateTime, format);
}
}
/**
* string字符串 按照格式变更为 localDateTime类型
*
* @param time 字符串时间
* @param format 转换格式
* @return
*/
public static LocalDateTime strToLocalDateTime(String time, String format) {
switch (format) {
case DATE_FORMAT_LONG_MS:
return longms2LocalDateTime(longTimeStrToLong(time));
case DATE_FORMAT_LONG_S:
return longs2LocalDateTime(longTimeStrToLong(time));
case DATE_FORMAT_FULL:
case DATE_FORMAT_FULL_SLASH:
return str2LocalDateTime(time, format);
default:
return Optional.ofNullable(str2LocalDate(time, format)).map(t->LocalDateTime.of(t, LocalTime.MIN)).orElse(null);
}
}
/**
* cst转换Str
* @param cstTime Thu Apr 01 00:00:00 CST 2021
* @param format 转换格式
*/
public static String cstToStr(String cstTime, String format){
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(Date.parse(cstTime));
}
/**
* 在[beginStr,endStr]只随机生成时间,不包含日期
* 在没有添加日期格式时,默认为1970-01-01
* @param beginStr
* @param endStr
* @return
*/
public static LocalTime randomTime(String beginStr,String endStr){
try {
DateTimeFormatter format = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalTime beginTime = LocalTime.parse(beginStr, format);
LocalTime endTime = LocalTime.parse(endStr, format);
if (beginTime.isAfter(endTime)) {
return null;
}
long randDateTime = random(beginTime.toNanoOfDay(), endTime.toNanoOfDay());
return LocalTime.ofNanoOfDay(randDateTime);
} catch (Exception e) {
e.printStackTrace();
}
return LocalTime.now();
}
/**
* 随机生成时间
* 使用Math.random()方法---返回一个在介于(0,1)的随机数
* @param begin
* @param end
* @return
*/
private static long random(long begin, long end) {
long rand = begin + (long)(Math.random()*(end - begin));
if (rand == begin || rand == end) {
return random(begin, end);
}
return rand;
}
}
1.5 Stream流
package com.gemenyaofei.integration.domain.common.utils;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* @Author ljh
* @Date 2022/11/23
* @Desc Stream操作相关工具类
*/
public class StreamUtils {
/**
* 获取list中第一个符合条件的对象
*
* @param srcList 对象list
* @param filterFunc 条件
* @param <T> 对象类型
* @return 属性list
*/
public static <T> T findFirst(List<T> srcList, Predicate<? super T> filterFunc) {
if (CollectionUtils.isEmpty(srcList)) {
return null;
}
return srcList.stream().filter(filterFunc).findFirst().orElse(null);
}
/**
* 将List转换为string拼接
*
* @param srcList 对象list
* @param mapper 对象::get属性名
* @param <T> 对象类型
* @param <R> 属性类型
* @return 属性list
*/
public static <T, R> String toStr(List<T> srcList, Function<? super T, ? extends R> mapper, String separator) {
if (CollectionUtils.isEmpty(srcList)) {
return "";
}
return srcList.stream().map(mapper).filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining(separator));
}
/**
* 将Set转换为string拼接
*
* @param srcList 对象list
* @param mapper 对象::get属性名
* @param <T> 对象类型
* @param <R> 属性类型
* @return 属性list
*/
public static <T, R> String toStr(Set<T> srcList, Function<? super T, ? extends R> mapper, String separator) {
if (CollectionUtils.isEmpty(srcList)) {
return "";
}
return srcList.stream().map(mapper).filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining(separator));
}
/**
* 提取对象中的某一个属性
*
* @param srcList 对象list
* @param mapper 对象::get属性名
* @param <T> 对象类型
* @param <R> 属性类型
* @return 属性list
*/
public static <T, R> List<R> toList(List<T> srcList, Function<? super T, ? extends R> mapper) {
if (CollectionUtils.isEmpty(srcList)) {
return Collections.emptyList();
}
return srcList.stream().map(mapper).collect(Collectors.toList());
}
/**
* 提取对象中的某一个属性
*
* @param srcList 对象list
* @param <T> 对象类型
* @return 属性list
*/
public static <T> List<T> toFilterList(List<T> srcList, Predicate<? super T> predicate) {
if (CollectionUtils.isEmpty(srcList)) {
return Collections.emptyList();
}
return srcList.stream().filter(predicate).collect(Collectors.toList());
}
/**
* 提取map中的list
*
* @param srcList 对象list
* @param <T> 对象类型
* @return 属性list
*/
public static <K,T> List<T> flatMapList(Map<K, List<T>> srcList) {
if (CollectionUtils.isEmpty(srcList)) {
return Collections.emptyList();
}
return srcList.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
}
/**
* 提取对象中的某一个属性
*
* @param srcList 对象list
* @param mapper 对象::get属性名
* @param <T> 对象类型
* @param <R> 属性类型
* @return 属性list
*/
public static <T, R> List<R> toDistinctList(List<T> srcList, Function<? super T, ? extends R> mapper) {
if (CollectionUtils.isEmpty(srcList)) {
return Collections.emptyList();
}
return srcList.stream().map(mapper).distinct().collect(Collectors.toList());
}
/**
* 提取对象中的某一个属性
*
* @param srcList 对象list
* @param mapper 对象::get属性名
* @param <T> 对象类型
* @param <R> 属性类型
* @return 属性list
*/
public static <T, R> List<String> toLowerCaseList(List<T> srcList, Function<? super T, ? extends R> mapper) {
if (CollectionUtils.isEmpty(srcList)) {
return Collections.emptyList();
}
return srcList.stream().map(mapper).map(Object::toString).map(String::toLowerCase).distinct().collect(Collectors.toList());
}
/**
* 提取对象中的某一个属性,去重
*
* @param srcList 对象list
* @param mapper 对象::get属性名
* @param <T> 对象类型
* @param <R> 属性类型
* @return 属性set
*/
public static <T, R> Set<R> toSet(List<T> srcList, Function<? super T, ? extends R> mapper) {
if (CollectionUtils.isEmpty(srcList)) {
return Collections.emptySet();
}
return srcList.stream().map(mapper).collect(Collectors.toSet());
}
/**
* 构建 属性:对象 map
*
* @param srcList 对象list
* @param mapper 对象::get属性名
* @param <T> 对象类型
* @param <K> 属性类型
* @return 属性:对象 map
*/
public static <T, K> Map<K, T> toMap(List<T> srcList, Function<? super T, ? extends K> mapper) {
if (CollectionUtils.isEmpty(srcList)) {
return new HashMap<>();
}
return srcList.stream().collect(Collectors.toMap(mapper, v -> v, (v1, v2) -> v1));
}
/**
* 构建 属性:属性 map
*
* @param srcList 对象list
* @param mapper1 对象::get属性名
* @param mapper2 对象::get属性名
* @param <T> 对象类型
* @param <K> 属性类型
* @param <U> 属性类型
* @return 属性:属性 map
*/
public static <T, K, U> Map<K, U> toMap(List<T> srcList,
Function<? super T, ? extends K> mapper1,
Function<? super T, ? extends U> mapper2) {
if (CollectionUtils.isEmpty(srcList)) {
return new HashMap<>();
}
return srcList.stream().collect(Collectors.toMap(mapper1, mapper2, (v1, v2) -> v1));
}
/**
* 按特定规则筛选集合元素,返回List,过滤输入集合的null对象
*
* @param <T> 对象类型
* @param source 对象集合
* @param predicate 筛选条件
* @return
*/
public <T> List<T> filter(Collection<T> source, Predicate<T> predicate) {
if (CollectionUtils.isEmpty(source)) {
return new ArrayList<>(0);
}
return source.stream().filter(Objects::nonNull).filter(predicate).collect(Collectors.toList());
}
/**
* 按匹配条件返回某一个对象,过滤输入集合的null对象
*
* @param <T> 对象类型
* @param source 对象集合
* @param predicate 匹配条件
* @return
*/
public <T> T findAny(Collection<T> source, Predicate<T> predicate) {
if (CollectionUtils.isEmpty(source)) {
return null;
}
return source.stream().filter(Objects::nonNull).filter(predicate).findAny().orElse(null);
}
/**
* 判断集合是否有元素符合匹配条件
*
* @param <T> 对象类型
* @param source 对象集合
* @param predicate 匹配条件
* @return
*/
public <T> boolean anyMatch(Collection<T> source, Predicate<T> predicate) {
if (CollectionUtils.isEmpty(source)) {
return false;
}
return source.stream().anyMatch(predicate);
}
/**
* list分组
*
* @param srcList 对象list
* @param keyMapper 分组属性
* @param <T>
* @param <R>
* @return
*/
public static <T, R> Map<R, List<T>> groupBy(List<T> srcList, Function<? super T, ? extends R> keyMapper) {
if (CollectionUtils.isEmpty(srcList)) {
return new HashMap<>();
}
return srcList.stream().collect(Collectors.groupingBy(keyMapper));
}
/**
* list分组
*
* @param srcList 对象list
* @param keyMapper 分组属性
* @param <T>
* @param <R>
* @return
*/
public static <T, R> Map<R, List<T>> toFilterGroupBy(List<T> srcList,
Predicate<? super T> predicate,
Function<? super T, ? extends R> keyMapper) {
if (CollectionUtils.isEmpty(srcList)) {
return new HashMap<>();
}
return srcList.stream().filter(predicate).collect(Collectors.groupingBy(keyMapper));
}
/**
* list分组
*
* @param srcList 对象list
* @param keyMapper 分组属性
* @param <T>
* @param <R>
* @return
*/
public static <T, R, U> Map<R, Map<U, List<T>>> toMap2(List<T> srcList,
Function<? super T, ? extends R> keyMapper,
Function<? super T, ? extends U> keyMapper2) {
if (CollectionUtils.isEmpty(srcList)) {
return new HashMap<>();
}
return srcList.stream().collect(Collectors.groupingBy(keyMapper, Collectors.groupingBy(keyMapper2)));
}
/**
* list分组
*
* @param list 对象list
* @param keyMapper 分组属性
* @param <T>
* @param <R>
* @return
*/
public static <T, R, U> Map<R, List<U>> groupByMapList(List<T> list,
Function<? super T, ? extends R> keyMapper,
Function<? super T, ? extends U> valueMapper) {
if (CollectionUtils.isEmpty(list)) {
return new HashMap<>();
}
return list.stream().collect(Collectors.groupingBy(keyMapper, Collectors.mapping(valueMapper, Collectors.toList())));
}
/**
* list分组
*
* @param srcList 对象list
* @param keyMapper 分组属性
* @param <T>
* @param <R>
* @return
*/
public static <T, R, U> Map<R, Set<U>> groupByMapSet(List<T> srcList,
Function<? super T, ? extends R> keyMapper,
Function<? super T, ? extends U> mapper) {
if (CollectionUtils.isEmpty(srcList)) {
return new HashMap<>();
}
return srcList.stream().collect(Collectors.groupingBy(keyMapper, Collectors.mapping(mapper, Collectors.toSet())));
}
/**
* 切割 -> 操作 -> 归并
*
* @param source
* @param maxSize
* @param mapper
* @param <T>
* @param <R>
* @return
*/
public static <T, R> List<T> splitListConvert(final Collection<R> source, final int maxSize,
Function<List<R>, List<T>> mapper) {
if (CollectionUtils.isEmpty(source)) {
return new ArrayList<>(0);
}
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize must be positive");
}
final int size = source.size();
if (size <= maxSize) {
if (source instanceof List) {
return mapper.apply((List<R>) source);
}
return mapper.apply(new ArrayList<>(source));
}
final int step = (size + maxSize - 1) / maxSize;
List<T> list = IntStream.range(0, step)
.mapToObj(i -> source.stream().skip(i * maxSize).limit(maxSize).collect(Collectors.toList())).map(mapper)
.filter(Objects::nonNull).flatMap(Collection::stream).collect(Collectors.toList());
return list;
}
}
二、类和对象(反射)
2.1 BeanUtils
2.2 反射执行方法-ReflectionUtil
package com.gemenyaofei.integration.domain.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.List;
/**
* @Author ljh
* @Date 2022/11/28
* @Desc 通过反射执行方法的工具类
*/
public class ReflectionUtil {
private static Logger logger = LoggerFactory.getLogger(ReflectionUtil.class);
/**
* *通过反射的方式调用对象方法
*
* @param object 服务对象
* @param methodName 调用方法
* @param args 方法参数(具有顺序性)
*/
public static void invokeMethod(Object object, String methodName, Object[] args)
throws Exception {
logger.debug(" invokeMethod start : 服务对象={},调用方法={} ", new Object[]{object, methodName});
Class<?>[] paramClasses = null;
if (args.length > 0) {
paramClasses = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
paramClasses[i] = args[i] instanceof List ? List.class : args[i].getClass();
}
}
Method method = object.getClass().getMethod(methodName, paramClasses);
method.setAccessible(true);
method.invoke(object, args);
logger.debug(" invokeMethod end ");
}
}
三、复杂操作
3.1 异步工具类
1、异步任务执行类
package com.gemenyaofei.integration.domain.model.dto;
import com.gemenyaofei.integration.domain.common.utils.ReflectionUtil;
import lombok.extern.slf4j.Slf4j;
/**
* @Author ljh
* @Date 2022/11/28
* @Desc 异步任务类
*/
@Slf4j
public class AsyncTask implements Runnable {
// 服务对象
private Object object;
// 调用方法
private String methodName;
// 方法参数(具有顺序性)
private Object[] args;
public AsyncTask(Object object, String methodName, Object[] args) {
this.object = object;
this.methodName = methodName;
this.args = args;
}
@Override
public void run() {
try {
ReflectionUtil.invokeMethod(object, methodName, args);
} catch (Exception e) {
log.error("异步调用异常:object:{},methodName:{},args:{}",object, methodName, args);
log.error(e.getMessage());
}
}
}
2、获取容器中的Bean
package com.gemenyaofei.integration.domain.common.helper;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @Author ljh
* @Date 2022/11/28
* @Desc 从Spring容器中获取Bean的工具类
*/
@Component
public class SpringContextHelper implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHelper.applicationContext = applicationContext;
}
public static Object getBean(Class<?> clazz) throws BeansException {
return applicationContext.getBean(clazz);
}
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
3、通过反射执行方法
见2.2
4、异步任务工具类
package com.gemenyaofei.integration.domain.common.utils;
import com.gemenyaofei.integration.domain.common.helper.SpringContextHelper;
import com.gemenyaofei.integration.domain.model.dto.AsyncTask;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Author ljh
* @Date 2022/11/28
* @Desc 异步任务工具类
*/
public class AsyncTaskUtil {
private volatile static ThreadPoolTaskExecutor threadPoolTaskExecutor;
private static final ReentrantLock LOCK = new ReentrantLock();
private static ThreadPoolTaskExecutor getThreadPoolTaskExecutor() {
if (threadPoolTaskExecutor == null) {
LOCK.lock();
try {
if (threadPoolTaskExecutor == null) {
threadPoolTaskExecutor = (ThreadPoolTaskExecutor) SpringContextHelper.getBean("threadPoolTaskExecutor");
}
} finally {
LOCK.unlock();
}
}
return threadPoolTaskExecutor;
}
public static void asyncTask(Object object, String methodName, Object[] args) {
AsyncTask asyncTask = new AsyncTask(object, methodName, args);
asyncTask(asyncTask);
}
public static void asyncTask(Runnable asyncTask) {
getThreadPoolTaskExecutor().execute(asyncTask);
}
public static <T> Future<T> asyncTask(Callable<T> callableTask) {
return getThreadPoolTaskExecutor().submit(callableTask);
}
}
3.2 HTTP调用
1、请求参数实体类
package com.gemenyaofei.integration.app.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.http.util.Args;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @Author ljh
* @Date 2021/11/18
* @Desc HttpRequest 类
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class HttpRequestParam {
/**
* 接口地址
*/
protected String url;
/**
* 接口请求方式 get post put delete
*/
protected String method;
/**
* 请求头
*/
protected Map<String, String> headers;
/**
* 表单参数
*/
protected Map<String, Object> params;
/**
* body-json参数
*/
protected String body;
/**
* body-json参数
*/
protected File file;
public HttpRequestParam(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers;
this.params = builder.params;
this.body = builder.body;
this.file = builder.file;
}
public String url() {
return this.url;
}
public String method() {
return this.method;
}
public Map<String, String> headers() {
return this.headers;
}
public Map<String, Object> params() {
return this.params;
}
public String body() {
return this.body;
}
public File file() {
return this.file;
}
public Builder newBuilder() {
return new Builder(this);
}
@Override
public String toString() {
return "HttpRequest{url=" + this.url + ", method=" + this.method + ", headers=" + this.headers + ", params=" + this.params + ", body=" + this.body + '}';
}
public static class Builder {
String url;
String method;
Map<String, String> headers;
Map<String, Object> params;
String body;
File file;
public Builder() {
this.method = "GET";
}
Builder(HttpRequestParam httpRequest) {
this.url = httpRequest.url;
this.method = httpRequest.method;
this.headers = (Map) (httpRequest.headers.isEmpty() ? Collections.emptyMap() : new LinkedHashMap(httpRequest.headers));
this.params = (Map) (httpRequest.params.isEmpty() ? Collections.emptyMap() : new LinkedHashMap(httpRequest.params));
this.body = httpRequest.body;
this.file = httpRequest.file;
}
public Builder url(String url) {
if (url == null) {
throw new NullPointerException("url == null");
} else {
this.url = url;
return this;
}
}
public Builder header(Map<String, String> headers) {
this.headers = headers;
return this;
}
public Builder addHeader(String name, String value) {
Args.notNull(name, "Header name");
if (this.headers == null) {
this.headers = new HashMap<>(16);
}
this.headers.put(name, value);
return this;
}
public Builder removeHeader(String name) {
this.headers.remove(name);
return this;
}
public Builder params(Map<String, Object> params) {
this.params = params;
return this;
}
public Builder body(String body) {
this.body = body;
return this;
}
public Builder file(File file) {
this.file = file;
return this;
}
public Builder get() {
return this.method("GET");
}
public Builder post() {
return this.method("POST");
}
public Builder delete() {
return this.method("DELETE");
}
public Builder put() {
return this.method("PUT");
}
public Builder patch() {
return this.method("PATCH");
}
public Builder method(String method) {
if (method == null) {
throw new NullPointerException("method == null");
} else if (method.length() == 0) {
throw new IllegalArgumentException("method.length() == 0");
} else {
this.method = method;
return this;
}
}
public HttpRequestParam build() {
if (this.url == null) {
throw new IllegalStateException("url == null");
} else {
return new HttpRequestParam(this);
}
}
}
}
2、响应实体类
package com.gemenyaofei.integration.domain.common.entity;
import lombok.Data;
import java.io.Serializable;
/**
* @Author ljh
* @Date 2021/9/6
* @Desc 封装httpClient响应结果
*/
@Data
public class HttpClientResult implements Serializable {
/**
* 响应状态码,200成功
*/
private Integer code;
/**
* 响应成功/失败
*/
private Boolean success;
/**
* 响应数据
*/
private String responseBody;
/**
* 异常信息
*/
private String errorMsg;
public HttpClientResult(int code, String responseBody) {
this.code = code;
this.responseBody = responseBody;
}
public HttpClientResult(int code) {
this.code = code;
}
public HttpClientResult(int code, String responseBody, String errorMsg) {
this.code = code;
this.responseBody = responseBody;
this.errorMsg = errorMsg;
}
public HttpClientResult() {
}
}
3、调用工具类
package com.gemenyaofei.integration.app.utils;
import cn.hutool.json.JSONUtil;
import com.gemenyaofei.integration.app.dto.HttpRequestParam;
import com.gemenyaofei.integration.domain.common.entity.HttpClientResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.zookeeper.Shell;
import org.bouncycastle.jce.exception.ExtIOException;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Author huangqianqian
* @Date 2021/9/6
* @Desc httpClient工具类
*/
@Slf4j
public class HttpClientUtils {
/**
* 编码格式。发送编码格式统一用UTF-8
*/
private static final String ENCODING = "UTF-8";
private static final String APPLICATION_JSON_UTF_8 = "application/json";
private static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
private static final String APPLICATION_MSWORD = "application/msword";
/**
* 设置连接超时时间,单位毫秒。
*/
private static final int CONNECT_TIMEOUT = 6000;
/**
* 设置连接超时时间,单位毫秒。
*/
private static final int CONNECTION_REQUEST_TIMEOUT = 1000;
/**
* 请求获取数据的超时时间(即响应时间),单位毫秒。
*/
private static final int SOCKET_TIMEOUT = 60000;
private HttpClientUtils() {
}
private static RequestConfig requestConfig = null;
// private static final CloseableHttpClient GLOBAL_HTTP_CLIENT;
static {
// 存在连接超时和数据超时, 会导致请求卡住, 需要主动放弃
requestConfig = RequestConfig.custom()
// 设置连接超时时间, 单位毫秒
.setConnectTimeout(CONNECT_TIMEOUT)
// 请求获取数据的超时时间, 单位毫秒
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
// 如果访问一个接口, 多少时间内无法返回数据, 就直接放弃此次调用
.setSocketTimeout(SOCKET_TIMEOUT)
.build();
// GLOBAL_HTTP_CLIENT = HttpClientBuilder.create()
// // 全局请求超时策略
// .setDefaultRequestConfig(config)
// // 客户端连接池数量, 太多线程会导致线程上下文切换频繁, 开销也相当大
// .setMaxConnTotal(100)
// // 每个域名可占用的连接池数量, 考虑到部分接口访问的比较多, 超过会阻塞
// .setMaxConnPerRoute(30)
// .build();
}
/**
* get请求,表单入参,非body
*
* @param url 接口地址
* @return
*/
public static HttpClientResult doGet(String url) {
return executorRequest(new HttpRequestParam.Builder().url(url).get().build());
}
/**
* get请求,表单入参,非body
*
* @param url 接口地址
* @param paramMap 入参
* @return
*/
public static HttpClientResult doGet(String url, Map<String, Object> paramMap) {
return executorRequest(new HttpRequestParam.Builder().url(url).params(paramMap).get().build());
}
/**
* get请求,表单入参,非body
*
* @param url 接口地址---new
* @param paramMap 入参
* @return
*/
public static HttpClientResult doGet(String url, Map<String, Object> paramMap, Map<String, String> headers) {
return executorRequest(new HttpRequestParam.Builder().url(url).header(headers).params(paramMap).get().build());
}
/**
* delete请求,表单入参,非body
*
* @param url 接口地址
* @return
*/
public static HttpClientResult doDelete(String url) {
return executorRequest(new HttpRequestParam.Builder().url(url).delete().build());
}
/**
* delete请求,表单入参,非body
*
* @param url 接口地址
* @param paramMap 入参
* @return
*/
public static HttpClientResult doDelete(String url, Map<String, Object> paramMap) {
return executorRequest(new HttpRequestParam.Builder().url(url).params(paramMap).delete().build());
}
/**
* delete请求,表单入参,非body---token
*
* @param url 接口地址
* @param paramMap 入参
* @return
*/
public static HttpClientResult doDelete(String url, Map<String, Object> paramMap, Map<String, String> headers) {
return executorRequest(new HttpRequestParam.Builder().url(url).header(headers).params(paramMap).delete().build());
}
/**
* put请求,表单入参,非body
*
* @param url 接口地址
* @param paramMap 入参
* @return
*/
public static HttpClientResult doPut(String url, Map<String, Object> paramMap) {
return executorRequest(new HttpRequestParam.Builder().url(url).params(paramMap).put().build());
}
/**
* post请求,表单入参,非body
*
* @param url 接口地址
* @return
*/
public static HttpClientResult doPost(String url) {
return executorRequest(new HttpRequestParam.Builder().url(url).post().build());
}
/**
* post请求,表单入参,非body
*
* @param url 接口地址
* @param paramMap 入参
* @return
*/
public static HttpClientResult doPost(String url, Map<String, Object> paramMap) {
return executorRequest(new HttpRequestParam.Builder().url(url).params(paramMap).post().build());
}
/**
* post请求,表单入参,非body
*
* @param url 接口地址----new
* @param paramMap 入参
* @return
*/
public static HttpClientResult doPost(String url, Map<String, Object> paramMap, Map<String, String> headers) {
return executorRequest(new HttpRequestParam.Builder().url(url).header(headers).params(paramMap).post().build());
}
/**
* post请求,表单入参,非body
*
* @param url 接口地址
* @param json 入参
* @return
*/
public static HttpClientResult doPost(String url, String json) {
return executorRequest(new HttpRequestParam.Builder().url(url).body(json).post().build());
}
/**
* post请求,表单入参,非body
*
* @param url 接口地址--new
* @param json 入参
* @return
*/
public static HttpClientResult doPost(String url, String json, Map<String, String> headers) {
return executorRequest(new HttpRequestParam.Builder().url(url).header(headers).body(json).post().build());
}
/**
* post请求,表单入参,非body
*
* @param url 接口地址
* @param paramMap 入参
* @return
*/
public static HttpClientResult doPostJson(String url, Map<String, Object> paramMap, Map<String, String> headers) {
return executorRequest(new HttpRequestParam.Builder().url(url).header(headers).body(JSONUtil.toJsonStr(paramMap)).post().build());
}
/**
* post请求,body入参(json字符串)
*
* @param url 接口地址
* @param jsonStr json字符串
* @return
*/
public static HttpClientResult doPostJson(String url, String jsonStr, Map<String, String> headerMap) {
log.info("doPost url:[{}], param:[{}]", url, jsonStr);
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
if (!MapUtils.isEmpty(headerMap)) {
for (String key : headerMap.keySet()) {
httpPost.addHeader(key, headerMap.get(key));
}
}
StringEntity entity = new StringEntity(jsonStr, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
return executeHttp(httpPost);
}
/**
* post请求,body入参(form-data)
*
* @param url 接口地址
* @param formData 表单入参
* @return
*/
public static HttpClientResult doPostFormData(String url, Map<String, String> headerMap, List<NameValuePair> formData) {
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(formData, StandardCharsets.UTF_8));
//httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
if (!MapUtils.isEmpty(headerMap)) {
for (String key : headerMap.keySet()) {
httpPost.addHeader(key, headerMap.get(key));
}
}
return executeHttp(httpPost);
}
/**
* 执行请求
*
* @param httpRequestParam
* @return
*/
public static HttpClientResult executorRequest(HttpRequestParam httpRequestParam) {
log.info("executorRequest info:[{}]", httpRequestParam.toString());
String method = httpRequestParam.method();
switch (method) {
case "GET":
return doRequest(new HttpGet(), httpRequestParam);
case "DELETE":
return doRequest(new HttpDelete(), httpRequestParam);
case "POST":
return doEntityRequest(new HttpPost(), httpRequestParam);
case "PUT":
return doEntityRequest(new HttpPut(), httpRequestParam);
case "PATCH":
return doEntityRequest(new HttpPatch(), httpRequestParam);
default:
break;
}
return new HttpClientResult(500, "未知的请求方式");
}
public static HttpClientResult doEntityRequest(HttpEntityEnclosingRequestBase httpEntityRequestBase, HttpRequestParam httpRequestParam) {
// 添加参数, 请求参数除body外最终都需要拼接到地址栏中
Map<String, Object> paramMap = httpRequestParam.params();
httpEntityRequestBase.setURI(
paramMap == null || paramMap.isEmpty()
? URI.create(httpRequestParam.url())
: buildUri(httpRequestParam.url(), paramMap));
// 添加头内容
addHeader(httpEntityRequestBase, httpRequestParam.headers(), httpRequestParam.body());
// 添加body内容
if (!StringUtils.isBlank(httpRequestParam.getBody())) {
StringEntity requestEntity = new StringEntity(httpRequestParam.getBody(), "utf-8");
requestEntity.setContentEncoding("UTF-8");
httpEntityRequestBase.setEntity(requestEntity);
}
// 执行HTTP
return executeHttp(httpEntityRequestBase);
}
/**
* 根据 请求方式、接口地址、参数 执行executeHttp请求
*
* @return
*/
private static HttpClientResult doRequest(HttpRequestBase httpBase, HttpRequestParam httpRequestParam) {
if (MapUtils.isEmpty(httpRequestParam.params())) {
httpBase.setURI(URI.create(httpRequestParam.url()));
} else {
httpBase.setURI(buildUri(httpRequestParam.url(), httpRequestParam.params()));
}
if (!MapUtils.isEmpty(httpRequestParam.headers())) {
addHeader(httpBase, httpRequestParam.headers(), httpRequestParam.body());
}
return executeHttp(httpBase);
}
/**
* 执行http请求 获取数据 并释放资源
*/
private static HttpClientResult executeHttp(HttpRequestBase httpBase) {
httpBase.setConfig(requestConfig);
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse httpResponse = null;
try {
// 执行请求
httpResponse = httpClient.execute(httpBase);
//response = GLOBAL_HTTP_CLIENT.execute(httpBase);
HttpClientResult result = getHttpClientResult(httpResponse, httpBase);
log.info("executeHttp result:[{}]", result);
return result;
} catch (Exception e) {
log.error("Failed to execute request or get response, message:[{}], Exception:[{}]", e.getMessage(), e);
return new HttpClientResult(HttpStatus.SC_INTERNAL_SERVER_ERROR, null, "Failed to execute request or get response: " + e.toString());
} finally {
closeHttpClientAndResp(httpClient, httpResponse);
}
}
/**
* http请求结束,获取请求结果,封装结果
*
* @param response 请求结果
* @param httpBase
* @return
* @throws IOException
*/
private static HttpClientResult getHttpClientResult(CloseableHttpResponse response, HttpRequestBase httpBase) throws Exception {
try {
if (response == null || response.getStatusLine() == null) {
return new HttpClientResult(HttpStatus.SC_INTERNAL_SERVER_ERROR, null, "response响应内容为空");
}
// 获取返回结果
String content = "";
if (response.getEntity() != null) {
content = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8.name());
}
// response.getStatusLine().getStatusCode();
// 返回响应结果
return new HttpClientResult(response.getStatusLine().getStatusCode(), content, response.getStatusLine().getStatusCode() == HttpStatus.SC_OK ? null : "服务繁忙");
} catch (Exception exception) {
throw new Exception(exception);
} finally {
if (!httpBase.isAborted()) {
httpBase.abort();
}
}
}
/**
* http请求结束,释放资源
*/
private static void closeHttpClientAndResp(CloseableHttpClient httpClient, CloseableHttpResponse httpResponse) {
if (httpResponse != null) {
try {
httpResponse.close();
} catch (IOException e) {
log.error("Failed to close httpResponse {}", e.getLocalizedMessage(), e);
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
log.error("Failed to close httpClient {}", e.getLocalizedMessage(), e);
}
}
}
// /**
// * http请求结束,释放资源(当使用GLOBAL_HTTP_CLIENT执行时,用这段代码释放资源)
// */
// private static void closeHttpClientAndResp(HttpRequestBase httpBase, CloseableHttpResponse httpResponse) {
// if (httpResponse != null) {
// try {
// httpResponse.close();
// } catch (IOException e) {
// log.error("Failed to close httpResponse {}", e.getLocalizedMessage(), e);
// }
// }
// if (httpBase != null) {
// httpBase.releaseConnection();
// }
// }
/**
* 接口地址拼接入参
*
* @param url 接口地址
* @param paramMap 入参
* @return
*/
private static URI buildUri(String url, Map<String, Object> paramMap) {
String param = URLEncodedUtils.format(setHttpParams(paramMap), StandardCharsets.UTF_8);
return StringUtils.isEmpty(param) ? URI.create(url) : URI.create(url + "?" + param);
}
/**
* 参数录入(注意 map中的数据最终都会变为字符串)
*
* @param paramMap 参数
* @return
*/
private static List<NameValuePair> setHttpParams(Map<String, Object> paramMap) {
List<NameValuePair> nameValPair = new ArrayList<>();
if (paramMap == null || paramMap.isEmpty()) {
return nameValPair;
}
for (Map.Entry<String, Object> mapEntry : paramMap.entrySet()) {
nameValPair.add(new BasicNameValuePair(mapEntry.getKey(), Optional.ofNullable(mapEntry.getValue()).map(Object::toString).orElse(null)));
}
return nameValPair;
}
/**
* 执行http请求前,添加头内容
*
* @param httpRequestBase
* @param headerMap
* @param body
*/
private static void addHeader(HttpRequestBase httpRequestBase, Map<String, String> headerMap, String body) {
if (MapUtils.isEmpty(headerMap)) {
httpRequestBase.addHeader(HTTP.CONTENT_TYPE, StringUtils.isEmpty(body) ? APPLICATION_X_WWW_FORM_URLENCODED : APPLICATION_JSON_UTF_8);
} else {
for (Map.Entry<String, String> headerEntry : headerMap.entrySet()) {
httpRequestBase.addHeader(headerEntry.getKey(), headerEntry.getValue());
}
if (Objects.isNull(httpRequestBase.getFirstHeader(HTTP.CONTENT_TYPE))) {
httpRequestBase.addHeader(HTTP.CONTENT_TYPE, StringUtils.isEmpty(body) ? APPLICATION_X_WWW_FORM_URLENCODED : APPLICATION_JSON_UTF_8);
}
}
}
/**
* 针对url中拼接 {参数} 的请求,替换url参数路径
*
* @param url
* @param param
* @return
*/
public static String matcherUrl(String url, Map<String, String> param) {
String regex = "(?=\\{).*?(\\})";
String fieldRegex = "\\{|\\}";
//创建一个模式对象
Pattern pattern = Pattern.compile(regex);
//匹配字符串中的已编译模式
Matcher matcher = pattern.matcher(url);
List<String> fields = new ArrayList<>();
while (matcher.find()) {
fields.add(matcher.group());
}
if (!fields.isEmpty()) {
for (String field : fields) {
url = url.replace(field, param.getOrDefault(field.replaceAll(fieldRegex, ""), ""));
}
}
return url;
}
}
3.3 数据库查询
package com.gemenyaofei.integration.app.utils;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON;
import com.gemenyaofei.integration.app.constant.DbDataSourceConst;
import com.gemenyaofei.integration.app.dto.vo.IntegrateDatasetVO;
import com.gemenyaofei.integration.client.base.dto.data.DsTableDetailViewDTO;
import com.gemenyaofei.integration.client.base.dto.data.DsTableFieldViewDTO;
import com.gemenyaofei.integration.domain.common.exception.BizException;
import com.gemenyaofei.integration.domain.common.exception.ErrorCodeEnum;
import com.gemenyaofei.integration.domain.common.utils.DataSourceUtil;
import com.gemenyaofei.integration.domain.common.utils.StringUtils;
import com.gemenyaofei.integration.domain.model.entities.DataSourceDbInfoEntity;
import com.gemenyaofei.integration.domain.model.enums.DbTypeEnum;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.*;
/**
* @Author: XiaoKY
* @Description: 数据源连接工具类
* @Data: Created in 17:58 2022/7/18
*/
@Slf4j
public class IntegrateConnectionUtils {
private IntegrateConnectionUtils() {
}
private static final String SQLSERVER = "SQLSERVER";
/**
* 根据连接信息获取connection
*/
// TODO 优化为连接池可复用
public static Connection getConnection(DataSourceDbInfoEntity db) {
if (Objects.isNull(db)) {
log.info("数据源信息为空");
throw new BizException(ErrorCodeEnum.BIZ_DB_CONNECTION_FAIL);
}
Connection conn = null;
try {
/*//1.加载驱动
Class.forName(db.getDriverType());
//2.获取连接
conn = DriverManager.getConnection(Objects.requireNonNull(getJdbcURL(db)), db.getUsername(), db.getPassword());
return DbTypeEnum.ORACLE.getDriver().equals(db.getDriverType()) || conn.isValid(5) ? conn : null;*/
conn = DataSourceUtil.createJdbcDataSource(db).getConnection();
} catch (Exception e) {
log.warn(DbDataSourceConst.CONNBUILDINFO, e);
}
return conn;
}
/**
* 关闭connection
*/
public static void closeConnection(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 根据连接信息获取JdbcURL
*/
public static String getJdbcURL(DataSourceDbInfoEntity db) {
try {
DbTypeEnum dbType = DbTypeEnum.valueOf(db.getDbType());
switch (dbType) {
case ORACLE:
return DbDataSourceConst.ORACLEURL + db.getHost() + ":" + db.getPort() + "/" + db.getDbName();
case MYSQL:
return DbDataSourceConst.MYSQLURL + db.getHost() + ":" + db.getPort() + "/" + db.getDbName() +
"?useUnicode=true&characterEncoding=" + db.getCodeType() +
"&autoReconnect=true&failOverReadOnly=true&serverTimezone=UTC&useSSL=false";
case POSTGRESQL:
return DbDataSourceConst.PGURL + db.getHost() + ":" + db.getPort() + "/" + db.getDbName()
+ "?currentSchema=" + db.getSchema() // 不用写schema.table
+ "&tcpKeepAlive=true" // 长连接保持,避免连接关闭问题
+ "&socketTimeout=600" // 等待数据库响应时最多等待 600 秒
+ "&loginTimeout=600" // 建立连接时最多等待 600 秒
+ "&connectTimeout=600"; // 连接等待时长,最多等待600s
case SQLSERVER:
return DbDataSourceConst.SQLSERVERURL + db.getHost() + ":" + db.getPort() + ";databaseName=" + db.getDbName();
default:
throw new BizException(ErrorCodeEnum.DATABASE_TYPE_NOT_EXISTS);
}
} catch (NullPointerException e) {
log.warn(DbDataSourceConst.URLBUILDINFO, e);
}
return null;
}
/**
* 得到数据源下所有的表和视图信息
*
* @param dbSource 数据源实体信息
* @return
* @throws Exception
*/
public static List<IntegrateDatasetVO> getDBTables(DataSourceDbInfoEntity dbSource) {
List<IntegrateDatasetVO> integrateDatasetVOList = new ArrayList<>();
Connection conn = null;
String catalog = null;
try {
conn = getConnection(dbSource);
if (Objects.nonNull(conn)) {
catalog = conn.getCatalog();
} else {
throw new BizException(ErrorCodeEnum.BIZ_DB_CONNECTION_FAIL);
}
DatabaseMetaData metaData = conn.getMetaData();
ResultSet itr;
if (StringUtils.isNotEmpty(dbSource.getSchema())) {
itr = metaData.getTables(catalog, dbSource.getSchema(), null, new String[]{"VIEW", "TABLE"});
} else {
itr = metaData.getTables(catalog, conn.getSchema(), null, new String[]{"VIEW", "TABLE"});
}
while (itr.next()) {
IntegrateDatasetVO integrateDatasetVO = new IntegrateDatasetVO();
integrateDatasetVO.setTableName(itr.getString("TABLE_NAME"));
integrateDatasetVO.setDescription(itr.getString("REMARKS"));
integrateDatasetVOList.add(integrateDatasetVO);
}
} catch (Exception e) {
e.printStackTrace();
throw new BizException(ErrorCodeEnum.SYS_ERR);
} finally {
closeConnection(conn);
}
return integrateDatasetVOList;
}
/**
* 获得指定表的字段信息
*
* @param tableName 表名
* @param dataSourceDbInfoEntity 数据源实体信息
* @return
*/
public static DsTableDetailViewDTO getDBColumns(String tableName, DataSourceDbInfoEntity dataSourceDbInfoEntity) {
ArrayList<DsTableFieldViewDTO> dsTableFields = new ArrayList<>();
DsTableDetailViewDTO dsTableDetailDTO = new DsTableDetailViewDTO();
Connection conn = null;
String tableSql = buildFetchStatement(dataSourceDbInfoEntity, tableName, 1);
log.info("所执行的SQL为:{}", tableSql);
HashMap<String, String> sqlserverFieldDict = new HashMap<>();
HashMap<String, String> fieldDict = new HashMap<>();
try {
conn = getConnection(dataSourceDbInfoEntity);
// 获取sqlserver字段描述的sql语句
String sqlPlus = buildSqlOfSqlServerFindFiledDesc(dataSourceDbInfoEntity, tableName);
// 获取字段的描述
if (DbTypeEnum.SQLSERVER.getDBType().equals(dataSourceDbInfoEntity.getDbType())) {
findSqlServer2FieldDescExecute(sqlserverFieldDict, conn, sqlPlus);
} else {
fieldDict = getFieldDict(conn, tableName, fieldDict);
}
// 获取字段的主键字段名
String primaryKey = getPrimaryKeyName(conn, tableName);
List<DsTableFieldViewDTO> fieldMetaDTO =
getAndBuildFieldMetaData(conn, tableSql, primaryKey, dataSourceDbInfoEntity, sqlserverFieldDict, fieldDict, dsTableFields);
dsTableDetailDTO.setTableName(tableName);
dsTableDetailDTO.setDsTableFieldVOList(fieldMetaDTO);
} catch (Exception e) {
log.error("tableName:" + tableName + ",查询执行{},", e.getMessage());
} finally {
closeConnection(conn);
}
return dsTableDetailDTO;
}
/**
* 构建表字段的DTO:字段主键,字段描述,是否必填,字段名...
*
* @param conn 数据源连接信息
* @param tableSql 查询表sql语句
* @param primaryKey 主键字段名
* @param dataSourceDbInfoEntity 数据源信息
* @param sqlserverFieldDict 数据库类型为sqlserver的字段字典
* @param fieldDict 数据库不为sqlserver的字段字典
* @param dsTableFields DsTableFieldViewDTO 列表
* @return
*/
private static List<DsTableFieldViewDTO> getAndBuildFieldMetaData(Connection conn,
String tableSql,
String primaryKey,
DataSourceDbInfoEntity dataSourceDbInfoEntity,
HashMap<String, String> sqlserverFieldDict,
HashMap<String, String> fieldDict,
ArrayList<DsTableFieldViewDTO> dsTableFields) throws SQLException {
PreparedStatement statement = null;
try {
statement = conn.prepareStatement(tableSql);
//从结果集元数据获取字段信息
ResultSetMetaData resultMeta = statement.getMetaData();
// 设置字段的主键
for (int i = 0; i < resultMeta.getColumnCount(); i++) {
DsTableFieldViewDTO dsTableFieldViewDTO = new DsTableFieldViewDTO();
if (StringUtils.isNotEmpty(primaryKey) && primaryKey.equals(resultMeta.getColumnName(i + 1))) {
dsTableFieldViewDTO.setIsPrimary(1);
} else {
dsTableFieldViewDTO.setIsPrimary(0);
}
dsTableFieldViewDTO.setFieldName(resultMeta.getColumnName(i + 1));
dsTableFieldViewDTO.setFieldType(resultMeta.getColumnTypeName(i + 1));
// 字段是否可为空:0不可为空,1可为空
dsTableFieldViewDTO.setIsRequiredField(resultMeta.isNullable(i + 1) == 0 ? Boolean.TRUE : Boolean.FALSE);
// 设置字段的描述
if (SQLSERVER.equals(dataSourceDbInfoEntity.getDbType())) {
dsTableFieldViewDTO.setFieldDesc(sqlserverFieldDict.get(resultMeta.getColumnName(i + 1)));
} else {
dsTableFieldViewDTO.setFieldDesc(fieldDict.get(resultMeta.getColumnName(i + 1)));
}
dsTableFields.add(dsTableFieldViewDTO);
}
} catch (Exception e) {
log.info("构建表详情信息失败:[{}]", e.getMessage());
throw new BizException(ErrorCodeEnum.SYS_ERR);
} finally {
if (Objects.nonNull(statement)) {
statement.close();
}
}
return dsTableFields;
}
/**
* 获得表的字段字典map: 键为字段名,值为字段描述
*
* @param conn 数据源连接信息
* @param tableName 表名
* @param fieldDict 字段初始化map字典
* @return
*/
private static HashMap<String, String> getFieldDict(Connection conn, String tableName, HashMap<String, String> fieldDict) {
ResultSet columns = null;
try {
columns = conn.getMetaData().getColumns(conn.getCatalog(), "%", tableName, "%");
// 获得字段的描述字典
while (columns.next()) {
String columnName = columns.getString("COLUMN_NAME");
String remarks = columns.getString("REMARKS");
if (StringUtils.isEmpty(remarks)) {
fieldDict.put(columnName, null);
} else {
fieldDict.put(columnName, remarks);
}
}
} catch (Exception e) {
log.info("获取字段描述信息异常:[{}]", e.getMessage());
throw new BizException(ErrorCodeEnum.SYS_ERR);
}
log.info("表[{}]的字段字典为:[{}]", tableName, JSON.toJSONString(fieldDict));
return fieldDict;
}
/**
* 得到表的主键字段名
*
* @param conn 连接信息
* @param tableName 表名
* @return
*/
private static String getPrimaryKeyName(Connection conn, String tableName) {
ResultSet primaryKeyResult = null;
DatabaseMetaData dbMeta = null;
String primaryKey = null;
try {
dbMeta = conn.getMetaData();
// 得到字段的主键信息
primaryKeyResult = dbMeta.getPrimaryKeys(conn.getCatalog(), conn.getSchema(), tableName);
while (primaryKeyResult.next()) {
primaryKey = primaryKeyResult.getString("COLUMN_NAME");
log.info("表[{}]的字段主键名为[{}]", tableName, primaryKey);
}
} catch (Exception e) {
log.info("查找表[{}]的主键信息未找到", tableName);
throw new BizException(ErrorCodeEnum.SYS_ERR);
}
return primaryKey;
}
/**
* 数据库类型为sqlserver时,获得表字段的描述信息
*
* @param fieldDescMap 键为字段名,值为字段描述
* @param conn 数据源连接
* @param sqlPlus 需要执行的sql
*/
private static void findSqlServer2FieldDescExecute(HashMap<String, String> fieldDescMap, Connection conn, String sqlPlus) throws SQLException {
PreparedStatement findFieldDesc = null;
try {
findFieldDesc = conn.prepareStatement(sqlPlus);
ResultSet resultSet = findFieldDesc.executeQuery();
while (resultSet.next()) {
fieldDescMap.put(resultSet.getString("FIELD"), resultSet.getString("COMMENT"));
}
} catch (Exception e) {
log.info("当前数据库类型为sqlserver,获取字段描述信息失败:[{}]", e.getMessage());
throw new BizException(ErrorCodeEnum.SYS_ERR);
} finally {
if (Objects.nonNull(findFieldDesc)) {
findFieldDesc.close();
}
}
}
/**
* 当数据库类型为sqlserver时,根据下面的sql获取字段表述信息
*
* @param dataSourceDbInfoEntity 数据源信息
* @param tableName 表名
* @return
*/
private static String buildSqlOfSqlServerFindFiledDesc(DataSourceDbInfoEntity dataSourceDbInfoEntity, String tableName) {
if (SQLSERVER.equals(dataSourceDbInfoEntity.getDbType())) {
String sqlPlus = " SELECT\n" +
"a.name FIELD,\n" +
"CASE\n" +
"\n" +
"WHEN EXISTS (\n" +
"SELECT\n" +
"1 \n" +
"FROM\n" +
"sysobjects \n" +
"WHERE\n" +
"xtype = 'PK' \n" +
"AND parent_obj = a.id \n" +
"AND name IN ( SELECT name FROM sysindexes WHERE indid IN ( SELECT indid FROM sysindexkeys WHERE id = a.id AND colid = a.colid ) ) \n" +
") THEN\n" +
"1 ELSE NULL \n" +
"END \"KEY\",\n" +
"b.name TYPE,\n" +
"COLUMNPROPERTY( a.id, a.name, 'PRECISION' ) LENGTH,\n" +
"CONVERT(nvarchar(50),isnull( d.[value], '' )) COMMENT \n" +
"FROM\n" +
"syscolumns a\n" +
"LEFT JOIN systypes b ON a.xusertype= b.xusertype\n" +
"INNER JOIN sysobjects c ON a.id= c.id \n" +
"AND c.xtype= 'U' \n" +
"AND c.name<> 'dtproperties'\n" +
"LEFT JOIN sys.extended_properties d ON a.id= d.major_id \n" +
"AND a.colid= d.minor_id \n" +
"WHERE\n" +
"c.name= '" + tableName + "'";
log.info("生成的sql语句为:[{}]", sqlPlus);
return sqlPlus;
} else {
return null;
}
}
/**
* 执行sql查询
*
* @param sql 需要执行的sql信息
* @param conn 连接信息
* @return
*/
public static ResultSet executeSQL(String sql, Connection conn) throws SQLException {
ResultSet res = null;
Statement statement = null;
try {
if (conn.isClosed()) {
log.info("conn is closed");
}
statement = conn.createStatement();
res = statement.executeQuery(sql);
} catch (SQLException e) {
log.info("查询执行[{}]", e.getMessage());
}
return res;
}
public static String buildFetchStatement(DataSourceDbInfoEntity dataSourceDbInfoEntity, String dsTableName, Integer rowCount) {
StringBuilder sql = new StringBuilder();
String schema = Assert.notNull(dataSourceDbInfoEntity).getSchema();
switch (dataSourceDbInfoEntity.getDbType()) {
case "POSTGRESQL":
sql.append("SELECT * FROM ").append(schema).append(".\"").append(dsTableName).append("\" limit ").append(rowCount);
break;
case "SQLSERVER":
sql.append("SELECT TOP ").append(rowCount).append(" * FROM ").append(schema).append(".").append(dsTableName);
break;
case "ORACLE":
sql.append("SELECT * FROM (SELECT * FROM ").append(schema == null ? "" : schema + ".").append(dsTableName)
.append(" ) WHERE ROWNUM > 0 AND ROWNUM <= ").append(rowCount);
break;
default:
break;
}
return new String(sql);
}
public static Map<String, String> fieldSearchSQL(DataSourceDbInfoEntity dataSourceDbInfoEntity, String dsTableName) {
String sql = buildFetchStatement(dataSourceDbInfoEntity, dsTableName, 1);
log.info("示例数据查询sql语句:[{}]", JSON.toJSONString(sql));
List<Map<String, String>> sampleDataList = sampleData(dataSourceDbInfoEntity, sql);
return sampleDataList!=null && sampleDataList.size() == 1 ? sampleDataList.get(0): new HashMap<>();
}
public static List<Map<String, String>> sampleData(DataSourceDbInfoEntity dataSourceDbInfoEntity, String sql) {
List<Map<String, String>> resultList = Lists.newLinkedList();
try (Connection conn = getConnection(dataSourceDbInfoEntity)){
int columnCount = 0;
ResultSet res = IntegrateConnectionUtils.executeSQL(sql, conn);
ResultSetMetaData rsmd = res.getMetaData();
columnCount = rsmd.getColumnCount();
while(res.next()) {
Map<String, String> resultMap = new HashMap<>();
for (int i = 1; i <= columnCount; i++) {
try {
resultMap.put(rsmd.getColumnName(i), res.getString(i));
} catch (Exception e) {
resultMap.put(rsmd.getColumnName(i), null);
}
}
resultList.add(resultMap);
}
} catch (Exception e) {
log.info("获取示例数据异常:", e.getMessage());
}
return resultList;
}
}
3.4 Spring Bean的工具类
package com.gemenyaofei.metabase.model.core.utils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;
import java.util.Map;
/**
* @Description:
* @author:ljh
* @create: 2023-10-16 16:25
*/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor {
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringUtils.beanFactory = beanFactory;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws BeansException
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T) beanFactory.getBean(name);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws BeansException
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
T result = (T) beanFactory.getBean(clz);
return result;
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return beanFactory.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
*
* @param name
* @return boolean
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return beanFactory.isSingleton(name);
}
/**
* @param name
* @return Class 注册对象的类型
* @throws NoSuchBeanDefinitionException
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
*
* @param name
* @return
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getAliases(name);
}
/**
* 获取aop代理对象
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker) {
return (T) AopContext.currentProxy();
}
/**
* 根据注解类型获取bean
*
* @param clz 注解类型
* @return bean集合
*/
public static Map<String, Object> getBeansByAnnotation(Class<? extends Annotation> clz) {
return beanFactory.getBeansWithAnnotation(clz);
}
}
3.5 线程休眠工具类
package com.gemenyaofei.metabase.lang.util;
import java.util.concurrent.TimeUnit;
public class SleepUtil {
public static void sleepSecond(long timeout)
{
try {
TimeUnit.SECONDS.sleep(timeout);
} catch (Exception e) {
}
}
public static void sleepMillisecond(long timeout)
{
try {
TimeUnit.MILLISECONDS.sleep(timeout);
} catch (Exception e) {
}
}
}
四、常用信息获取工具
4.1 获取本地ip
package com.gemenyaofei.metabase.sync.core.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* @ClassName: NetUtils
* @Description: 获取当前ip地址工具
* @author ljh
* @date 2022年09月05日
* @Copyright gemenyaofei.com
*/
public class NetUtils {
private final static Logger logger = LoggerFactory.getLogger(NetUtils.class);
/**
* 获取本地ip
* @return ip地址
*/
public static String getLocalAddress() {
try {
Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
List<String> ipv4Result = new ArrayList<String>();
List<String> ipv6Result = new ArrayList<String>();
while (enumeration.hasMoreElements()) {
final NetworkInterface networkInterface = enumeration.nextElement();
final Enumeration<InetAddress> en = networkInterface.getInetAddresses();
while (en.hasMoreElements()) {
final InetAddress address = en.nextElement();
if (!address.isLoopbackAddress()) {
if (address instanceof Inet6Address) {
ipv6Result.add(normalizeHostAddress(address));
} else {
ipv4Result.add(normalizeHostAddress(address));
}
}
}
}
// prefer ipv4
if (!ipv4Result.isEmpty()) {
for (String ip : ipv4Result) {
if (ip.startsWith("127.0")
// || ip.startsWith("192.168")
) {
continue;
}
return ip;
}
return ipv4Result.get(ipv4Result.size() - 1);
} else if (!ipv6Result.isEmpty()) {
return ipv6Result.get(0);
}
final InetAddress localHost = InetAddress.getLocalHost();
return normalizeHostAddress(localHost);
} catch (Exception e) {
logger.error("Failed to obtain local address", e);
}
return null;
}
/**
* 将ip地址转换为字符
* @param localHost ip详情
* @return 返回字符ip
*/
public static String normalizeHostAddress(final InetAddress localHost) {
if (localHost instanceof Inet6Address) {
return "[" + localHost.getHostAddress() + "]";
} else {
return localHost.getHostAddress();
}
}
}