Java常用工具类整合
一、字符串相关
StringUtils
-
isEmpty() 判断字符串是否为空(在cs为null,""的情况下返回true)
public static boolean isEmpty(final CharSequence cs) { return cs == null || cs.length() == 0; }
- isBlank() 判断字符串是否为空(在cs为null,""," "的情况下返回true)
public static boolean isBlank(final CharSequence cs) { int strLen; if (cs == null || (strLen = cs.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } return true; }
- equals() 判断两个字符串是否为空,两者都是null也会返回true,区分大小写
public static boolean equals(final CharSequence cs1, final CharSequence cs2) { if (cs1 == cs2) { return true; } if (cs1 == null || cs2 == null) { return false; } if (cs1.length() != cs2.length()) { return false; } if (cs1 instanceof String && cs2 instanceof String) { return cs1.equals(cs2); } // Step-wise comparison final int length = cs1.length(); for (int i = 0; i < length; i++) { if (cs1.charAt(i) != cs2.charAt(i)) { return false; } } return true; }
- join() 合并数组为单一字符串,可传分隔符
- spit() 分割字符串
- trimToNull:trim后为空字符串则转换为null
- replace:替换字符串
- capitalize:首字符大写
二、I/O相关
- org.apache.commons.io.IOUtils
closeQuietly:关闭一个IO流、socket、或者selector且不抛出异常,通常放在finally块
toString:转换IO流、 Uri、 byte[]为String
copy:IO流数据复制,从输入流写到输出流中,最大支持2GB
toByteArray:从输入流、URI获取byte[]
write:把字节. 字符等写入输出流
toInputStream:把字符转换为输入流
readLines:从输入流中读取多行数据,返回List<String>
copyLarge:同copy,支持2GB以上数据的复制
lineIterator:从输入流返回一个迭代器,根据参数要求读取的数据量,全部读取,如果数据不够,则失败 -
org.apache.commons.io.FileUtils
readFileToString:以字符形式读取文件内容
deleteQueitly:删除文件或文件夹且不会抛出异常
copyFile:复制文件
writeStringToFile:把字符写到目标文件,如果文件不存在,则创建
forceMkdir:强制创建文件夹,如果该文件夹父级目录不存在,则创建父级
write:把字符写到指定文件中
listFiles:列举某个目录下的文件(根据过滤器)
copyDirectory:复制文件夹
forceDelete:强制删除文件 -
org.apache.commons.io.FilenameUtils
getExtension:返回文件后缀名
getBaseName:返回文件名,不包含后缀名
getName:返回文件全名
concat:按命令行风格组合文件路径(详见方法注释)
removeExtension:删除后缀名
normalize:使路径正常化
wildcardMatch:匹配通配符
seperatorToUnix:路径分隔符改成unix系统格式的,即/
getFullPath:获取文件路径,不包括文件名
isExtension:检查文件后缀名是不是传入参数(List<String>)中的一个
三、集合/数组相关
-
org.apache.commons.lang3.ArrayUtils
contains:是否包含某字符串
addAll:添加整个数组
clone:克隆一个数组
isEmpty:是否空数组
add:向数组添加元素
subarray:截取数组
indexOf:查找某个元素的下标
isEquals:比较数组是否相等
toObject:基础类型数据数组转换为对应的Object数组 -
org.apache.commons.collections.CollectionUtils
isEmpty:是否为空
select:根据条件筛选集合元素
transform:根据指定方法处理集合元素,类似List的map()
filter:过滤元素,类似List的filter()
find:基本和select一样
collect:和transform 差不多一样,但是返回新数组
forAllDo:调用每个元素的指定方法
isEqualCollection:判断两个集合是否一致
四、具体实例
Java自带工具方法:
1、List集合拼接成以逗号分隔的字符串
// 如何把list集合拼接成以逗号分隔的字符串 a,b,c List<String> list = Arrays.asList("a", "b", "c"); // 第一种方法,可以用stream流 String join = list.stream().collect(Collectors.joining(",")); System.out.println(join); // 输出 a,b,c // 第二种方法,其实String也有join方法可以实现这个功能 String join = String.join(",", list); System.out.println(join); // 输出 a,b,c
2、比较两个字符串是否相等,忽略大小写
if (strA.equalsIgnoreCase(strB)) { System.out.println("相等"); }
3、比较两个对象是否相等【当我们用 equals 比较两个对象是否相等的时候,还需要对左边的对象进行判空,不然可能会报空指针异常,我们可以用 java.util 包下 Objects 封装好的比较是否相等的方法】
Objects.equals(strA, strB);
4、两个 List 集合取交集
List<String> list1 = new ArrayList<>(); list1.add("a"); list1.add("b"); list1.add("c"); List<String> list2 = new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("d"); list1.retainAll(list2); System.out.println(list1); // 输出[a, b]
apache commons 工具类库:
5、包装临时对象【当一个方法需要返回两个及以上字段时,我们一般会封装成一个临时对象返回,现在有了 Pair 和 Triple 就不需要了】
// 返回两个字段 ImmutablePair<Integer, String> pair = ImmutablePair.of(1, "yideng"); System.out.println(pair.getLeft() + "," + pair.getRight()); // 输出 1,yideng // 返回三个字段 ImmutableTriple<Integer, String, Date> triple = ImmutableTriple.of(1, "yideng", new Date()); System.out.println(triple.getLeft() + "," + triple.getMiddle() + "," + triple.getRight()); // 输出 1,yideng,Wed Apr 07 23:30:00 CST 2021
6、commons-io 文件流处理
File file = new File("demo1.txt"); // 读取文件 List<String> lines = FileUtils.readLines(file, Charset.defaultCharset()); // 写入文件 FileUtils.writeLines(new File("demo2.txt"), lines); // 复制文件 FileUtils.copyFile(srcFile, destFile);
7、common-beanutils 操作对象
// 设置对象属性 User user = new User(); BeanUtils.setProperty(user, "id", 1); BeanUtils.setProperty(user, "name", "yideng"); System.out.println(BeanUtils.getProperty(user, "name")); // 输出 yideng System.out.println(user); // 输出 {"id":1,"name":"yideng"} // 对象和 map 互转 // 对象转map Map<String, String> map = BeanUtils.describe(user); System.out.println(map); // 输出 {"id":"1","name":"yideng"} // map转对象 User newUser = new User(); BeanUtils.populate(newUser, map); System.out.println(newUser); // 输出 {"id":1,"name":"yideng"}
Google Guava 工具类库
8、创建集合
List<String> list = Lists.newArrayList(); List<Integer> list = Lists.newArrayList(1, 2, 3); // 反转list List<Integer> reverse = Lists.reverse(list); System.out.println(reverse); // 输出 [3, 2, 1] // list集合元素太多,可以分成若干个集合,每个集合10个元素 List<List<Integer>> partition = Lists.partition(list, 10); Map<String, String> map = Maps.newHashMap(); Set<String> set = Sets.newHashSet();
9、Multimap 一个 key 可以映射多个 value 的 HashMap
Multimap<String, Integer> map = ArrayListMultimap.create(); map.put("key", 1); map.put("key", 2); Collection<Integer> values = map.get("key"); System.out.println(map); // 输出 {"key":[1,2]} // 还能返回你以前使用的臃肿的Map Map<String, Collection<Integer>> collectionMap = map.asMap();
10、BiMap 一种连 value 也不能重复的 HashMap
BiMap<String, String> biMap = HashBiMap.create(); // 如果value重复,put方法会抛异常,除非用forcePut方法 biMap.put("key","value"); System.out.println(biMap); // 输出 {"key":"value"} // 既然value不能重复,何不实现个翻转key/value的方法,已经有了 BiMap<String, String> inverse = biMap.inverse(); System.out.println(inverse); // 输出 {"value":"key"}
11、Table 一种有两个 key 的 HashMap
// 一批用户,同时按年龄和性别分组 Table<Integer, String, String> table = HashBasedTable.create(); table.put(18, "男", "yideng"); table.put(18, "女", "Lily"); System.out.println(table.get(18, "男")); // 输出 yideng // 这其实是一个二维的Map,可以查看行数据 Map<String, String> row = table.row(18); System.out.println(row); // 输出 {"男":"yideng","女":"Lily"} // 查看列数据 Map<Integer, String> column = table.column("男"); System.out.println(column); // 输出 {18:"yideng"}
12、Multiset 一种用来计数的 Set
Multiset<String> multiset = HashMultiset.create(); multiset.add("apple"); multiset.add("apple"); multiset.add("orange"); System.out.println(multiset.count("apple")); // 输出 2 // 查看去重的元素 Set<String> set = multiset.elementSet(); System.out.println(set); // 输出 ["orange","apple"] // 还能查看没有去重的元素 Iterator<String> iterator = multiset.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } // 还能手动设置某个元素出现的次数 multiset.setCount("apple", 5);
13、Java8 时间处理类
package com.ai.oss.utils; import org.apache.commons.compress.utils.Lists; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjusters; import java.util.List; /** * java1.8 的新特性,解决SimpleDateFormat的线程问题 * Instant代替 Date,LocalDateTime代替 Calendar * 注意:如果是共享变量,则可能会出现线程问题。 * @author helin * @date 2021/5/10 11:02 * @description 基于Java8的Lambda日期处理工具类 */ public class DataUtil { // 时间元素 private static final String YEAR = "year"; private static final String MONTH = "month"; private static final String WEEK = "week"; private static final String DAY = "day"; private static final String HOUR = "hour"; private static final String MINUTE = "minute"; private static final String SECOND = "second"; // 星期元素 private static final String MONDAY = "MONDAY";// 星期一 private static final String TUESDAY = "TUESDAY";// 星期二 private static final String WEDNESDAY = "WEDNESDAY";// 星期三 private static final String THURSDAY = "THURSDAY";// 星期四 private static final String FRIDAY = "FRIDAY";// 星期五 private static final String SATURDAY = "SATURDAY";// 星期六 private static final String SUNDAY = "SUNDAY";// 星期日 // 根据指定格式显示日期和时间 private static final DateTimeFormatter yyyyMMdd_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd"); private static final DateTimeFormatter yyyyMMddHH_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH"); private static final DateTimeFormatter yyyyMMddHHmm_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); private static final DateTimeFormatter yyyyMMddHHmmss_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private static final DateTimeFormatter HHmmss_EN = DateTimeFormatter.ofPattern("HH:mm:ss"); private static final DateTimeFormatter yyyyMMdd_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日"); private static final DateTimeFormatter yyyyMMddHH_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时"); private static final DateTimeFormatter yyyyMMddHHmm_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分"); private static final DateTimeFormatter yyyyMMddHHmmss_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒"); private static final DateTimeFormatter HHmmss_CN = DateTimeFormatter.ofPattern("HH时mm分ss秒"); // 本地时间显示格式:区分中文和外文显示 private static final DateTimeFormatter shotDate = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT); private static final DateTimeFormatter fullDate = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL); private static final DateTimeFormatter longDate = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG); private static final DateTimeFormatter mediumDate = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM); /** * 获取当前日期 * @return yyyy-MM-dd */ public static String getNowDate_EN() { return String.valueOf(LocalDate.now()); } /** * 获取当前日期 * @return yyyy-MM-dd HH:mm:ss */ public static String getNowTime_EN() { return LocalDateTime.now().format(yyyyMMddHHmmss_EN); } /** * 获取当前日期 * @return yyyy-MM-dd HH */ public static String getNowTime_EN_yMdH() { return LocalDateTime.now().format(yyyyMMddHH_EN); } /** * 获取当前日期 * @return yyyy年MM月dd日 */ public static String getNowTime_CN_yMdH() { return LocalDateTime.now().format(yyyyMMddHH_CN); } /** * 获取当前日期 * @return yyyy-MM-dd HH:mm */ public static String getNowTime_EN_yMdHm() { return LocalDateTime.now().format(yyyyMMddHHmm_EN); } /** * 获取当前日期 * @return yyyy年MM月dd日HH时mm分 */ public static String getNowTime_CN_yMdHm() { return LocalDateTime.now().format(yyyyMMddHHmm_CN); } /** * 获取当前日期 * @return HH时mm分ss秒 */ public static String getNowTime_CN_HHmmss() { return LocalDateTime.now().format(HHmmss_CN); } /** * 根据日期格式,获取当前时间 * * @param formatStr 日期格式<br> * <li>yyyy</li> * <li>yyyy-MM-dd</li> * <li>yyyy-MM-dd HH:mm:ss</li> * <li>HH:mm:ss</li> */ public static String getTime(String formatStr) { return LocalDateTime.now().format(DateTimeFormatter.ofPattern(formatStr)); } /** * 获取当前日期 * @return yyyy年mm月dd日 */ public static String getNowDate_CN() { return LocalDate.now().format(yyyyMMdd_CN); } /** * 获取当前日期 * @return yyyy年MM月dd日HH时mm分ss秒 */ public static String getNowTime_CN() { return LocalDateTime.now().format(yyyyMMddHHmmss_CN); } /** * 简写本地当前日期:yy-M-dd * 例如:21-5-10为2021年05月10日 * @return yy-M-dd */ public static String getNowLocalTime_shot() { return LocalDateTime.now().format(shotDate); } /** * 根据当地日期显示格式:yyyy年M月dd日 星期几 * @return 例如:2021年5月10日 星期一 */ public static String getNowLocalTime_full() { return LocalDateTime.now().format(fullDate); } /** * 根据当地显示日期格式:yyyy年M月dd日 * @return 例如:2021年5月10日 */ public static String getNowLocalTime_long() { return LocalDateTime.now().format(longDate); } /** * 根据当地显示日期格式:yyyy-M-dd * @return 例如:2021-5-10 */ public static String getNowLocalTime_medium() { return LocalDateTime.now().format(mediumDate); } /** * 获取当前日期的节点时间(年,月,周,日,时,分,秒) * * @param node 日期中的节点元素(年,月,周,日,时,分,秒) * @return 节点数字,如创建此方法的时间:年 2019,月 3,日 30,周 6 */ public static Integer getNodeTime(String node) { System.out.println(); LocalDateTime today = LocalDateTime.now(); int resultNode; switch (node) { case YEAR: resultNode = today.getYear(); break; case MONTH: resultNode = today.getMonthValue(); break; case WEEK: resultNode = transformWeekEN2Num(String.valueOf(today.getDayOfWeek())); break; case DAY: resultNode = today.getDayOfMonth(); break; case HOUR: resultNode = today.getHour(); break; case MINUTE: resultNode = today.getMinute(); break; case SECOND: resultNode = today.getSecond(); break; default: // 当前日期是当前年的第几天。例如:2019/1/3是2019年的第三天 resultNode = today.getDayOfYear(); break; } return resultNode; } /** * 将英文星期转换成数字 * * @param enWeek 英文星期 * @return int,如果数字小于0,则检查,看是否输入错误 or 入参为null */ public static int transformWeekEN2Num(String enWeek) { if (MONDAY.equals(enWeek)) { return 1; } else if (TUESDAY.equals(enWeek)) { return 2; } else if (WEDNESDAY.equals(enWeek)) { return 3; } else if (THURSDAY.equals(enWeek)) { return 4; } else if (FRIDAY.equals(enWeek)) { return 5; } else if (SATURDAY.equals(enWeek)) { return 6; } else if (SUNDAY.equals(enWeek)) { return 7; } else { return -1; } } /** * 获取当前日期之后(之后)的节点事件<br> * <ul> * 比如当前时间为:2019-03-30 10:20:30 * </ul> * <li>node="hour",num=5L:2019-03-30 15:20:30</li> * <li>node="day",num=1L:2019-03-31 10:20:30</li> * <li>node="year",num=1L:2020-03-30 10:20:30</li> * * @param node 节点元素(“year”,"month","week","day","huor","minute","second") * @param num 第几天(+:之后,-:之前) * @return 之后或之后的日期 */ public static String getAfterOrPreNowTime(String node, Long num) { LocalDateTime now = LocalDateTime.now(); if (HOUR.equals(node)) { return now.plusHours(num).format(yyyyMMddHHmmss_EN); } else if (DAY.equals(node)) { return now.plusDays(num).format(yyyyMMddHHmmss_EN); } else if (WEEK.equals(node)) { return now.plusWeeks(num).format(yyyyMMddHHmmss_EN); } else if (MONTH.equals(node)) { return now.plusMonths(num).format(yyyyMMddHHmmss_EN); } else if (YEAR.equals(node)) { return now.plusYears(num).format(yyyyMMddHHmmss_EN); } else if (MINUTE.equals(node)) { return now.plusMinutes(num).format(yyyyMMddHHmmss_EN); } else if (SECOND.equals(node)) { return now.plusSeconds(num).format(yyyyMMddHHmmss_EN); } else { return "Node is Error!"; } } /** * 获取与当前日期相距num个之后(之前)的日期<br> * <ul> * 比如当前时间为:2019-03-30 10:20:30的格式日期 * <li>node="hour",num=5L:2019-03-30 15:20:30</li> * <li>node="day",num=1L:2019-03-31 10:20:30</li> * <li>node="year",num=1L:2020-03-30 10:20:30</li> * </ul> * * @param dtf 格式化当前时间格式(dtf = yyyyMMddHHmmss_EN) * @param node 节点元素(“year”,"month","week","day","huor","minute","second") * @param num (+:之后,-:之前) * @return 之后之前的日期 */ public static String getAfterOrPreNowTimePlus(DateTimeFormatter dtf, String node, Long num) { LocalDateTime now = LocalDateTime.now(); if (HOUR.equals(node)) { return now.plusHours(num).format(dtf); } else if (DAY.equals(node)) { return now.plusDays(num).format(dtf); } else if (WEEK.equals(node)) { return now.plusWeeks(num).format(dtf); } else if (MONTH.equals(node)) { return now.plusMonths(num).format(dtf); } else if (YEAR.equals(node)) { return now.plusYears(num).format(dtf); } else if (MINUTE.equals(node)) { return now.plusMinutes(num).format(dtf); } else if (SECOND.equals(node)) { return now.plusSeconds(num).format(dtf); } else { return "Node is Error!"; } } /** * 当前时间的hour,minute,second之后(之前)的时刻 * * @param node 时间节点元素(hour,minute,second) * @param num 之后(之后)多久时,分,秒(+:之后,-:之前) * @return HH:mm:ss 字符串 */ public static String getAfterOrPreNowTimeSimp(String node, Long num) { LocalTime now = LocalTime.now(); if (HOUR.equals(node)) { return now.plusHours(num).format(HHmmss_EN); } else if (MINUTE.equals(node)) { return now.plusMinutes(num).format(HHmmss_EN); } else if (SECOND.equals(node)) { return now.plusSeconds(num).format(HHmmss_EN); } else { return "Node is Error!"; } } /** * 检查重复事件,比如生日 * * @param dayOfMonth month */ public static boolean isBirthday(int month, int dayOfMonth) { MonthDay birthDay = MonthDay.of(month, dayOfMonth); MonthDay curMonthDay = MonthDay.from(LocalDate.now());// MonthDay只存储了月、日。 return birthDay.equals(curMonthDay); } /** * 获取当前日期第index日之后(之前)的日期(yyyy-MM-dd) * * @param index 第index天 * @return 日期字符串:yyyy-MM-dd */ public static String getAfterOrPreDayDate(int index) { return LocalDate.now().plus(index, ChronoUnit.DAYS).format(yyyyMMdd_EN); } /** * 获取当前日期第index周之前(之后)的日期(yyyy-MM-dd) * @param index 第index周(+:之后,-:之前) * @return 日期字符串:yyyy-MM-dd */ public static String getAfterOrPreWeekDate(int index) { return LocalDate.now().plus(index, ChronoUnit.WEEKS).format(yyyyMMdd_EN); } /** * 获取当前日期第index月之前(之后)的日期(yyyy-MM-dd) * * @param index 第index月(+:之后,-:之前) * @return 日期字符串:yyyy-MM-dd */ public static String getAfterOrPreMonthDate(int index) { return LocalDate.now().plus(index, ChronoUnit.MONTHS).format(yyyyMMdd_EN); } /** * 获取当前日期第index年之前(之后)的日期(yyyy-MM-dd) * * @param index 第index年(+:之后,-:之前) * @return 日期字符串:yyyy-MM-dd */ public static String getAfterOrPreYearDate(int index) { return LocalDate.now().plus(index, ChronoUnit.YEARS).format(yyyyMMdd_EN); } /** * 获取指定日期之前之后的第index的日,周,月,年的日期 * * @param date 指定日期格式:yyyy-MM-dd * @param node 时间节点元素(日周月年) * @param index 之前之后第index个日期 * @return yyyy-MM-dd 日期字符串 */ public static String getAfterOrPreDate(String date, String node, int index) { date = date.trim(); if (DAY.equals(node)) { return LocalDate.parse(date).plus(index, ChronoUnit.DAYS).format(yyyyMMdd_EN); } else if (WEEK.equals(node)) { return LocalDate.parse(date).plus(index, ChronoUnit.WEEKS).format(yyyyMMdd_EN); } else if (MONTH.equals(node)) { return LocalDate.parse(date).plus(index, ChronoUnit.MONTHS).format(yyyyMMdd_EN); } else if (YEAR.equals(node)) { return LocalDate.parse(date).plus(index, ChronoUnit.YEARS).format(yyyyMMdd_EN); } else { return "Wrong date format!"; } } /** * 检测:输入年份是否是闰年? * * @param date 日期格式:yyyy-MM-dd * @return true:闰年,false:平年 */ public static boolean isLeapYear(String date) { return LocalDate.parse(date.trim()).isLeapYear(); } /** * 计算两个日期字符串之间相差多少个周期(天,月,年) * * @param date1 yyyy-MM-dd * @param date2 yyyy-MM-dd * @param node 三者之一:(day,month,year) * @return 相差多少周期 */ public static int peridCount(String date1, String date2, String node) { date1 = date1.trim(); date2 = date2.trim(); if (DAY.equals(node)) { return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getDays(); } else if (MONTH.equals(node)) { return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getMonths(); } else if (YEAR.equals(node)) { return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getYears(); } else { return 0; } } /** * 切割日期。按照周期切割成小段日期段。例如: <br> * * @param startDate 开始日期(yyyy-MM-dd) * @param endDate 结束日期(yyyy-MM-dd) * @param period 周期(天,周,月,年) * @return 切割之后的日期集合 * <li>startDate="2019-02-28",endDate="2019-03-05",period="day"</li> * <li>结果为:[2019-02-28, 2019-03-01, 2019-03-02, 2019-03-03, 2019-03-04, 2019-03-05]</li><br> * <li>startDate="2019-02-28",endDate="2019-03-25",period="week"</li> * <li>结果为:[2019-02-28,2019-03-06, 2019-03-07,2019-03-13, 2019-03-14,2019-03-20, * 2019-03-21,2019-03-25]</li><br> * <li>startDate="2019-02-28",endDate="2019-05-25",period="month"</li> * <li>结果为:[2019-02-28,2019-02-28, 2019-03-01,2019-03-31, 2019-04-01,2019-04-30, * 2019-05-01,2019-05-25]</li><br> * <li>startDate="2019-02-28",endDate="2020-05-25",period="year"</li> * <li>结果为:[2019-02-28,2019-12-31, 2020-01-01,2020-05-25]</li><br> */ public static List<String> getPieDateRange(String startDate, String endDate, String period) { List<String> result = Lists.newArrayList(); LocalDate end = LocalDate.parse(endDate, yyyyMMdd_EN); LocalDate start = LocalDate.parse(startDate, yyyyMMdd_EN); LocalDate tmp = start; switch (period) { case DAY: while (start.isBefore(end) || start.isEqual(end)) { result.add(start.toString()); start = start.plusDays(1); } break; case WEEK: while (tmp.isBefore(end) || tmp.isEqual(end)) { if (tmp.plusDays(6).isAfter(end)) { result.add(tmp + "," + end); } else { result.add(tmp + "," + tmp.plusDays(6)); } tmp = tmp.plusDays(7); } break; case MONTH: while (tmp.isBefore(end) || tmp.isEqual(end)) { LocalDate lastDayOfMonth = tmp.with(TemporalAdjusters.lastDayOfMonth()); if (lastDayOfMonth.isAfter(end)) { result.add(tmp + "," + end); } else { result.add(tmp + "," + lastDayOfMonth); } tmp = lastDayOfMonth.plusDays(1); } break; case YEAR: while (tmp.isBefore(end) || tmp.isEqual(end)) { LocalDate lastDayOfYear = tmp.with(TemporalAdjusters.lastDayOfYear()); if (lastDayOfYear.isAfter(end)) { result.add(tmp + "," + end); } else { result.add(tmp + "," + lastDayOfYear); } tmp = lastDayOfYear.plusDays(1); } break; default: break; } return result; } /** * 指定日期月的最后一天(yyyy-MM-dd) * * @param curDate 日期格式(yyyy-MM-dd) * @param firstOrLast true:第一天,false:最后一天 * */ public static String getLastDayOfMonth(String curDate, boolean firstOrLast) { if (firstOrLast) { return LocalDate.parse(curDate, yyyyMMdd_EN).with(TemporalAdjusters.firstDayOfMonth()).toString(); } else { return LocalDate.parse(curDate, yyyyMMdd_EN).with(TemporalAdjusters.lastDayOfMonth()).toString(); } } /** * 指定日期年的最后一天(yyyy-MM-dd) * * @param curDate 指定日期(格式:yyyy-MM-dd) * @param firstOrLast true:第一天,false:最后一天 * @return 例如:日期年的第一天:2021-01-01 日期年的最后一天:2021-12-31 */ public static String getLastDayOfYear(String curDate, boolean firstOrLast) { if (firstOrLast) { return LocalDate.parse(curDate, yyyyMMdd_EN).with(TemporalAdjusters.firstDayOfYear()).toString(); } else { return LocalDate.parse(curDate, yyyyMMdd_EN).with(TemporalAdjusters.lastDayOfYear()).toString(); } } /** * 获取下一个星期的日期 * * @param curDay yyyy-MM-dd * @param dayOfWeek monday:1~sunday:7 * @param isContainCurDay 是否包含当天,true:是,false:不包含 * @return 日期(yyyy-MM-dd) */ public static String getNextWeekDate(String curDay, int dayOfWeek, boolean isContainCurDay) { dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek; if (isContainCurDay) { return LocalDate.parse(curDay).with(TemporalAdjusters.nextOrSame(DayOfWeek.of(dayOfWeek))).toString(); } else { return LocalDate.parse(curDay).with(TemporalAdjusters.next(DayOfWeek.of(dayOfWeek))).toString(); } } /** * 获取上一个星期的日期 * * @param curDay 指定日期(yyyy-MM-dd) * @param dayOfWeek 数字范围(monday:1~sunday:7) * @param isCurDay 是否包含当天,true:是,false:不包含 * @return 日期(yyyy-MM-dd) */ public static String getPreWeekDate(String curDay, int dayOfWeek, boolean isCurDay) { dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek; if (isCurDay) { return LocalDate.parse(curDay).with(TemporalAdjusters.previousOrSame(DayOfWeek.of(dayOfWeek))).toString(); } else { return LocalDate.parse(curDay).with(TemporalAdjusters.previous(DayOfWeek.of(dayOfWeek))).toString(); } } /** * 获取指定日期当月的最后或第一个星期日期 * * @param curDay 指定日期(yyyy-MM-dd) * @param dayOfWeek 周几(1~7) * @param lastOrFirst true:最后一个,false本月第一个 * @return 日期(yyyy-MM-dd) */ public static String getFirstOrLastWeekDate(String curDay, int dayOfWeek, boolean lastOrFirst) { dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek; if (lastOrFirst) { return LocalDate.parse(curDay).with(TemporalAdjusters.lastInMonth(DayOfWeek.of(dayOfWeek))).toString(); } else { return LocalDate.parse(curDay).with(TemporalAdjusters.firstInMonth(DayOfWeek.of(dayOfWeek))).toString(); } } public static void main(String[] args) { System.out.println("==================="); System.out.println("获取当前日期:"+getNowTime_EN_yMdH()); System.out.println("获取当前日期:"+getNowTime_CN_yMdH()); System.out.println("获取当前日期:"+getNowTime_EN_yMdHm()); System.out.println("获取当前日期:"+getNowTime_CN_yMdHm()); System.out.println("获取当前日期:"+getNowTime_CN_HHmmss()); System.out.println("获取当前日期:"+getTime("HH:mm:ss")); System.out.println("获取当前日期:"+getNowLocalTime_shot()); System.out.println("获取当前日期:"+getNowLocalTime_full()); System.out.println("获取当前日期:"+getNowLocalTime_long()); System.out.println("获取当前日期:"+getNowLocalTime_medium()); System.out.println("获取当前日期:"+getNowTime_CN()); System.out.println("获取当前日期:"+getNowTime_EN()); System.out.println("获取当前日期:"+getNowDate_CN()); System.out.println("==================="); String curDate = getNowDate_EN(); // 指定日期 System.out.println("日期:"+getNowDate_EN()); System.out.println("日期月的第一天:"+getLastDayOfMonth(curDate, true)); System.out.println("日期月的最后一天:"+getLastDayOfMonth(curDate, false)); System.out.println("日期年的第一天:"+getLastDayOfYear(curDate, true)); System.out.println("日期年的最后一天:"+getLastDayOfYear(curDate, false)); System.out.println("==================="); String startDate = "2021-02-28", endDate = "2021-03-05"; System.out.println(startDate+"和"+endDate+"按日切割:"+getPieDateRange(startDate, endDate, DAY)); System.out.println("==================="); System.out.println("获取2021-05-10的下一个星期:"+getNextWeekDate("2021-05-10", 1, false)); System.out.println("2021-01-12和2021-02-15按周切割:"+getPieDateRange("2021-01-12", "2021-02-15", WEEK)); System.out.println("==================="); System.out.println("获取2021-04-02的第一个星期的周一:"+getFirstOrLastWeekDate("2021-04-02", 0, false)); System.out.println("获取2021-04-02的上一个星期的周二(不包含当天):"+getPreWeekDate("2021-04-02", 2, false)); System.out.println("获取2021-04-02的下一个星期的周二:"+getNextWeekDate("2021-04-02", 2, false)); System.out.println("==================="); System.out.println("当前时间戳:" + Instant.now()); System.out.println("当前时间:" + LocalDateTime.now()); System.out.println("==================="); System.out.println("计算2021-01-30和2021-03-31相差几个月:"+peridCount("2021-01-30", "2021-03-31", MONTH)); System.out.println("2020-03-31是否为闰年:"+isLeapYear("2020-03-31")); System.out.println("当今是否为闰年:"+LocalDate.now().isLeapYear()); System.out.println("==================="); System.out.println("获取2021-03-10前一周:"+getAfterOrPreDate("2021-03-10", WEEK, -1)); System.out.println("获取当前日期五天前:"+getAfterOrPreDayDate(-5)); System.out.println("获取当前日期三天前:"+getAfterOrPreDayDate(-3)); System.out.println("获取当前日期六天后:"+getAfterOrPreDayDate(6)); System.out.println("获取当前日期后第6年:"+getAfterOrPreYearDate(6)); System.out.println("获取当前日期后第1周:"+getAfterOrPreWeekDate(1)); System.out.println("==================="); System.out.println("7月13日(生日)是否是今天:"+isBirthday(7, 13)); System.out.println("==================="); LocalDate date0 = LocalDate.of(2021, Month.OCTOBER, 31); LocalDate date = LocalDate.of(2021, 3, 31); System.out.println("当前日期等不等于2021年09月31日:"+date0.equals(LocalDate.now())); System.out.println("年-月-日:"+date.getYear() + "-" + date.getMonthValue() + "-" + date.getDayOfMonth()); System.out.println("获取当前日期节点年份:"+getNodeTime("year")); System.out.println(transformWeekEN2Num(null)); System.out.println("==================="); } }
14、返回结果类
package com.ai.oss.utils; import lombok.Data; @Data public class OperateResult { private boolean success = true; private Object data; private String message; private String code = "0"; public OperateResult(boolean success, String msg, Object data, String code) { this.success = success; this.message = msg; this.data = data; this.code = code; } public OperateResult(boolean success, String msg, Object data) { this(success, msg, data, "0"); } public OperateResult(boolean success, String msg) { this(success, msg, null, "0"); } public static OperateResult success(Object data) { OperateResult operateResult = new OperateResult(true, "", data); return operateResult; } public static OperateResult success() { OperateResult operateResult = new OperateResult(true, ""); return operateResult; } public static OperateResult failure(String msg) { OperateResult operateResult = new OperateResult(true, msg); return operateResult; } }
15、返回结果枚举
package com.ai.oss.utils; public enum ResultCode { /* 成功状态码 */ SUCCESS(0,"操作成功!"), /* 错误状态码 */ FAIL(-1,"操作失败!"), /* 参数错误:10001-19999 */ PARAM_IS_INVALID(10001, "参数无效"), PARAM_IS_BLANK(10002, "参数为空"), PARAM_TYPE_BIND_ERROR(10003, "参数格式错误"), PARAM_NOT_COMPLETE(10004, "参数缺失"), /* 用户错误:20001-29999*/ USER_NOT_LOGGED_IN(20001, "用户未登录,请先登录"), USER_LOGIN_ERROR(20002, "账号不存在或密码错误"), USER_ACCOUNT_FORBIDDEN(20003, "账号已被禁用"), USER_NOT_EXIST(20004, "用户不存在"), USER_HAS_EXISTED(20005, "用户已存在"), /* 业务错误:30001-39999 */ BUSINESS_GROUP_NO_ALLOWED_DEL(30001, "应用分组已经被应用使用,不能删除"), BUSINESS_THEME_NO_ALLOWED_DEL(30002, "主题已经被用户使用,不能删除"), BUSINESS_THEME_NO_ALLOWED_DISABLE(30003, "主题已经被用户使用,不能停用"), BUSINESS_THEME_DEFAULT_NO_ALLOWED_DEL(30004, "默认主题,不能删除"), BUSINESS_THEME_NO_ALLOWED_UPDATE(30005, "主题已经被用户使用,不能修改图片信息"), BUSINESS_IS_TOP(30040, "已经到最顶部"), BUSINESS_IS_BOTTOM(30041, "已经到最底部"), BUSINESS_NAME_EXISTED(30051, "名称已存在"), /* 系统错误:40001-49999 */ SYSTEM_INNER_ERROR(40001, "系统繁忙,请稍后重试"), UPLOAD_ERROR(40002, "系统异常,上传文件失败"), FILE_MAX_SIZE_OVERFLOW(40003, "上传尺寸过大"), FILE_ACCEPT_NOT_SUPPORT(40004, "上传文件格式不支持"), SET_UP_AT_LEAST_ONE_ADMIN(40005, "至少指定一个管理员"), URL_INVALID(40006, "地址不合法"), LINK_AND_LOGOUT_NO_MATCH(40006, "主页地址和注销地址IP不一致"), IP_AND_PORT_EXISTED(40007, "当前IP和端口已经被占中"), LINK_IS_REQUIRED(40008, "生成第三方token认证信息: 主页地址不能为空,请完善信息"), ONLY_ROOT_DEPARTMENT(40009, "组织机构只能存在一个根机构"), DEPART_CODE_EXISTED(40010, "组织机构编码已存在"), DEPART_CONTAINS_USERS(40011, "该机构下是存在用户,不允许删除"), DEPART_CONTAINS_SON(40012, "该机构下是存在子级机构,不允许删除"), DEPART_PARENT_IS_SELF(40013, "选择的父机构不能为本身"), DICT_EXIST_DEPEND(40014, "该字典数据存在详情依赖,不允许删除"), DICT_DETAIL_LOCK(40015, "该字典数据被锁定,不允许修改或删除"), DEPART_CODE_EXISTED_WITH_ARGS(40016, "组织机构编码【{0}】系统已存在"), /* 数据错误:50001-599999 */ RESULT_DATA_NONE(50001, "数据未找到"), DATA_IS_WRONG(50002, "数据有误"), DATA_ALREADY_EXISTED(50003, "数据已存在"), /* 接口错误:60001-69999 */ INTERFACE_INNER_INVOKE_ERROR(60001, "内部系统接口调用异常"), INTERFACE_OUTTER_INVOKE_ERROR(60002, "外部系统接口调用异常"), INTERFACE_FORBID_VISIT(60003, "该接口禁止访问"), INTERFACE_ADDRESS_INVALID(60004, "接口地址无效"), INTERFACE_REQUEST_TIMEOUT(60005, "接口请求超时"), INTERFACE_EXCEED_LOAD(60006, "接口负载过高"), /* 权限错误:70001-79999 */ PERMISSION_UNAUTHENTICATED(70001,"此操作需要登陆系统!"), PERMISSION_UNAUTHORISE(70002,"权限不足,无权操作!"), PERMISSION_EXPIRE(70003,"登录状态过期!"), PERMISSION_TOKEN_EXPIRED(70004, "token已过期"), PERMISSION_LIMIT(70005, "访问次数受限制"), PERMISSION_TOKEN_INVALID(70006, "无效token"), PERMISSION_SIGNATURE_ERROR(70007, "签名失败"); //操作代码 int code; //提示信息 String message; ResultCode(int code, String message){ this.code = code; this.message = message; } public int code() { return code; } public String message() { return message; } public void setCode(int code) { this.code = code; } public void setMessage(String message) { this.message = message; } }
16、树形工具类
package com.ai.oss.utils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.beanutils.BeanUtils; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @Slf4j public class TreeTableUtil { /** * 把列表转换为树结构 * * @param originalList 原始list数据 * @param idFieldName 作为唯一标示的字段名称 * @param pidFieldName 父节点标识字段名 * @param childrenFieldName 子节点(列表)标识字段名 * @return 树结构列表 */ public static <T> List<T> list2TreeList(List<T> originalList, String idFieldName, String pidFieldName, String childrenFieldName) { LinkedHashMap pm = new LinkedHashMap<>(); originalList.stream().forEach(t -> { try { String id = BeanUtils.getProperty(t, idFieldName); pm.put(id,id); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { log.error(e.getMessage()); } }); // 获取根节点,即找出父节点为空的对象 List<T> rootNodeList = new ArrayList<>(); for (T t : originalList) { String parentId = null; try { parentId = BeanUtils.getProperty(t, pidFieldName); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { log.error(e.getMessage()); } if (StringUtils.isBlank(parentId)) { rootNodeList.add(0, t); }else{ boolean bool = true; if(pm.containsKey(parentId)){ bool = false; } if(bool) { try { BeanUtils.setProperty(t, pidFieldName, ""); }catch (Exception e){ log.error(e.getMessage()); } rootNodeList.add(t); } } } // 将根节点从原始list移除,减少下次处理数据 originalList.removeAll(rootNodeList); // 递归封装树 try { packTree(rootNodeList, originalList, idFieldName, pidFieldName, childrenFieldName); } catch (Exception e) { log.error(e.getMessage()); } return rootNodeList; } /** * 封装树(向下递归) * * @param parentNodeList 要封装为树的父节点对象集合 * @param originalList 原始list数据 * @param keyName 作为唯一标示的字段名称 * @param pidFieldName 父节点标识字段名 * @param childrenFieldName 子节点(列表)标识字段名 */ private static <T> void packTree(List<T> parentNodeList, List<T> originalList, String keyName, String pidFieldName, String childrenFieldName) throws Exception { for (T parentNode : parentNodeList) { // 找到当前父节点的子节点列表 List<T> children = packChildren(parentNode, originalList, keyName, pidFieldName, childrenFieldName); if (children.isEmpty()) { continue; } // 将当前父节点的子节点从原始list移除,减少下次处理数据 originalList.removeAll(children); // 开始下次递归 packTree(children, originalList, keyName, pidFieldName, childrenFieldName); } } /** * 封装子对象 * * @param parentNode 父节点对象 * @param originalList 原始list数据 * @param keyName 作为唯一标示的字段名称 * @param pidFieldName 父节点标识字段名 * @param childrenFieldName 子节点(列表)标识字段名 */ private static <T> List<T> packChildren(T parentNode, List<T> originalList, String keyName, String pidFieldName, String childrenFieldName) throws Exception { // 找到当前父节点下的子节点列表 List<T> childNodeList = new ArrayList<>(); String parentId = BeanUtils.getProperty(parentNode, keyName); for (T t : originalList) { String childNodeParentId = BeanUtils.getProperty(t, pidFieldName); if (parentId.equals(childNodeParentId)) { childNodeList.add(t); } } // 将当前父节点下的子节点列表写入到当前父节点下(给子节点列表字段赋值) if (!childNodeList.isEmpty()) { BeanUtils.setProperty(parentNode,childrenFieldName,childNodeList); } return childNodeList; } }
16、加密工具类
package com.ai.oss.sso.utils; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.MessageDigest; /** * @Author helin * @Date 2021/5/21 11:10 * @Description NULL */ public class EnDes { public static final String KEY_SHA = "SHA"; public static final String KEY_MD5 = "MD5"; /** * MAC算法可选以下多种算法 * * <pre> * HmacMD5 * HmacSHA1 * HmacSHA256 * HmacSHA384 * HmacSHA512 * </pre> */ public static final String KEY_MAC = "HmacMD5"; /** * BASE64解密 * * @param key * @return * @throws Exception */ public static byte[] decryptBASE64(String key) throws Exception { return (new BASE64Decoder()).decodeBuffer(key); } /** * BASE64加密 * * @param key * @return * @throws Exception */ public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); } /** * MD5加密 * * @param data * @return * @throws Exception */ public static byte[] encryptMD5(byte[] data) throws Exception { MessageDigest md5 = MessageDigest.getInstance(KEY_MD5); md5.update(data); return md5.digest(); } /** * SHA加密 * * @param data * @return * @throws Exception */ public static byte[] encryptSHA(byte[] data) throws Exception { MessageDigest sha = MessageDigest.getInstance(KEY_SHA); sha.update(data); return sha.digest(); } /** * 初始化HMAC密钥 * * @return * @throws Exception */ public static String initMacKey() throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC); SecretKey secretKey = keyGenerator.generateKey(); return encryptBASE64(secretKey.getEncoded()); } /** * HMAC加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptHMAC(byte[] data, String key) throws Exception { SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); return mac.doFinal(data); } }
package com.ai.oss.sso.utils; import javax.crypto.Cipher; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * @Author helin * @Date 2021/5/21 11:01 * @Description NULL */ public class RSAUtil extends EnDes{ public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * 用私钥对信息生成数字签名 * * @param data * 加密数据 * @param privateKey * 私钥 * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64编码的私钥 byte[] keyBytes = decryptBASE64(privateKey); // 构造PKCS8EncodedKeySpec对象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私钥匙对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return encryptBASE64(signature.sign()); } /** * 校验数字签名 * * @param data * 加密数据 * @param publicKey * 公钥 * @param sign * 数字签名 * * @return 校验成功返回true 失败返回false * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64编码的公钥 byte[] keyBytes = decryptBASE64(publicKey); // 构造X509EncodedKeySpec对象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公钥匙对象 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(data); // 验证签名是否正常 return signature.verify(decryptBASE64(sign)); } /** * 解密<br> * 用私钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 解密<br> * 用公钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用公钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception { // 对公钥解密 byte[] keyBytes = decryptBASE64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用私钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 取得私钥 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公钥 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化密钥 * * @return * @throws Exception */ public static Map<String, Object> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM); keyPairGen.initialize(2048); KeyPair keyPair = keyPairGen.generateKeyPair(); // 公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } }
package com.ai.oss.sso.utils; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Date; import java.util.HashMap; import java.util.Map; import cn.hutool.core.codec.Base64Encoder; import com.ai.oss.utils.DateHelper; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class RSAUtilTest { private static String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTivFyv/LSQtCkil0Ct7RQaLPX6o1bqY5vlayz7Wyjqwkk9Mk3JDxebPMaU4rHlB5gzwfWSyQsuHs+hUaTw5dABhFdejUmeYdT5PiYEj2owOl+4UOkh/XxJ8lnwPGp/beVuCsTfQ8DCh/siJtkRVOJ8zli+PTkm6nCGYeRenZBabdHg0MwZCPYAaDGdbtM8CWVx1vZCWRtOeBnLJ5oXUXgoSkHjYwR3NJNe4KvVXxhCgKKyxsFQaVcDd0601/xhXgko8Lbxt/m+RrdNrrROU2Sy89qjb0z9N1sYTwgK4KD17j3Cl3iK1TusefRsKdk0fZLRQSh1044fC4Cn/K+SmpQIDAQAB"; private static String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC1OK8XK/8tJC0KSKXQK3tFBos9fqjVupjm+VrLPtbKOrCST0yTckPF5s8xpTiseUHmDPB9ZLJCy4ez6FRpPDl0AGEV16NSZ5h1Pk+JgSPajA6X7hQ6SH9fEnyWfA8an9t5W4KxN9DwMKH+yIm2RFU4nzOWL49OSbqcIZh5F6dkFpt0eDQzBkI9gBoMZ1u0zwJZXHW9kJZG054GcsnmhdReChKQeNjBHc0k17gq9VfGEKAorLGwVBpVwN3TrTX/GFeCSjwtvG3+b5Gt02utE5TZLLz2qNvTP03WxhPCArgoPXuPcKXeIrVO6x59Gwp2TR9ktFBKHXTjh8LgKf8r5KalAgMBAAECggEAXBa06sqBvleux5YJJJKj7nyXzyUI+Kr8vgqid7uz/En8pizD1f1vsSZLzYePGB36PcP/hUjhSQ4SJHsAQgXHkEoNC8NrjBl2oMWMN2y3YnxfghcKkl960j4br4DVUAtBxRaagCHD+/pKp6USTdvFjqNf3IbIhNj0ihiMWaSKfFIhn/dsuLxTZt9oN36XF9Vnv5S7487s8FKC0rHnzYGExcs9nx8LyRXvaHaWJzeOGTIGGP0XOQGfG9wBv8a2ZlgsQPEtsPWlTYYMnpDcW5TvN1275DcO9HfSGhMPbG0avFV9fBb2HWkC2GwiW2Aw//lEnnjjcuFGVccCZWJ90aEXwQKBgQDerOtHNx7i1V0yzgu9SFZZZULbXEQBPbXIi1v2CRSHsOZBfOvJCYUXiBxIrLrUmHjopxqvqY3rxVxVKRclWZdqpAzG4LqkFLYgppxVSPhb57WOkT5lYtOIKfBOLz2dd0mZN02/gJlrBX2gGBqTm8slCL2QTkRh9eVEN/zN4EqaFQKBgQDQV5bKYDvttu/sJg2XYRFTsIEqk4ULi0rXFAA/P8mbBwgSNpNVruWhH5KTDAR2dUHvda1XW+qgA0A7LuA2YatOh8/WN6ZhcgcIbyew5XASsreM1sbAXGXpCT8x8NrNq/4pvov20gQwGgG9N2fxlyze5UXToDahdcq2Nyu+71nOUQKBgAGHam4owLuJ/4PTylzYXE9s1JKxBX6Er/TakB0WXt+3pT0Z4HyW5iUNODR/iyDekyX1z8cZAPJ3fnTPPWtyPAntanELJfzub3m16yjiwWHQK3z5HlaP4Sf0McQ3qtKj+QtmR9Biz6redMheogAVd8WfU73j67BIgfR/9epr+dcpAoGAH7XlLqJdHL5mYCQel3bfw0QvNMLFUk9+MaRKsVXNIrp8QQFrhXQcYVzD23vNxhXs1jysCIrl+DrmcNuepshQ4aAMQ0evHE/VwDPi76rMVxw6kcYy9B5cKI8OvlQxiXJvOf1Voliu6H9c2mbvfDcNTlPJP/+3sPWTyA43q1UU7zECgYB5zlVHwpsUZ9vqiMcsavX87E4zT4v95uNY/9HZrQhQptPHSqlmX6O3RVXXssp3IOZyU9HjdnOZUhMOw9DOXZY9rHFyvjH5re9S0Q5RvuhvvgY/ra/hMUhZR2FlhKA2ckWmmOr5WsXy/N8BT4igZUlXNNchiiLTQ6CIW8ij28DyuQ=="; public static void main(String arg[]) { try{ System.out.println("私钥加密——公钥解密"); String inputStr = "123"; byte[] data = inputStr.getBytes(); byte[] encodedData = RSAUtil.encryptByPrivateKey(data, privateKey); BASE64Encoder base64 =new BASE64Encoder(); String mw = base64.encode(encodedData); System.out.println("密文:"+mw); System.out.println(DateHelper.formatShortDate(new Date())); byte[] decodedData = RSAUtil .decryptByPublicKey((new BASE64Decoder()).decodeBuffer(mw), publicKey); String outputStr = new String(decodedData); System.out.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr); String param = "lU0c4SRO7vnpU_fTcQvA4H9Ad7w3qCX4EuQ86tm9ejri3RLsaUEvDqqGMvWcn6Mfr3OWWlcxrYcaVhJ5a9pMie-AftV8lMnqsnpiT1oKbLZ2cT03VCV943SvdbaaQqwmXdVzJ-2o-m6xUoY5w1FFh-ySvIWF_RUf3T1IeapOxgPQ9twl3_OzM84WCxSp9nXLv3S3_mRPdilk46T3jMlQiWizrEGHLkxgzDsP4rLAe8NVkMYqy53-vxMV71T1H3uDbamUt0q7E-DS_704OuBqMp3TBSUak07Epw9N50muWsfB8FxkJrXU0sOI4g9Q0059Hr-wqQQuUiIyNz45C_gKAA=="; Base64.Decoder decoder = Base64.getUrlDecoder(); byte[] bytes = decoder.decode(param); System.out.println(new String(bytes, StandardCharsets.UTF_8)); }catch (Exception e){ e.printStackTrace(); } } }

浙公网安备 33010602011771号