From ea58e018b47f5c774d53326725be41efe13c3843 Mon Sep 17 00:00:00 2001 From: cuijiawang Date: Tue, 27 May 2025 17:58:49 +0800 Subject: [PATCH] init --- pom.xml | 161 ++++++++ utils/AESPKCS7PaddingUtils.java | 127 ++++++ utils/BeanUtils.java | 514 +++++++++++++++++++++++ utils/ClassUtils.java | 58 +++ utils/CommonUtils.java | 200 +++++++++ utils/DateUtils.java | 300 ++++++++++++++ utils/EscUtils.java | 28 ++ utils/HttpsUtils.java | 164 ++++++++ utils/JwtUtils.java | 113 +++++ utils/MD5Utils.java | 67 +++ utils/PageUtils.java | 40 ++ utils/RedisUtils.java | 704 ++++++++++++++++++++++++++++++++ 12 files changed, 2476 insertions(+) create mode 100644 pom.xml create mode 100644 utils/AESPKCS7PaddingUtils.java create mode 100644 utils/BeanUtils.java create mode 100644 utils/ClassUtils.java create mode 100644 utils/CommonUtils.java create mode 100644 utils/DateUtils.java create mode 100644 utils/EscUtils.java create mode 100644 utils/HttpsUtils.java create mode 100644 utils/JwtUtils.java create mode 100644 utils/MD5Utils.java create mode 100644 utils/PageUtils.java create mode 100644 utils/RedisUtils.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..7944320 --- /dev/null +++ b/pom.xml @@ -0,0 +1,161 @@ + + + 4.0.0 + + + + + 1.0-SNAPSHOT + ../pom.xml + + + + common-module + 0.0.1-SNAPSHOT + common-module + Demo project for Spring Boot + + + 8 + 4.4.0 + 1.2.78 + 5.7.16 + 33.2.1-jre + 4.1.0 + + + + + org.springframework.boot + spring-boot-starter + + + com.github.xiaoymin + knife4j-openapi3-spring-boot-starter + ${knife4j.version} + + + commons-lang3 + org.apache.commons + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + true + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + org.springframework.boot + spring-boot-starter-data-redis + + + io.lettuce + lettuce-core + + + + + redis.clients + jedis + + + + cn.hutool + hutool-all + ${hutool.version} + + + + com.auth0 + java-jwt + ${jwt.version} + + + org.apache.httpcomponents + httpclient + + + + com.alibaba + fastjson + ${fastjson.version} + + + commons-io + commons-io + 2.16.1 + compile + + + com.google.guava + guava + ${guava.version} + + + + com.baomidou + mybatis-plus-boot-starter + 3.5.1 + + + com.aostarit + smcrypto + 1.0 + system + ${project.basedir}/src/main/resources/libs/aostarit.smcrypto-1.0.0.jar + + + + com.alibaba + easyexcel + 2.2.8 + + + com.fasterxml.jackson.core + jackson-annotations + 2.17.1 + + + + com.github.ulisesbocchio + jasypt-spring-boot-starter + + + + commons-codec + commons-codec + 1.16.1 + + + org.bouncycastle + bcprov-jdk15to18 + 1.68 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + + diff --git a/utils/AESPKCS7PaddingUtils.java b/utils/AESPKCS7PaddingUtils.java new file mode 100644 index 0000000..0aee4a0 --- /dev/null +++ b/utils/AESPKCS7PaddingUtils.java @@ -0,0 +1,127 @@ +package com.sgcc.utils; + +import ch.qos.logback.core.boolex.EvaluationException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.security.Security; + +/** + * AES加密/解密工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/11/22 14:03 + */ +@Slf4j +public class AESPKCS7PaddingUtils { + + /** + * 密钥算法 + */ + private static final String KEY_ALGORITHM = "AES"; + + /** + * 加密/解密算法 / 工作模式 / 填充方式 + * Java 6支持PKCS5Padding填充方式 + * Bouncy Castle支持PKCS7Padding填充方式 + */ + private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding"; + + /** + * 偏移量,只有CBC模式才需要 + */ + private final static String ivParameter = "0000000000000000"; + + /** + * AES要求密钥长度为128位或192位或256位,java默认限制AES密钥长度最多128位 + */ + public static String secretKey = ""; + + /** + * 编码格式 + */ + public static final String ENCODING = "utf-8"; + + static { + //如果是PKCS7Padding填充方式,则必须加上下面这行 + Security.addProvider(new BouncyCastleProvider()); + } + + /** + * AES加密 + * + * @param source 源字符串 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/11/22 14:05 + */ + public static String encrypt(String source) { + try { + byte[] sourceBytes = source.getBytes(ENCODING); + byte[] keyBytes = secretKey.getBytes(ENCODING); + Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC"); + IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes(ENCODING)); + cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, KEY_ALGORITHM),iv); + byte[] decrypted = cipher.doFinal(sourceBytes); + return Base64.encodeBase64String(decrypted); + } catch (Exception e) { + log.error(e.toString()); + } + return null; + } + + /** + * AES解密 + * + * @param encryptStr 加密后的密文 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/11/22 14:05 + */ + public static String decrypt(String encryptStr) { + try { + byte[] sourceBytes = Base64.decodeBase64(encryptStr); + byte[] keyBytes = secretKey.getBytes(ENCODING); + Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC"); + IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes(ENCODING)); + cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, KEY_ALGORITHM),iv); + byte[] decoded = cipher.doFinal(sourceBytes); + return new String(decoded, ENCODING); + } catch (Exception e) { + log.error(e.toString()); + } + return null; + } + + /** + * 校验密码 + * + * @param inputPassword 输入密码 + * @param password 数据库存储密码 + * @return boolean + * @author zhaoyuanyuan + * @date 2024/11/23 09:40 + */ + public static boolean validatePassword(String inputPassword, String password) { + if (decrypt(inputPassword).equals(decrypt(password))) { + return true; + } + return false; + } + + public static void main(String[] args) throws Exception { + //加密 + String enString = AESPKCS7PaddingUtils.encrypt("12345678"); + System.out.println("加密后的字串是:" + enString); + // 解密 + String DeString = AESPKCS7PaddingUtils.decrypt("wUpDBpZlm//omEBf20WCag=="); + System.out.println("解密后的字串是:" + DeString); + } + +} + diff --git a/utils/BeanUtils.java b/utils/BeanUtils.java new file mode 100644 index 0000000..e5504b5 --- /dev/null +++ b/utils/BeanUtils.java @@ -0,0 +1,514 @@ +package com.sgcc.utils; + +import com.google.common.collect.Maps; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; + +/** + * 实体转化工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/06/24 17:35 + */ +@Slf4j +public class BeanUtils { + + private static final String CLASS = "class"; + + private BeanUtils() { + throw new IllegalStateException("Utility class"); + } + + /** + * 判断对象是否为数字 + * + * @param o + * @return + */ + public static boolean isNumber(Object o) { + if (o == null) { + return false; + } + if (o instanceof Number) { + return true; + } + if (o instanceof String) { + try { + Double.parseDouble((String) o); + return true; + } catch (NumberFormatException e) { + return false; + } + } + return false; + } + + /** + * 将bean转化为map + * + * @param clazz bean + * @param 泛型 + * @return Map 返回对象 + */ + public static Map toMap(final T clazz) { + Map paramsMap = Maps.newHashMap(); + try { + BeanInfo bi = Introspector.getBeanInfo(clazz.getClass()); + PropertyDescriptor[] pd = bi.getPropertyDescriptors(); + for (int i = 0; i < pd.length; i++) { + String name = pd[i].getName(); + Method method = pd[i].getReadMethod(); + Object value = method.invoke(clazz); + if (!CLASS.equals(name)) { + paramsMap.put(name, value); + } + } + } catch (IntrospectionException ie) { + log.error("IntrospectionException.className=" + clazz.getClass() + "BeanInfo error : ", ie); + } catch (Exception e) { + log.error("Exception.className=" + clazz.getClass() + "Method error :", e); + } + return paramsMap; + } + + /** + * 获取到对象中属性为指定值的属性名 + * + * @param source 要拷贝的对象 + * @param values 指定的值数组 + * @return + */ + public static String[] getPropertyNamesWithValues(Object source, String... values) { + List valueList = (values != null ? Arrays.asList(values) : null); + final BeanWrapper src = new BeanWrapperImpl(source); + PropertyDescriptor[] pds = src.getPropertyDescriptors(); + Set propertyNames = new HashSet<>(); + for (PropertyDescriptor pd : pds) { + Object srcValue = src.getPropertyValue(pd.getName()); + if (valueList == null && srcValue == null) { + propertyNames.add(pd.getName()); + } else if (valueList != null && valueList.contains(srcValue)) { + propertyNames.add(pd.getName()); + } else { + // DO NOTHING + } + } + String[] result = new String[propertyNames.size()]; + return propertyNames.toArray(result); + } + + /** + * 列表实体类属性拷贝,忽略null值 + * + * @param fromList 待转换实体列数组 + * @param tClass 目标类 + * @param + * @param + * @return + */ + public static List copyPropertiesIgnoreNull(List fromList, Class tClass) { + return copyPropertiesIgnoreValues(fromList, tClass, (String[]) null); + } + + /** + * 实体类属性拷贝,忽略null值、空字符串""和"null" + * + * @param fromList 待转换实体列数组 + * @param tClass 目标类 + * @param + * @param + * @return + */ + public static List copyPropertiesIgnoreEmpty(List fromList, Class tClass) { + return copyPropertiesIgnoreValues(fromList, tClass, null, "", "null"); + } + + /** + * 实体类列表属性拷贝,忽略指定值 + * 将entityList转换成modelList + * + * @param fromList 待转换实体列数组 + * @param tClass 目标类 + * @param values 指定的值数组 + * @param + * @param + * @return + */ + public static List copyPropertiesIgnoreValues(List fromList, Class tClass, String... values) { + Assert.notNull(tClass, "tClass must not be null."); + List tList = new ArrayList<>(); + if (fromList != null && !fromList.isEmpty()) { + for (F f : fromList) { + T t = copyPropertiesIgnoreValues(f, tClass, values); + tList.add(t); + } + } + return tList; + } + + /** + * 实体类列表属性拷贝 + * 将entityList转换成modelList + * + * @param fromList 待转换实体列数组 + * @param tClass 目标类 + * @param + * @param + * @return + */ + public static List copyProperties(List fromList, Class tClass) { + Assert.notNull(tClass, "tClass must not be null."); + List tList = new ArrayList<>(); + if (fromList != null && !fromList.isEmpty()) { + for (F f : fromList) { + T t = copyProperties(f, tClass); + tList.add(t); + } + } + return tList; + } + + /** + * 实体类属性拷贝,忽略null值 + * + * @param entity 实体类 + * @param modelClass 目标类 + * @param + * @param + * @return + */ + public static T copyPropertiesIgnoreNull(F entity, Class modelClass) { + return copyPropertiesIgnoreValues(entity, modelClass, (String[]) null); + } + + /** + * 实体类属性拷贝,忽略null值、空字符串""和"null" + * + * @param entity 实体类 + * @param modelClass 目标类 + * @param + * @param + * @return + */ + public static T copyPropertiesIgnoreEmpty(F entity, Class modelClass) { + return copyPropertiesIgnoreValues(entity, modelClass, null, "", "null"); + } + + /** + * 实体类属性拷贝,忽略指定值 + * + * @param entity 实体类 + * @param modelClass 目标类 + * @param values 指定的值数组 + * @param + * @param + * @return + */ + public static T copyPropertiesIgnoreValues(F entity, Class modelClass, String... values) { + return copyProperties(entity, modelClass, getPropertyNamesWithValues(entity, values)); + } + + /** + * 实体类属性拷贝 + * + * @param entity 实体类 + * @param modelClass 目标类 + * @param + * @param + * @return + */ + public static T copyProperties(F entity, Class modelClass) { + return copyProperties(entity, modelClass, (String[]) null); + } + + /** + * 实体类属性拷贝 + * + * @param entity 实体类 + * @param modelClass 目标类 + * @param ignoreProperties 忽略属性列表 + * @param + * @param + * @return + */ + public static T copyProperties(F entity, Class modelClass, String... ignoreProperties) { + Assert.notNull(modelClass, "modelClass must not be null."); + Object model = null; + + try { + model = modelClass.newInstance(); + } catch (InstantiationException e) { + log.error("copyProperties: InstantiationException", e); + } catch (IllegalAccessException e) { + log.error("copyProperties: IllegalAccessException", e); + } + + if (entity != null) { + org.springframework.beans.BeanUtils.copyProperties(entity, model, ignoreProperties); + } else { + // DO NOTHING + } + return (T) model; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world->helloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelName(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母小写 + return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase(); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 处理真正的驼峰片段 + if (result.length() == 0) { + // 第一个驼峰片段,全部字母都小写 + result.append(camel.toLowerCase()); + } else { + // 其他的驼峰片段,首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + } + return result.toString(); + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world,test_id->helloWorld,testId + * + * @param names 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelNames(String names) { + if (names == null || names.equals("")) { + return null; + } + StringBuilder sb = new StringBuilder(); + String[] fs = names.split(","); + for (String field : fs) { + field = camelName(field); + sb.append(field + ","); + } + String result = sb.toString(); + return result.substring(0, result.length() - 1); + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * (首字母写) 如果转换前的下划线大写方式命名的字符串为空, + * 则返回空字符串。
+ * 例如:hello_world->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelNameCapFirst(String name) { + // 转换为首字母小写的驼峰片段 + String camel = camelName(name); + if (camel == null || camel.length() < 1) { + return name; + } + // 首字母大写 + char[] charArray = camel.toCharArray(); + charArray[0] -= 32; + return String.valueOf(charArray); + } + + /** + * 将驼峰命名转化成下划线 + * + * @param param + * @return + */ + public static String camelToUnderline(String param) { + if (param == null) { + return null; + } + int paramLen = param.length(); + if (paramLen < 3) { + return param.toLowerCase(); + } + int wordCount = 0; + StringBuilder sb = new StringBuilder(param); + // 从第三个字符开始 避免命名不规范 + for (int i = 2; i < paramLen; i++) { + if (Character.isUpperCase(param.charAt(i))) { + sb.insert(i + wordCount, "_"); + wordCount += 1; + } + } + return sb.toString().toLowerCase(); + } + + /** + * 根据指定的类名判定指定的类是否存在。 + * + * @param className + * @return + */ + public static boolean validClass(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + + /** + * 判定类是否继承自父类 + * + * @param cls 子类 + * @param parentClass 父类 + * @return + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public static boolean isInherit(Class cls, Class parentClass) { + return parentClass.isAssignableFrom(cls); + } + + /** + * 输入基类包名,扫描其下的类,返回类的全路径 + * + * @param basePackages 如:com.hotent + * @return + * @throws IllegalArgumentException + */ + @SuppressWarnings("all") + public static List scanPackages(String basePackages) + throws IllegalArgumentException { + ResourcePatternResolver rl = new PathMatchingResourcePatternResolver(); + MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory( + rl); + List result = new ArrayList(); + String[] arrayPackages = basePackages.split(","); + try { + for (int j = 0; j < arrayPackages.length; j++) { + String packageToScan = arrayPackages[j]; + String packagePart = packageToScan.replace('.', '/'); + String classPattern = "classpath*:/" + packagePart + + "/**/*.class"; + Resource[] resources = rl.getResources(classPattern); + for (int i = 0; i < resources.length; i++) { + Resource resource = resources[i]; + MetadataReader metadataReader = metadataReaderFactory + .getMetadataReader(resource); + String className = metadataReader.getClassMetadata() + .getClassName(); + result.add(className); + } + } + } catch (Exception e) { + new IllegalArgumentException("scan pakcage class error,pakcages:" + + basePackages); + } + + return result; + } + + /** + * 将字符串数据按照指定的类型进行转换。 + * + * @param typeName 实际的数据类型 + * @param value 字符串值。 + * @return Object + */ + public static Object convertByActType(String typeName, String value) { + Object o = null; + if (typeName.equals("int")) { + o = Integer.parseInt(value); + } else if (typeName.equals("short")) { + o = Short.parseShort(value); + } else if (typeName.equals("long")) { + o = Long.parseLong(value); + } else if (typeName.equals("float")) { + o = Float.parseFloat(value); + } else if (typeName.equals("double")) { + o = Double.parseDouble(value); + } else if (typeName.equals("boolean")) { + o = Boolean.parseBoolean(value); + } else if (typeName.equals("java.lang.String")) { + o = value; + } else { + o = value; + } + return o; + } + + /** + * 根据类和成员变量名称获取成员变量。 + * + * @param thisClass + * @param fieldName + * @return + * @throws NoSuchFieldException Field + */ + public static Field getField(Class thisClass, String fieldName) + throws NoSuchFieldException { + + if (fieldName == null) { + throw new NoSuchFieldException("Error field !"); + } + + Field field = thisClass.getDeclaredField(fieldName); + return field; + } + + /** + * 数据列表去重 + * + * @param list + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static void removeDuplicate(List list) { + HashSet h = new HashSet(list); + list.clear(); + list.addAll(h); + } + + private static void handleReflectionException(Exception e) { + ReflectionUtils.handleReflectionException(e); + } + +} \ No newline at end of file diff --git a/utils/ClassUtils.java b/utils/ClassUtils.java new file mode 100644 index 0000000..06f1bd1 --- /dev/null +++ b/utils/ClassUtils.java @@ -0,0 +1,58 @@ +package com.sgcc.utils; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Class反射工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/06/24 17:26 + */ +public class ClassUtils { + + /** + * 对象转化为Map + * + * @param obj + * @return {@code Map } + * @author zhaoyuanyuan + * @date 2024/06/24 17:26 + */ + public static Map objectToMap(Object obj) throws IllegalAccessException { + Map map = new HashMap<>(); + if (obj == null){ + return map; + } + Field[] fields = obj.getClass().getDeclaredFields(); + for(Field field:fields){ + field.setAccessible(true); + map.put(field.getName(), field.get(obj)); + } + return map; + } + + /** + * 类型转化,实体对象列表转Map列表 + * + * @param objectList + * @return {@code List> } + * @author zhaoyuanyuan + * @date 2024/06/24 17:27 + */ + public static List> objectListToListMap(List objectList) throws IllegalAccessException { + List> resultList = new ArrayList<>(); + if (objectList == null || objectList.isEmpty()){ + return resultList; + } + for (T t : objectList) { + resultList.add(objectToMap(t)); + } + return resultList; + } + +} diff --git a/utils/CommonUtils.java b/utils/CommonUtils.java new file mode 100644 index 0000000..a885cc3 --- /dev/null +++ b/utils/CommonUtils.java @@ -0,0 +1,200 @@ +package com.sgcc.utils; + +import com.alibaba.fastjson.JSON; +import java.io.IOException; +import java.io.InputStream; +import java.math.RoundingMode; +import java.security.SecureRandom; +import java.text.DecimalFormat; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +import com.sgcc.constant.Constants; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.io.IOUtils; + +/** + * 共通方法工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/06/24 17:18 + */ +@Slf4j +public class CommonUtils { + + public static final String JSON_PATH = "classpath:json/"; + + /** + * ip和掩码分隔符 + */ + public static final String IP_MASK_CODE_SEPARATOR = "\\/"; + + /** + * 解析JSON值 + * + * @param fileName 文件名 + * @param clazz 实体类 + * @param 泛型 + * @return + */ + public static T parseJson(String fileName, Class clazz) throws IOException { + return JSON.parseObject(readJsonFile(fileName), clazz); + } + + /** + * 读取json格式文件 + * + * @param fileName 文件名 + * @return + */ + public static String readJsonFile(String fileName) throws IOException { + return read(JSON_PATH + fileName); + } + + /** + * 读取json格式文件 + * + * @param path 文件路径 + * @return + */ + public static String read(String path) throws IOException { + String content = ""; + InputStream stream = null; + try { + stream = CommonUtils.class.getClassLoader() + .getResourceAsStream(path.replace("classpath:", "")); + content = IOUtils.toString(stream, "UTF-8"); + } catch (IOException e) { + log.error("read file[{}] catch IOException. {}", path, e.getMessage()); + } finally { + stream.close(); + } + return content; + } + + /** + * 布尔值判断 true-0 false-1 + * + * @param param + * @return {@code Integer } + * @author zhaoyuanyuan + * @date 2024/06/24 17:21 + */ + public static Integer booleanValueJudge(Boolean param) { + if (param == null) { + return null; + } + if (param) { + return Constants.IS_TRUE; + } else { + return Constants.IS_FALSE; + } + } + + /** + * 获取IP地址 + * + * @param ipAndMaskOffCode ip和屏蔽代码 + * @return {@code String} + */ + public static String getIp(String ipAndMaskOffCode) { + String ip = ""; + if(StringUtils.isEmpty(ipAndMaskOffCode)){ + return ip; + } + String[] ipAndMaskOffCodes = ipAndMaskOffCode.split(IP_MASK_CODE_SEPARATOR); + if (ipAndMaskOffCodes.length > 1) { + ip = ipAndMaskOffCodes[0]; + }else { + ip =ipAndMaskOffCode; + } + return ip; + } + + /** + * 获取掩码 + * + * @param ipAndMaskOffCode ip和屏蔽代码 + * @return {@code String} + */ + public static String getMaskOffCode(String ipAndMaskOffCode) { + String maskOffCode = ""; + if (StringUtils.isEmpty(ipAndMaskOffCode)){ + return maskOffCode; + } + String[] ipAndMaskOffCodes = ipAndMaskOffCode.split(IP_MASK_CODE_SEPARATOR); + if (ipAndMaskOffCodes.length >= 2) { + maskOffCode = ipAndMaskOffCodes[1]; + } + return maskOffCode; + } + + /** + * 字符串形式的数组转换为List + * + * @param integerArrStr 数组字符串 + * @return {@code List } + * @author zhaoyuanyuan + * @date 2024/07/11 09:43 + */ + public static List string2IntegerList(String integerArrStr) { + List tempList = Arrays.asList(integerArrStr.split(",")); + List resultList = tempList.stream().map(Integer::valueOf).collect(Collectors.toList()); + return resultList; + } + + /** + * 随机获取列表中的某一个元素 + * + * @param list 列表 + * @return {@code T } + * @author zhaoyuanyuan + * @date 2024/07/18 16:16 + */ + public static T getRandomElement(List list) { + if (list == null || list.isEmpty()) { + throw new IllegalArgumentException("List cannot be null or empty"); + } + SecureRandom random = new SecureRandom(); + int index = random.nextInt(list.size()); + return list.get(index); + } + + /** + * Double类型数据保留两位小数 + * + * @param value 值 + * @return {@code Double } + * @author zhaoyuanyuan + * @date 2024/09/18 14:01 + */ + public static Double formatDouble(Double value) { + //格式化字符串,表示两位小数 + DecimalFormat df = new DecimalFormat("#.00"); + //设置格式化器 + df.setRoundingMode(RoundingMode.HALF_UP); + //转换并输出 + String formattedValue = df.format(value); + return Double.valueOf(formattedValue); + } + + /** + * 身份证号脱敏处理 + * + * @param idCard 身份证号 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/11/21 13:14 + */ + public static String desensitizedIdCard(String idCard) { + if (idCard == null || (idCard.length() != 18 && idCard.length() != 15)) { + return null; + } + return idCard.replaceAll("^(\\d{6})(\\d+)(\\d{4})$", "$1****$3"); + } + +} \ No newline at end of file diff --git a/utils/DateUtils.java b/utils/DateUtils.java new file mode 100644 index 0000000..042beeb --- /dev/null +++ b/utils/DateUtils.java @@ -0,0 +1,300 @@ +package com.sgcc.utils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Date; +import org.apache.commons.lang3.time.DateFormatUtils; + +/** + * 时间日期工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/07/23 14:24 + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils { + + public static final String YYYY = "yyyy"; + + public static final String YYYY_MM = "yyyy-MM"; + + public static final String YYYY_MM_DD = "yyyy-MM-dd"; + + public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static final String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM" }; + + /** + * 获取当前Date型日期 + * + * @return {@code Date } + * @author zhaoyuanyuan + * @date 2024/07/23 14:25 + */ + public static Date getNowDate() { + return new Date(); + } + + /** + * 获取当前Date型日期 YYYY_MM_DD + * + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:25 + */ + public static String getDate() { + return dateTimeNow(YYYY_MM_DD); + } + + /** + * 获取当前Date型日期 YYYY_MM_DD_HH_MM_SS + * + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:25 + */ + public static final String getTime() { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + /** + * 获取当前Date型日期 YYYYMMDDHHMMSS + * + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:25 + */ + public static final String dateTimeNow() { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + /** + * 获取当前Date型日期 format + * + * @param format 格式化类型 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:25 + */ + public static final String dateTimeNow(final String format) { + return parseDateToStr(format, new Date()); + } + + /** + * 获取Date型日期 YYYY_MM_DD + * + * @param date + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:26 + */ + public static final String dateTime(final Date date) { + return parseDateToStr(YYYY_MM_DD, date); + } + + /** + * 将Date型日期转换为format型字符串 + * + * @param format 格式化类型 + * @param date 日期 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:26 + */ + public static final String parseDateToStr(final String format, final Date date) { + return new SimpleDateFormat(format).format(date); + } + + /** + * 获取Date型日期 format + * + * @param format 格式化类型 + * @param ts 日期字符串 + * @return {@code Date } + * @author zhaoyuanyuan + * @date 2024/07/23 14:27 + */ + public static final Date dateTime(final String format, final String ts) { + try { + return new SimpleDateFormat(format).parse(ts); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2024/08/08 + * + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:27 + */ + public static final String datePath() { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20240808 + * + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:27 + */ + public static final String dateTime() { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期格式 + * + * @param str + * @return {@code Date } + * @author zhaoyuanyuan + * @date 2024/07/23 14:28 + */ + public static Date parseDate(Object str) { + if (str == null) { + return null; + } + try { + return parseDate(str.toString(), parsePatterns); + } catch (ParseException e) { + return null; + } + } + + /** + * 获取服务器启动时间 + * + * @return {@code Date } + * @author zhaoyuanyuan + * @date 2024/07/23 14:28 + */ + public static Date getServerStartDate() { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算相差天数 + * + * @param date1 开始日期 + * @param date2 结束日期 + * @return int + * @author zhaoyuanyuan + * @date 2024/07/23 14:28 + */ + public static int differentDaysByMillisecond(Date date1, Date date2) { + return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); + } + + /** + * 计算两个时间差 + * + * @param startDate 开始日期 + * @param endDate 结束日期 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/07/23 14:30 + */ + public static String getDatePoor(Date startDate, Date endDate) { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = startDate.getTime() - endDate.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + //输出结果 + return day + "天" + hour + "小时" + min + "分钟"; + } + + /** + * 将 LocalDateTime 对象转换为 Date 对象 + * + * @param temporalAccessor LocalDateTime 实例 + * @return {@code Date } + * @author zhaoyuanyuan + * @date 2024/07/23 14:30 + */ + public static Date toDate(LocalDateTime temporalAccessor) { + // 将 LocalDateTime 转换为系统默认时区的 ZonedDateTime + ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); + // 使用 ZonedDateTime 的瞬时时间创建 Date 对象 + return Date.from(zdt.toInstant()); + } + + /** + * 将 LocalDate 对象转换为 Date 对象 + * + * @param temporalAccessor LocalDate 实例 + * @return {@code Date } + * @author zhaoyuanyuan + * @date 2024/07/23 14:30 + */ + public static Date toDate(LocalDate temporalAccessor) { + // 将 LocalDate 转换为 LocalDateTime,时间为 00:00:00 + LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); + // 将 LocalDateTime 转换为系统默认时区的 ZonedDateTime + ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); + // 使用 ZonedDateTime 的瞬时时间创建 Date 对象 + return Date.from(zdt.toInstant()); + } + + /** + * 判断传入日期是否在系统当前日期之后 + * + * @param date 日期 + * @return boolean + * @author zhaoyuanyuan + * @date 2024/07/23 14:34 + */ + public static boolean isGreaterThanNow(Date date) { + Date nowDate = new Date(); + int compareResult = date.compareTo(nowDate); + if (compareResult > 0) { + return true; + } else { + return false; + } + } + + /** + * 获取指定日期特定分钟数后的日期 + * + * @param date 指定日期 + * @param minutes 分钟数 + * @return {@code Date } + * @author zhaoyuanyuan + * @date 2024/07/31 16:50 + */ + public static Date getMinutesAfterDate(Date date, Integer minutes) { + Instant instant = date.toInstant(); + //转换为LocalDateTime + LocalDateTime specifiedDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + //在指定日期基础上,增加指定分钟数 + LocalDateTime newDateTime = specifiedDateTime.plus(Duration.ofMinutes(minutes)); + return toDate(newDateTime); + } + +} diff --git a/utils/EscUtils.java b/utils/EscUtils.java new file mode 100644 index 0000000..6e750da --- /dev/null +++ b/utils/EscUtils.java @@ -0,0 +1,28 @@ +package com.sgcc.utils; + +import lombok.extern.slf4j.Slf4j; +import org.jasypt.encryption.StringEncryptor; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * 配置加密工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/10/31 13:30 + */ +@Slf4j +public class EscUtils { + + @Autowired + private StringEncryptor stringEncryptor; + + public String test(String str) { + String encData = stringEncryptor.encrypt(str); + String decData = stringEncryptor.decrypt(encData); + log.info("加密数据:[{}]", encData); + log.info("解密数据:[{}]", decData); + return encData; + } + +} diff --git a/utils/HttpsUtils.java b/utils/HttpsUtils.java new file mode 100644 index 0000000..f0a0ff6 --- /dev/null +++ b/utils/HttpsUtils.java @@ -0,0 +1,164 @@ +package com.sgcc.utils; + +import cn.hutool.json.JSONObject; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +/** + * Http请求工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/06/24 17:14 + */ +@Slf4j +public class HttpsUtils { + + /** + * 字符编码utf-8 + */ + public static final String CHARSET_UTF8 = "UTF-8"; + /** + * https请求url前缀 + */ + public static final String HTTPS_PREFIX = "https"; + /** + * 认证信息 + */ + public static final String AUTHORIZATION = "Authorization"; + + /** + * post提交 + * + * @param url url + * @param map 请求入参 + * @param header 头信息 + * @return {@code String} + */ + public static String doPost(String url, Map map, Map header) { + return doPost(url, map, CHARSET_UTF8, header); + } + + /** + * post请求 + * + * @param url url + * @param map 请求入参 + * @param charset 字符集 + * @param header 头 + * @return {@code String} + */ + public static String doPost(String url, Map map, String charset, Map header) { + HttpClient httpClient = null; + HttpPost httpPost = null; + String result = null; + try { + httpClient = new DefaultHttpClient(); + httpPost = new HttpPost(url); + //设置参数 + List list = new ArrayList(); + Iterator iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry elem = (Map.Entry) iterator.next(); + list.add(new BasicNameValuePair(elem.getKey(), elem.getValue())); + } + if (list.size() > 0) { + Map param = new HashMap<>(); + param.putAll(map); + log.info("httpParam:{}", param); + StringEntity stringEntity = new StringEntity(new JSONObject(param).toString()); + httpPost.setEntity(stringEntity); + } + if (header.size() > 0) { + //设置请求头 + Iterator entryList = header.entrySet().iterator(); + while (entryList.hasNext()) { + Map.Entry entry = (Map.Entry) entryList.next(); + httpPost.setHeader(entry.getKey(), entry.getValue()); + } + } + HttpResponse response = httpClient.execute(httpPost); + if (response != null) { + HttpEntity resEntity = response.getEntity(); + if (resEntity != null) { + result = EntityUtils.toString(resEntity, charset); + } + } + } catch (Exception e) { + log.error("HttpsUtils doPost exception: {}", e.getMessage()); + } + return result; + } + + /** + * https Get 请求方式 + * + * @param url 请求url + * @param header 请求头 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/06/24 17:16 + */ + public static String doGet(String url, Map header) { + return doGet(url, header, new HashMap<>()); + } + + /** + * https Get 请求方式 + * + * @param url url + * @param header 请求头 + * @param uriVariable 请求参数 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/06/24 17:16 + */ + public static String doGet(String url, Map header, Map uriVariable) { + HttpClient httpClient = null; + HttpGet httpGet = null; + String result = null; + try { + httpClient = new DefaultHttpClient(); + URIBuilder uriBuilder = new URIBuilder(url); + // 请求参数 + if (uriVariable != null) { + uriVariable.forEach(uriBuilder::addParameter); + } + URI uri = uriBuilder.build(); + httpGet = new HttpGet(uri); + log.info("HttpsUtils doGet: {}", httpGet.getRequestLine().getUri()); + // 请求头 + if (header != null) { + header.forEach(httpGet::setHeader); + } + HttpResponse response = httpClient.execute(httpGet); + if (response != null) { + HttpEntity resEntity = response.getEntity(); + log.info("HttpsUtils doGet response status: {}", response.getStatusLine().getStatusCode()); + if (resEntity != null) { + result = EntityUtils.toString(resEntity, CHARSET_UTF8); + } + } + } catch (Exception e) { + log.error("HttpsUtils doGet exception: {}", e.getMessage()); + } + return result; + } + +} \ No newline at end of file diff --git a/utils/JwtUtils.java b/utils/JwtUtils.java new file mode 100644 index 0000000..2ae804a --- /dev/null +++ b/utils/JwtUtils.java @@ -0,0 +1,113 @@ +package com.sgcc.utils; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTCreator; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.sgcc.entity.User; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * JWT工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/06/27 14:47 + */ +@Slf4j +public class JwtUtils { + + /** + * JWT用户名 + */ + private static final String USER_NAME = "admin"; + + /** + * token有效时间 + */ + public static final int TOKEN_TIME_OUT = 1000 * 60 * 60; + + /** + * 生成token + * + * @param user 用户信息 + * @param key 用于签名加密的密钥 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/11/22 11:15 + */ + public static String getToken(User user, String key) { + //获取jwt生成器 + JWTCreator.Builder jwtBuilder = JWT.create(); + //该生成器设置Header的参数为一个的Map, + Map headers = new HashMap<>(); + //设置token的type为jwt + headers.put("typ", "jwt"); + //表明加密的算法为HS256 + headers.put("alg", "hs256"); + //开始生成token + String token = jwtBuilder.withHeader(headers) + //接下来为设置PayLoad,Claim中的键值对可自定义 + //设置用户ID + .withClaim("userId", user.getId()) + //设置用户角色ID + .withClaim("roleId", user.getRoleId()) + //token失效时间,这里为一消失后失效 + .withExpiresAt(new Date(System.currentTimeMillis() + TOKEN_TIME_OUT)) + //设置该jwt的发行时间,一般为当前系统时间 + .withIssuedAt(new Date(System.currentTimeMillis())) + //token的发行者(可自定义) + .withIssuer(USER_NAME) + //进行签名,选择加密算法,以一个字符串密钥为参数 + .sign(Algorithm.HMAC256(key)); + log.info("-------------Token={}-------------", token); + return token; + } + + /** + * 验证Token + * + * @param token 凭证 + * @return boolean + * @author zhaoyuanyuan + * @date 2024/06/27 14:55 + */ + public static boolean verify(String token) { + if (StringUtils.isBlank(token)) { + return false; + } + DecodedJWT decode = JWT.decode(token); + //若验证成功,就可获取其携带的信息进行其他操作 + if (decode.getClaim("userId") == null) { + return false; + } + log.info("用户ID[{}]", decode.getClaim("userId").asInt()); + log.info("用户角色ID[{}]", decode.getClaim("roleId").asInt()); + //获取发送者,没有设置则为空 + log.info("发送者[{}]", decode.getIssuer()); + //获取过期时间 + log.info("过期时间[{}]", String.valueOf(decode.getExpiresAt())); + //获取主题,没有设置则为空 + log.info("主题[{}]", decode.getSubject()); + return true; + } + + /** + * 获取Token中的userId + * + * @param token 凭证 + * @return {@code Integer } + * @author zhaoyuanyuan + * @date 2024/11/21 09:52 + */ + public static Integer getUserId(String token) { + DecodedJWT decode = JWT.decode(token); + return decode.getClaim("userId").asInt(); + } + +} diff --git a/utils/MD5Utils.java b/utils/MD5Utils.java new file mode 100644 index 0000000..02faba1 --- /dev/null +++ b/utils/MD5Utils.java @@ -0,0 +1,67 @@ +package com.sgcc.utils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * 用户登录相关工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/06/26 17:24 + */ +public class MD5Utils { + + /** + * MD5转字符串 + * + * @param bytes + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/06/26 17:25 + */ + public static String toHexString(byte[] bytes) { + StringBuilder hexString = new StringBuilder(); + for (byte b : bytes) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } + + /** + * 密码加密 + * + * @param password 密码 + * @return {@code String } + * @author zhaoyuanyuan + * @date 2024/06/26 17:25 + */ + public static String encryptPassword(String password) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(password.getBytes()); + byte[] digest = md.digest(); + return toHexString(digest); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("MD5 algorithm not found", e); + } + } + + /** + * 密码验证 + * + * @param inputPassword 表单输入密码 + * @param storedPassword 数据库存储加密密码 + * @return boolean + * @author zhaoyuanyuan + * @date 2024/06/26 17:27 + */ + public static boolean validatePassword(String inputPassword, String storedPassword) { + return encryptPassword(inputPassword).equals(storedPassword); + } + +} diff --git a/utils/PageUtils.java b/utils/PageUtils.java new file mode 100644 index 0000000..da4037c --- /dev/null +++ b/utils/PageUtils.java @@ -0,0 +1,40 @@ +package com.sgcc.utils; + +/** + * 分页工具 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/06/24 16:05 + */ +public class PageUtils { + + /** + * 根据总数计算总页数 + * + * @param totalCount 总数 + * @param pageSize 每页数 + * @return 总页数 + */ + public static int totalPage(int totalCount, int pageSize) { + if (pageSize == 0) { + return 0; + } + return totalCount % pageSize == 0 ? (totalCount / pageSize) : (totalCount / pageSize + 1); + } + + /** + * 根据总数计算总页数 + * + * @param totalCount 总数 + * @param pageSize 每页数 + * @return 总页数 + */ + public static long totalPage(long totalCount, long pageSize) { + if (pageSize == 0) { + return 0; + } + return totalCount % pageSize == 0 ? (totalCount / pageSize) : (totalCount / pageSize + 1); + } + +} \ No newline at end of file diff --git a/utils/RedisUtils.java b/utils/RedisUtils.java new file mode 100644 index 0000000..876e5cc --- /dev/null +++ b/utils/RedisUtils.java @@ -0,0 +1,704 @@ +package com.sgcc.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Redis封装工具类 + * + * @author zhaoyuanyuan + * @version 1.0.0 + * @date 2024/07/03 11:30 + */ +@Slf4j +@Component +public class RedisUtils { + + @Resource + private RedisTemplate redisTemplate; + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + log.info("RedisCmd==================expire key:[{}]", key); + if (time > 0) { + //logger.debug("指定缓存失效时间key="+key + ",time=" + time); + redisTemplate.expire(key, time, TimeUnit.SECONDS); + + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据key获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + log.info("RedisCmd==================getExpire key:[{}]", key); + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + log.info("RedisCmd==================hasKey key:[{}]", key); + return redisTemplate.hasKey(key); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 重名名key,如果newKey已经存在,则newKey的原值被覆盖 + * + * @param oldKey 原key + * @param newKey 新key + */ + public void renameKey(String oldKey, String newKey) { + try { + log.info("RedisCmd==================renameKey oldKey:[{}] newKey:[{}]", oldKey, newKey); + redisTemplate.rename(oldKey, newKey); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * newKey不存在时才重命名 + * + * @param oldKey 原key + * @param newKey 新key + * @return 修改成功返回true + */ + public boolean renameKeyNotExist(String oldKey, String newKey) { + try { + log.info("RedisCmd==================renameKeyNotExist oldKey:[{}] newKey:[{}]", oldKey, newKey); + return redisTemplate.renameIfAbsent(oldKey, newKey); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除key + * + * @param key 键 + */ + public void deleteKey(String key) { + try { + log.info("RedisCmd==================deleteKey key:[{}]", key); + redisTemplate.delete(key); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除多个key + * + * @param keys + */ + public void deleteKeys(String... keys) { + try { + log.info("RedisCmd==================deleteKeys keys:[{}]", keys); + Set kSet = Stream.of(keys).map(k -> k).collect(Collectors.toSet()); + redisTemplate.delete(kSet); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Set keys(String key) { + log.info("RedisCmd==================keys key:[{}]", key); + return key == null ? null : redisTemplate.keys(key); + } + + // ============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + log.info("RedisCmd==================get key:[{}]", key); + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + log.info("RedisCmd==================set key:[{}]", key); + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + log.info("RedisCmd==================set2 key:[{}]", key); + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 递增 + * + * @param key 键 + * @param delta 步长 + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + log.info("RedisCmd==================incr key:[{}]", key); + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * + * @param key 键 + * @param delta 步长 + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + log.info("RedisCmd==================decr key:[{}]", key); + return redisTemplate.opsForValue().increment(key, -delta); + } + + // ================================Map================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hGet(String key, String item) { + log.info("RedisCmd==================hGet key:[{}]", key); + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmGet(String key) { + log.info("RedisCmd==================hmGet key:[{}]", key); + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet存储 + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmSet(String key, Map map) { + try { + log.info("RedisCmd==================hmSet key:[{}]", key); + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmSet(String key, Map map, long time) { + try { + log.info("RedisCmd==================hmSet2 key:[{}]", key); + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hSet(String key, String item, Object value) { + try { + log.info("RedisCmd==================hSet1 key:[{}]", key); + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hSet(String key, String item, Object value, long time) { + try { + log.info("RedisCmd==================hSet2 key:[{}]", key); + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hDel(String key, Object... item) { + log.info("RedisCmd==================hDel key:[{}]", key); + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + log.info("RedisCmd==================hHasKey key:[{}]", key); + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hIncr(String key, String item, double by) { + log.info("RedisCmd==================hIncr key:[{}]", key); + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hDecr(String key, String item, double by) { + log.info("RedisCmd==================hDecr key:[{}]", key); + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + log.info("RedisCmd==================sGet key:[{}]", key); + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + log.info("RedisCmd==================sHasKey key:[{}]", key); + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + log.info("RedisCmd==================sSet key:[{}]", key); + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + log.info("RedisCmd==================sSetAndTime key:[{}]", key); + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + log.info("RedisCmd==================sGetSetSize key:[{}]", key); + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + log.info("RedisCmd==================setRemove key:[{}]", key); + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + log.info("RedisCmd==================lGet key:[{}]", key); + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + log.info("RedisCmd==================lGetListSize key:[{}]", key); + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + log.info("RedisCmd==================lGetIndex key:[{}]", key); + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + log.info("RedisCmd==================lSet1 key:[{}]", key); + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + log.info("RedisCmd==================lSet2 key:[{}]", key); + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + log.info("RedisCmd==================lSet3 key:[{}]", key); + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + log.info("RedisCmd==================lSet4 key:[{}]", key); + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + log.info("RedisCmd==================lUpdateIndex key:[{}]", key); + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + log.info("RedisCmd==================lRemove key:[{}]", key); + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 从list中删除并返回第一个元素 + * + * @param key + * @return + */ + public Object lPop(String key) { + try { + log.info("RedisCmd==================lPop key:[{}]", key); + return redisTemplate.opsForList().leftPop(key); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 将value放入list的尾部 + * + * @param key + * @param value + * @return + */ + public boolean rPush(String key, Object value) { + try { + log.info("RedisCmd==================rPush key:[{}]", key); + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + +} + +