有用的工具类(Java)

IP地址获取

public class IPUtil {

    private static final String UNKNOWN = "unknown";

    protected IPUtil(){

    }

    /**
     * 获取 IP地址
     * 使用 Nginx等反向代理软件, 则不能通过 request.getRemoteAddr()获取 IP地址
     * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,
     * X-Forwarded-For中第一个非 unknown的有效IP字符串,则为真实IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isNotEmpty(ip)) {
            ip = ip.split(", ")[0];
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

}
View Code

 获取上个月月份字符串

public static final String getLastMonth() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        // 设置为当前时间
        calendar.setTime(date);
        // 设置为上一个月
        calendar.add(Calendar.MONTH,-1);
        date = calendar.getTime();
        return format.format(date);
    }
View Code

日期工具类

/**
 * 日期工具类
 *
 */
@UtilityClass
public class DateUtil {

    public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_DATETIME_MINI = "yyyyMMddHHmmss";
    public static final String PATTERN_DATE = "yyyy-MM-dd";
    public static final String PATTERN_TIME = "HH:mm:ss";
    /**
     * 老 date 格式化
     */
    public static final ConcurrentDateFormat DATETIME_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME);
    public static final ConcurrentDateFormat DATETIME_MINI_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME_MINI);
    public static final ConcurrentDateFormat DATE_FORMAT = ConcurrentDateFormat.of(PATTERN_DATE);
    public static final ConcurrentDateFormat TIME_FORMAT = ConcurrentDateFormat.of(PATTERN_TIME);
    /**
     * java 8 时间格式化
     */
    public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
    public static final DateTimeFormatter DATETIME_MINI_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME_MINI);
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
    public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);

    /**
     * 获取当前日期
     *
     * @return 当前日期
     */
    public static Date now() {
        return new Date();
    }

    /**
     * 添加年
     *
     * @param date       时间
     * @param yearsToAdd 添加的年数
     * @return 设置后的时间
     */
    public static Date plusYears(Date date, int yearsToAdd) {
        return DateUtil.set(date, Calendar.YEAR, yearsToAdd);
    }

    /**
     * 添加月
     *
     * @param date        时间
     * @param monthsToAdd 添加的月数
     * @return 设置后的时间
     */
    public static Date plusMonths(Date date, int monthsToAdd) {
        return DateUtil.set(date, Calendar.MONTH, monthsToAdd);
    }

    /**
     * 添加周
     *
     * @param date       时间
     * @param weeksToAdd 添加的周数
     * @return 设置后的时间
     */
    public static Date plusWeeks(Date date, int weeksToAdd) {
        return DateUtil.plus(date, Period.ofWeeks(weeksToAdd));
    }

    /**
     * 添加天
     *
     * @param date      时间
     * @param daysToAdd 添加的天数
     * @return 设置后的时间
     */
    public static Date plusDays(Date date, long daysToAdd) {
        return DateUtil.plus(date, Duration.ofDays(daysToAdd));
    }

    /**
     * 添加小时
     *
     * @param date       时间
     * @param hoursToAdd 添加的小时数
     * @return 设置后的时间
     */
    public static Date plusHours(Date date, long hoursToAdd) {
        return DateUtil.plus(date, Duration.ofHours(hoursToAdd));
    }

    /**
     * 添加分钟
     *
     * @param date         时间
     * @param minutesToAdd 添加的分钟数
     * @return 设置后的时间
     */
    public static Date plusMinutes(Date date, long minutesToAdd) {
        return DateUtil.plus(date, Duration.ofMinutes(minutesToAdd));
    }

    /**
     * 添加秒
     *
     * @param date         时间
     * @param secondsToAdd 添加的秒数
     * @return 设置后的时间
     */
    public static Date plusSeconds(Date date, long secondsToAdd) {
        return DateUtil.plus(date, Duration.ofSeconds(secondsToAdd));
    }

    /**
     * 添加毫秒
     *
     * @param date        时间
     * @param millisToAdd 添加的毫秒数
     * @return 设置后的时间
     */
    public static Date plusMillis(Date date, long millisToAdd) {
        return DateUtil.plus(date, Duration.ofMillis(millisToAdd));
    }

    /**
     * 添加纳秒
     *
     * @param date       时间
     * @param nanosToAdd 添加的纳秒数
     * @return 设置后的时间
     */
    public static Date plusNanos(Date date, long nanosToAdd) {
        return DateUtil.plus(date, Duration.ofNanos(nanosToAdd));
    }

    /**
     * 日期添加时间量
     *
     * @param date   时间
     * @param amount 时间量
     * @return 设置后的时间
     */
    public static Date plus(Date date, TemporalAmount amount) {
        Instant instant = date.toInstant();
        return Date.from(instant.plus(amount));
    }

    /**
     * 减少年
     *
     * @param date  时间
     * @param years 减少的年数
     * @return 设置后的时间
     */
    public static Date minusYears(Date date, int years) {
        return DateUtil.set(date, Calendar.YEAR, -years);
    }

    /**
     * 减少月
     *
     * @param date   时间
     * @param months 减少的月数
     * @return 设置后的时间
     */
    public static Date minusMonths(Date date, int months) {
        return DateUtil.set(date, Calendar.MONTH, -months);
    }

    /**
     * 减少周
     *
     * @param date  时间
     * @param weeks 减少的周数
     * @return 设置后的时间
     */
    public static Date minusWeeks(Date date, int weeks) {
        return DateUtil.minus(date, Period.ofWeeks(weeks));
    }

    /**
     * 减少天
     *
     * @param date 时间
     * @param days 减少的天数
     * @return 设置后的时间
     */
    public static Date minusDays(Date date, long days) {
        return DateUtil.minus(date, Duration.ofDays(days));
    }

    /**
     * 减少小时
     *
     * @param date  时间
     * @param hours 减少的小时数
     * @return 设置后的时间
     */
    public static Date minusHours(Date date, long hours) {
        return DateUtil.minus(date, Duration.ofHours(hours));
    }

    /**
     * 减少分钟
     *
     * @param date    时间
     * @param minutes 减少的分钟数
     * @return 设置后的时间
     */
    public static Date minusMinutes(Date date, long minutes) {
        return DateUtil.minus(date, Duration.ofMinutes(minutes));
    }

    /**
     * 减少秒
     *
     * @param date    时间
     * @param seconds 减少的秒数
     * @return 设置后的时间
     */
    public static Date minusSeconds(Date date, long seconds) {
        return DateUtil.minus(date, Duration.ofSeconds(seconds));
    }

    /**
     * 减少毫秒
     *
     * @param date   时间
     * @param millis 减少的毫秒数
     * @return 设置后的时间
     */
    public static Date minusMillis(Date date, long millis) {
        return DateUtil.minus(date, Duration.ofMillis(millis));
    }

    /**
     * 减少纳秒
     *
     * @param date  时间
     * @param nanos 减少的纳秒数
     * @return 设置后的时间
     */
    public static Date minusNanos(Date date, long nanos) {
        return DateUtil.minus(date, Duration.ofNanos(nanos));
    }

    /**
     * 日期减少时间量
     *
     * @param date   时间
     * @param amount 时间量
     * @return 设置后的时间
     */
    public static Date minus(Date date, TemporalAmount amount) {
        Instant instant = date.toInstant();
        return Date.from(instant.minus(amount));
    }

    /**
     * 设置日期属性
     *
     * @param date          时间
     * @param calendarField 更改的属性
     * @param amount        更改数,-1表示减少
     * @return 设置后的时间
     */
    private static Date set(Date date, int calendarField, int amount) {
        Assert.notNull(date, "The date must not be null");
        Calendar c = Calendar.getInstance();
        c.setLenient(false);
        c.setTime(date);
        c.add(calendarField, amount);
        return c.getTime();
    }

    /**
     * 日期时间格式化
     *
     * @param date 时间
     * @return 格式化后的时间
     */
    public static String formatDateTime(Date date) {
        return DATETIME_FORMAT.format(date);
    }

    /**
     * 日期时间格式化
     *
     * @param date 时间
     * @return 格式化后的时间
     */
    public static String formatDateTimeMini(Date date) {
        return DATETIME_MINI_FORMAT.format(date);
    }

    /**
     * 日期格式化
     *
     * @param date 时间
     * @return 格式化后的时间
     */
    public static String formatDate(Date date) {
        return DATE_FORMAT.format(date);
    }

    /**
     * 时间格式化
     *
     * @param date 时间
     * @return 格式化后的时间
     */
    public static String formatTime(Date date) {
        return TIME_FORMAT.format(date);
    }

    /**
     * 日期格式化
     *
     * @param date    时间
     * @param pattern 表达式
     * @return 格式化后的时间
     */
    public static String format(Date date, String pattern) {
        return ConcurrentDateFormat.of(pattern).format(date);
    }

    /**
     * java8 日期时间格式化
     *
     * @param temporal 时间
     * @return 格式化后的时间
     */
    public static String formatDateTime(TemporalAccessor temporal) {
        return DATETIME_FORMATTER.format(temporal);
    }

    /**
     * java8 日期时间格式化
     *
     * @param temporal 时间
     * @return 格式化后的时间
     */
    public static String formatDateTimeMini(TemporalAccessor temporal) {
        return DATETIME_MINI_FORMATTER.format(temporal);
    }

    /**
     * java8 日期时间格式化
     *
     * @param temporal 时间
     * @return 格式化后的时间
     */
    public static String formatDate(TemporalAccessor temporal) {
        return DATE_FORMATTER.format(temporal);
    }

    /**
     * java8 时间格式化
     *
     * @param temporal 时间
     * @return 格式化后的时间
     */
    public static String formatTime(TemporalAccessor temporal) {
        return TIME_FORMATTER.format(temporal);
    }

    /**
     * java8 日期格式化
     *
     * @param temporal 时间
     * @param pattern  表达式
     * @return 格式化后的时间
     */
    public static String format(TemporalAccessor temporal, String pattern) {
        return DateTimeFormatter.ofPattern(pattern).format(temporal);
    }

    /**
     * 将字符串转换为时间
     *
     * @param dateStr 时间字符串
     * @param pattern 表达式
     * @return 时间
     */
    public static Date parse(String dateStr, String pattern) {
        ConcurrentDateFormat format = ConcurrentDateFormat.of(pattern);
        try {
            return format.parse(dateStr);
        } catch (ParseException e) {
            throw Exceptions.unchecked(e);
        }
    }

    /**
     * 将字符串转换为时间
     *
     * @param dateStr 时间字符串
     * @param format  ConcurrentDateFormat
     * @return 时间
     */
    public static Date parse(String dateStr, ConcurrentDateFormat format) {
        try {
            return format.parse(dateStr);
        } catch (ParseException e) {
            throw Exceptions.unchecked(e);
        }
    }

    /**
     * 将字符串转换为时间
     *
     * @param dateStr 时间字符串
     * @param pattern 表达式
     * @return 时间
     */
    public static <T> T parse(String dateStr, String pattern, TemporalQuery<T> query) {
        return DateTimeFormatter.ofPattern(pattern).parse(dateStr, query);
    }

    /**
     * 时间转 Instant
     *
     * @param dateTime 时间
     * @return Instant
     */
    public static Instant toInstant(LocalDateTime dateTime) {
        return dateTime.atZone(ZoneId.systemDefault()).toInstant();
    }

    /**
     * Instant 转 时间
     *
     * @param instant Instant
     * @return Instant
     */
    public static LocalDateTime toDateTime(Instant instant) {
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    /**
     * 转换成 date
     *
     * @param dateTime LocalDateTime
     * @return Date
     */
    public static Date toDate(LocalDateTime dateTime) {
        return Date.from(DateUtil.toInstant(dateTime));
    }

    /**
     * 转换成 date
     *
     * @param localDate LocalDate
     * @return Date
     */
    public static Date toDate(final LocalDate localDate) {
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * Converts local date time to Calendar.
     */
    public static Calendar toCalendar(final LocalDateTime localDateTime) {
        return GregorianCalendar.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
    }

    /**
     * localDateTime 转换成毫秒数
     *
     * @param localDateTime LocalDateTime
     * @return long
     */
    public static long toMilliseconds(final LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * localDate 转换成毫秒数
     *
     * @param localDate LocalDate
     * @return long
     */
    public static long toMilliseconds(LocalDate localDate) {
        return toMilliseconds(localDate.atStartOfDay());
    }

    /**
     * 转换成java8 时间
     *
     * @param calendar 日历
     * @return LocalDateTime
     */
    public static LocalDateTime fromCalendar(final Calendar calendar) {
        TimeZone tz = calendar.getTimeZone();
        ZoneId zid = tz == null ? ZoneId.systemDefault() : tz.toZoneId();
        return LocalDateTime.ofInstant(calendar.toInstant(), zid);
    }

    /**
     * 转换成java8 时间
     *
     * @param instant Instant
     * @return LocalDateTime
     */
    public static LocalDateTime fromInstant(final Instant instant) {
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    /**
     * 转换成java8 时间
     *
     * @param date Date
     * @return LocalDateTime
     */
    public static LocalDateTime fromDate(final Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * 转换成java8 时间
     *
     * @param milliseconds 毫秒数
     * @return LocalDateTime
     */
    public static LocalDateTime fromMilliseconds(final long milliseconds) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneId.systemDefault());
    }

    /**
     * 比较2个时间差,跨度比较小
     *
     * @param startInclusive 开始时间
     * @param endExclusive   结束时间
     * @return 时间间隔
     */
    public static Duration between(Temporal startInclusive, Temporal endExclusive) {
        return Duration.between(startInclusive, endExclusive);
    }

    /**
     * 比较2个时间差,跨度比较大,年月日为单位
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 时间间隔
     */
    public static Period between(LocalDate startDate, LocalDate endDate) {
        return Period.between(startDate, endDate);
    }

    /**
     * 比较2个 时间差
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 时间间隔
     */
    public static Duration between(Date startDate, Date endDate) {
        return Duration.between(startDate.toInstant(), endDate.toInstant());
    }


    /**
     * 获取今天的日期
     *
     * @return 时间
     */
    public static String today() {
        return format(new Date(), "yyyyMMdd");
    }

    /**
     * 获取今天的时间
     *
     * @return 时间
     */
    public static String time() {
        return format(new Date(), PATTERN_DATETIME_MINI);
    }

    /**
     * 获取指定年月的第一天
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最小天数
        int firstDay = cal.getMinimum(Calendar.DATE);
        //设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH,firstDay);
        //格式化日期
        return DATE_FORMAT.format(cal.getTime());
    }

    /**
     * 获取指定年月的最后一天
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        return DATE_FORMAT.format(cal.getTime());
    }


    /**
     * 获取指定年月的下个月第一天
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfNextMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month);
        //获取某月最小天数
        int firstDay = cal.getMinimum(Calendar.DATE);
        //设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH,firstDay);
        //格式化日期
        return DATE_FORMAT.format(cal.getTime());
    }
}
View Code

BigDecimal运算工具类

import java.math.BigDecimal;

/**
 * 用于高精确处理常用的数学运算
 */
public class ArithmeticUtils {
    //默认除法运算精度
    private static final int DEF_DIV_SCALE = 10;

    /**
     * 提供精确的加法运算
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */

    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static BigDecimal add(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2);
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1    被加数
     * @param v2    加数
     * @param scale 保留scale 位小数
     * @return 两个参数的和
     */
    public static String add(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static BigDecimal sub(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2);
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1    被减数
     * @param v2    减数
     * @param scale 保留scale 位小数
     * @return 两个参数的差
     */
    public static String sub(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static BigDecimal mul(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2);
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1    被乘数
     * @param v2    乘数
     * @param scale 保留scale 位小数
     * @return 两个参数的积
     */
    public static double mul(double v1, double v2, int scale) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return round(b1.multiply(b2).doubleValue(), scale);
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1    被乘数
     * @param v2    乘数
     * @param scale 保留scale 位小数
     * @return 两个参数的积
     */
    public static String mul(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
     * 小数点以后10位,以后的数字四舍五入
     *
     * @param v1 被除数
     * @param v2 除数
     * @return 两个参数的商
     */

    public static double div(double v1, double v2) {
        return div(v1, v2, DEF_DIV_SCALE);
    }

    /**
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
     * 定精度,以后的数字四舍五入
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
     * 定精度,以后的数字四舍五入
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示需要精确到小数点以后几位
     * @return 两个参数的商
     */
    public static String div(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v1);
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 提供精确的小数位四舍五入处理
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static String round(String v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(v);
        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 取余数
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 小数点后保留几位
     * @return 余数
     */
    public static String remainder(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 取余数  BigDecimal
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 小数点后保留几位
     * @return 余数
     */
    public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 比较大小
     *
     * @param v1 被比较数
     * @param v2 比较数
     * @return 如果v1 大于v2 则 返回true 否则false
     */
    public static boolean compare(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        int bj = b1.compareTo(b2);
        boolean res;
        if (bj > 0)
            res = true;
        else
            res = false;
        return res;
    }
}
View Code
/**
 * @Description: Double类型运算工具类
 */
public class DoubleUtil {

    /**
     * 提供精确的加法运算。
     *
     * @param v1
     *            被加数
     * @param v2
     *            加数
     * @return 两个参数的和
     */

    public static double add(double v1, double v2)
    {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1
     *            被减数
     * @param v2
     *            减数
     * @return 两个参数的差
     */

    public static double sub(double v1, double v2)
    {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 相除
     */

    /**
     * double 除法
     *
     * @param d1
     * @param d2
     * @param scale
     *            四舍五入 小数点位数
     * @return
     */
    public static double div(double d1, double d2, int scale) {
        // 当然在此之前,你要判断分母是否为0,
        // 为0你可以根据实际需求做相应的处理

        BigDecimal bd1 = new BigDecimal(Double.toString(d1));
        BigDecimal bd2 = new BigDecimal(Double.toString(d2));

        try
        {
            return bd1.divide(bd2, scale, BigDecimal.ROUND_DOWN).doubleValue();
        } catch (Exception e)
        {
            e.printStackTrace();
            return 0;
        }

    }


    /**
     *   提供精确的乘法运算。
     *   @param   v1   被乘数
     *   @param   v2   乘数
     *   @return   两个参数的积
     */

    public static double mul(double v1,double v2){
        BigDecimal  b1  = new BigDecimal(Double.toString(v1));
        BigDecimal  b2  = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 比较两个double值的大小
     * @param v1 值1
     * @param v2 值2
     * @return 比较结果 -1:v1<v2; 0:v1; 1:v1>v2;
     */
    public static Integer compare(double v1, double v2) {
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);

        return  b1.compareTo(b2);
    }
    /**
     * 按规则加减
     *
     * @param v1
     *            被加数
     * @param v2
     *            加数
     * @param scale
     *            保留小数位
     * @param roundUp
     *            保留规则:
     *            BigDecimal.ROUND_HALF_DOWN也是五舍六入,
     *            BigDecimal.ROUND_UP表示进位处理(就是直接加1),
     *            BigDecimal.ROUND_DOWN表示直接去掉尾数
     * @return 两个参数的和
     */

    public static Double addFormant(double v1, double v2, int scale, int roundUp) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).setScale(scale, roundUp).doubleValue();
    }
}
View Code
import java.math.BigDecimal;

/**
 */
public class MathUtil {
  /**
   * 乘法
   * @param objects
   * @return
   */
  public static BigDecimal multiply(Object...objects ){
    BigDecimal sum = new BigDecimal("1");
    for (Object objectValue : objects) {
      if(objectValue ==null){
        objectValue = 0;
      }
      if(objectValue instanceof BigDecimal){
        sum = sum.multiply((BigDecimal) objectValue);
      }else{
        sum = sum.multiply(new BigDecimal(objectValue.toString()));
      }
    }
    return sum;
  }

  /**
   * 加法
   * @param objects
   * @return
   */
  public static BigDecimal add(Object...objects ){
    BigDecimal sum = new BigDecimal("0");
    for (Object objectValue : objects) {
      if(objectValue ==null){
        objectValue = 0;
      }
      if(objectValue instanceof BigDecimal){
        sum = sum.add((BigDecimal) objectValue);
      }else{
        sum = sum.add(new BigDecimal(objectValue.toString()));
      }
    }
    return sum;
  }

  /**
   * 减法
   * @param objects
   * @return
   */
  public static BigDecimal subtract(Object...objects ){
    BigDecimal sum = null;
    for (int i = 0; i < objects.length; i++) {
      Object objectValue = objects[i];
      if(objectValue ==null){
        objectValue= 0;
      }
      if(i==0){
        if(objectValue instanceof BigDecimal){
            sum = (BigDecimal) objectValue;
          }else{
            sum = new BigDecimal(objectValue.toString());
          }
      }else{
        if(objectValue instanceof BigDecimal){
            sum = sum.subtract((BigDecimal) objectValue);
          }else{
            sum = sum.subtract(new BigDecimal(objectValue.toString()));
          }
      }
    }
    return sum;
  }

  /**
   * 除法
   * @param objects
   * @return
   */
  public static BigDecimal divide(Object...objects ){
    BigDecimal sum = null;
    if(objects.length>1){
      for (int i = 0; i < objects.length; i++) {
        Object objectValue = objects[i];
        if(i==0){
          if(objectValue ==null){
              return null;
          }
          if(objectValue instanceof BigDecimal){
            sum = (BigDecimal) objectValue;
          }else{
            sum = new BigDecimal(objectValue.toString());
          }
        }else{
          if(objectValue ==null){
            return null;
          }
          if(objectValue instanceof BigDecimal){
            sum = sum.divide((BigDecimal) objectValue);
          }else{
            sum = sum.divide(new BigDecimal(objectValue.toString()));
          }
        }
      }
      return sum;
    }else{
      return null;
    }
  }
}
View Code

异常处理工具类

/**
 * 异常处理工具类
 *
 */
@UtilityClass
public class Exceptions {

    /**
     * 将CheckedException转换为UncheckedException.
     *
     * @param e Throwable
     * @return {RuntimeException}
     */
    public static RuntimeException unchecked(Throwable e) {
        if (e instanceof Error) {
            throw (Error) e;
        } else if (e instanceof IllegalAccessException ||
            e instanceof IllegalArgumentException ||
            e instanceof NoSuchMethodException) {
            return new IllegalArgumentException(e);
        } else if (e instanceof InvocationTargetException) {
            return new RuntimeException(((InvocationTargetException) e).getTargetException());
        } else if (e instanceof RuntimeException) {
            return (RuntimeException) e;
        } else if (e instanceof InterruptedException) {
            Thread.currentThread().interrupt();
        }
        return Exceptions.runtime(e);
    }

    /**
     * 不采用 RuntimeException 包装,直接抛出,使异常更加精准
     *
     * @param throwable Throwable
     * @param <T>       泛型标记
     * @return Throwable
     * @throws T 泛型
     */
    @SuppressWarnings("unchecked")
    private static <T extends Throwable> T runtime(Throwable throwable) throws T {
        throw (T) throwable;
    }

    /**
     * 代理异常解包
     *
     * @param wrapped 包装过得异常
     * @return 解包后的异常
     */
    public static Throwable unwrap(Throwable wrapped) {
        Throwable unwrapped = wrapped;
        while (true) {
            if (unwrapped instanceof InvocationTargetException) {
                unwrapped = ((InvocationTargetException) unwrapped).getTargetException();
            } else if (unwrapped instanceof UndeclaredThrowableException) {
                unwrapped = ((UndeclaredThrowableException) unwrapped).getUndeclaredThrowable();
            } else {
                return unwrapped;
            }
        }
    }
}
View Code

Http请求工具类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * Http请求工具类
 *
 * @author yl
 */
@Slf4j
public class HttpUtil {

    private static final String AUTHORIZATION = "Authorization";

    /**
     * GET请求
     *
     * @param url 请求url
     * @param token 请求token
     * @return
     */
    public static String get(String url, String token) {

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(AUTHORIZATION, token);

        MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
        HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(requestBody, httpHeaders);
        RestTemplate restTemplate = new RestTemplate();
        if (log.isInfoEnabled()) {
            log.info("[http-get] requestUrl: {}", url);
        }
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
        String result = response.getBody();
        if (log.isInfoEnabled()) {
            log.info("[http-get] response: {}", result);
        }
        return result;
    }

    /**
     * application/json方式提交数据 自定义请求头
     *
     * @param url
     * @param object
     * @param headerMap
     * @return
     */
    public static String postWithHeader(String url, Object object, Map<String, String> headerMap) {
        String body = "";
        try {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
            httpHeaders.add(HttpHeaders.AUTHORIZATION, headerMap.get(HttpHeaders.AUTHORIZATION));
            log.info("地址 : " + url + "\n" + "参数 : " + JSON.toJSONString(object) + "\n" + "请求头 : " + httpHeaders.toString());
            //设置参数
            HttpEntity<Object> requestEntity = new HttpEntity<>(object, httpHeaders);
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
            body = responseEntity.getBody();
        } catch (RestClientException e) {
            e.printStackTrace();
            log.error("Rest调用异常!!!地址 : " + url + "\n" + "参数 : " + JSON.toJSONString(object) + "\n" + "请求头 : " + headerMap.toString(), e);
        }
        return body;
    }


    /**
     * post请求带请求体
     * @param url
     * @param requestBody
     * @return
     */
    public static JSONObject postJson(String url, Object requestBody) {
        RestTemplate restTemplate = new RestTemplate();
        log.info("[http] requestUrl: " + url);
        if (requestBody != null) {
            log.info("[http] requestBody:" + JSON.toJSONString(requestBody));
        }
        JSONObject response = restTemplate.postForObject(url, requestBody, JSONObject.class);
        log.info("[http] response:" + response.toJSONString());
        return response;
    }
}
View Code

Jackson工具类

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;


@Slf4j
public class JacksonUtil {

    private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    /**
     * 获取实体
     * @return ObjectMapper
     */
    private static ObjectMapper getInstance() {
        return OBJECT_MAPPER;
    }

    /**
     * bean、array、List、Map --> json
     *
     * @param obj obj
     * @return json
     */
    public static String writeValueAsString(Object obj) {
        try {
            return getInstance().writeValueAsString(obj);
        } catch (JsonGenerationException e) {
            log.error(e.getMessage(), e);
        } catch (JsonMappingException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * string --> bean、Map、List(array)
     *
     * @param jsonStr jsonStr
     * @param clazz 类型
     * @return obj 对象
     */
    public static <T> T readValue(String jsonStr, Class<T> clazz) {
        try {
            return getInstance().readValue(jsonStr, clazz);
        } catch (JsonParseException e) {
            log.error(e.getMessage(), e);
        } catch (JsonMappingException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
}
View Code

日志格式生成类

import com.alibaba.druid.util.StringUtils;
import com.oristand.common.model.LogType;

/**
 * 生成[标题][大类][小类][过滤1]..格式log
 */
public class LogCreate {

    /**
     *
     * @param logTitle log标题
     * @param logType1 log大类型
     * @param logType2 log小类型
     * @param filters 过滤字段,用于查询日志
     * @return
     */
    public static String create(String logTitle, LogType logType1, LogType logType2, String... filters) {
        StringBuilder sb = new StringBuilder();
        sb.append("[").append(StringUtils.isEmpty(logTitle) ? "" : logTitle).append("]");
        sb.append("[").append(null == logType1 ? "" : logType1.getDesc()).append("]");
        sb.append("[").append(null == logType2 ? "" : logType2.getDesc()).append("]");
        for (String filter : filters) {
            sb.append("[").append(StringUtils.isEmpty(filter) ? "" : filter).append("]");
        }
        return sb.toString();
    }

}
View Code

Redis工具类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
 * Redis工具类
 */
@Component
public final class RedisUtil {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    // =============================common============================
    /***
     * 读取所有以某字符开头的key
     * @param key key前缀
     * @return java.util.Set<java.lang.String>
     */
    public Set<String> vagueFindKey(String key) {
        return redisTemplate.keys(key + StringPool.ASTERISK);
    }
    /**
     * 以redis文件夹名称读取所有key
     *
     * @param key 文件夹key
     * @return java.util.Set<java.lang.String>
     */
    public Set<String> skey(String key) {
        return redisTemplate.keys(key + StringPool.COLON_STA);
    }
    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public Boolean expire(String key, long time) {
        try {
            if (time > 0) {
                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) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public Boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        }
        catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }
    // ============================String=============================
    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return*/
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public Boolean set(String key, Object value) {
        try {
            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 {
            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 要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    // ================================Map=================================
    /**
     * HashGet
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return*/
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public Boolean hmset(String key, Map<String, Object> map) {
        try {
            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<String, Object> map, long time) {
        try {
            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 {
            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 {
            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) {
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public Boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }
    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        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) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
    // ============================set=============================
    /**
     * 根据key获取Set中的所有值
     *
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            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 {
            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 {
            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 {
            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 {
            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 {
            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<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        }
        catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取list缓存的长度
     *
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {
        try {
            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 {
            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 {
            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 {
            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<Object> value) {
        try {
            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<Object> value, long time) {
        try {
            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 {
            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 {
            long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        }
        catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}
View Code

RestTemplateUtils

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
@Component
@Slf4j
public class RestTemplateUtil
{
    @Autowired
    private RestTemplate restTemplate;
    /**
     * application/json方式提交数据
     *
     * @param url
     * @param object
     * @return
     */
    public String post(String url, Object object)
    {
        String body = "";
        try
        {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
            //设置参数
            HttpEntity < Object > requestEntity = new HttpEntity < > (object, httpHeaders);
            log.info("地址 : " + url + "\n" + "参数 : " + JSON.toJSONString(object) + "\n" + "请求头 : " + httpHeaders.toString());
            ResponseEntity < String > responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
            body = responseEntity.getBody();
        }
        catch (RestClientException e)
        {
            e.printStackTrace();
            log.error("Rest调用异常!!!地址 : " + url + "\n" + "参数 : " + JSON.toJSONString(object), e);
        }
        return body;
    }
    /**
     * application/json方式提交数据 自定义请求头
     *
     * @param url
     * @param object
     * @param headerMap
     * @return
     */
    public String postWithHeader(String url, Object object, Map < String, String > headerMap)
    {
        String body = "";
        try
        {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
            if (headerMap != null && headerMap.size() != 0)
            {
                for (String s: headerMap.keySet())
                {
                    httpHeaders.add(s, headerMap.get(s));
                }
            }
            log.info("地址 : " + url + "\n" + "参数 : " + JSON.toJSONString(object) + "\n" + "请求头 : " + httpHeaders.toString());
            //设置参数
            HttpEntity < Object > requestEntity = new HttpEntity < > (object, httpHeaders);
            ResponseEntity < String > responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
            body = responseEntity.getBody();
        }
        catch (RestClientException e)
        {
            e.printStackTrace();
            log.error("Rest调用异常!!!地址 : " + url + "\n" + "参数 : " + JSON.toJSONString(object) + "\n" + "请求头 : " + headerMap.toString(), e);
        }
        return body;
    }
    /**
     * 表单提交数据
     *
     * @param url
     * @param map
     * @return
     */
    public String postFrom(String url, Map < String, String > map)
    {
        String body = "";
        try
        {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            LinkedMultiValueMap < String, String > multiValueMap = new LinkedMultiValueMap < > ();
            if (map != null && map.size() != 0)
            {
                for (Map.Entry < String, String > entry: map.entrySet())
                {
                    multiValueMap.add(entry.getKey(), entry.getValue());
                }
            }
            //设置参数
            HttpEntity < LinkedMultiValueMap < String, String >> requestEntity = new HttpEntity < > (multiValueMap, httpHeaders);
            log.info("地址 : " + url + "\n" + "参数 : " + map.toString() + "\n" + "请求头 : " + httpHeaders.toString());
            ResponseEntity < String > responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
            body = responseEntity.getBody();
        }
        catch (RestClientException e)
        {
            e.printStackTrace();
            log.error("Rest调用异常!!!地址 : " + url + "\n" + "参数 : " + map.toString(), e);
        }
        return body;
    }
    /**
     * 表单提交数据 自定义请求头
     *
     * @param url
     * @param map
     * @param headerMap
     * @return
     */
    public String postFromWithHeader(String url, Map < String, String > map, Map < String, String > headerMap)
    {
        String body = "";
        try
        {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            if (headerMap != null && headerMap.size() != 0)
            {
                for (String s: headerMap.keySet())
                {
                    httpHeaders.add(s, headerMap.get(s));
                }
            }
            LinkedMultiValueMap < String, String > multiValueMap = new LinkedMultiValueMap < > ();
            if (map != null && map.size() != 0)
            {
                for (Map.Entry < String, String > entry: map.entrySet())
                {
                    multiValueMap.add(entry.getKey(), entry.getValue());
                }
            }
            //设置参数
            HttpEntity < LinkedMultiValueMap < String, String >> requestEntity = new HttpEntity < > (multiValueMap, httpHeaders);
            log.info("地址 : " + url + "\n" + "参数 : " + map.toString() + "\n" + "请求头 : " + headerMap.toString());
            ResponseEntity < String > responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
            body = responseEntity.getBody();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            log.error("Rest调用异常!!!地址 : " + url + "\n" + "参数 : " + map.toString() + "\n" + "请求头 : " + headerMap.toString(), e);
        }
        return body;
    }
}
View Code

SendMailUtils

发送邮件主类

import com.oristand.common.model.MyAuthenticator;
import com.oristand.common.model.SimpleMail;
import org.springframework.stereotype.Component;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

@Component
public class SendMailUtil {

    public static boolean sendMail(SimpleMail mailInfo){
        String host = mailInfo.getHost();
        String port = mailInfo.getPort();
        String username = mailInfo.getUserName();
        String password = mailInfo.getPassword();
        String from = mailInfo.getFrom();
        String[] to = mailInfo.getTo();
        String[] cc = mailInfo.getCc();
        Boolean needAuth = mailInfo.getNeedAuth();
        Map<String,String> fileInfo = mailInfo.getFiles();

        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", needAuth?"true":"flase");

        MyAuthenticator auth = null;
        if(needAuth){
            auth = new MyAuthenticator(username, password);
        }

        Session session = Session.getInstance(props,auth);

        try {
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress(from));
            if(to.length>0){
                InternetAddress[] toAddrs = new InternetAddress[to.length];
                for(int i=0;i<to.length;i++){
                    toAddrs[i] = new InternetAddress(to[i]);
                }
                msg.setRecipients(Message.RecipientType.TO, toAddrs);
            }
            if(cc!=null && cc.length>0){
                InternetAddress[] ccAddrs = new InternetAddress[cc.length];
                for(int i=0;i<cc.length;i++){
                    ccAddrs[i] = new InternetAddress(cc[i]);
                }
                msg.setRecipients(Message.RecipientType.CC, ccAddrs);
            }
            msg.setSubject(toChinese(mailInfo.getSubject()));

            // 创建多重消息
            Multipart multipart = new MimeMultipart();

            // 创建消息部分
            BodyPart messageBodyPart = new MimeBodyPart();

            // 消息
            messageBodyPart.setText(mailInfo.getContent());

            // 设置文本消息部分
            multipart.addBodyPart(messageBodyPart);

            // 附件部分
            if(fileInfo!=null && fileInfo.size()>0){
                Set<Entry<String, String>> files = fileInfo.entrySet();
                for (Entry<String, String> entry : files) {
                    String filename = entry.getKey();
                    String filePath = entry.getValue();
                    messageBodyPart = new MimeBodyPart();
                    // 设置要发送附件的文件路径
                    DataSource source = new FileDataSource(filePath);
                    messageBodyPart.setDataHandler(new DataHandler(source));
                    // messageBodyPart.setFileName(filename);
                    // 处理附件名称中文(附带文件路径)乱码问题
                    messageBodyPart.setFileName(MimeUtility.encodeText(filename));
                    multipart.addBodyPart(messageBodyPart);
                }
            }

            // 发送完整消息
            msg.setContent(multipart);

            Transport.send(msg);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    public static String toChinese(String text){
        try {
            text = MimeUtility.encodeText(text, "utf-8", "B");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return text;
    }
}
View Code

获取认证auth类

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class MyAuthenticator extends Authenticator {
    String userName=null;
    String password=null;

    public MyAuthenticator(){
    }

    public MyAuthenticator(String username, String password) {
        this.userName = username;
        this.password = password;
    }
    protected PasswordAuthentication getPasswordAuthentication(){
        return new PasswordAuthentication(userName, password);
    }
}
View Code

SimpleMail(发送邮件主类参数)

public class SimpleMail {
    private String[] to; //收件人
    private String[] cc; //抄送人
    private String from = "service7@bulkea.oristand.com"; //发件人
    private String host = "smtp.exmail.qq.com";
    private String port = "25";
    private String userName = "service7@bulkea.oristand.com";
    private String password = "Ori20180905";
    private String subject;
    private String content;
    private Boolean needAuth = true;
    private Map<String, String> files; //附件

    public SimpleMail(String[] to, String[] cc, String subject, String content) {
        super();
        this.to = to;
        this.cc = cc;
        this.subject = subject;
        this.content = content;
    }

    public String[] getTo() {
        return to;
    }

    public void setTo(String[] to) {
        this.to = to;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Map<String, String> getFiles() {
        return files;
    }

    public void setFiles(Map<String, String> files) {
        this.files = files;
    }

    public String[] getCc() {
        return cc;
    }

    public void setCc(String[] cc) {
        this.cc = cc;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public Boolean getNeedAuth() {
        return needAuth;
    }

    public void setNeedAuth(Boolean needAuth) {
        this.needAuth = needAuth;
    }
}
View Code

分割List为多个List

import java.util.ArrayList;
import java.util.List;


public class SplitListUtil {
    public static <T> List<List<T>> split(List<T> sList, int num) {
        List<List<T>> eList = new ArrayList<List<T>>();
        int size = sList.size();

        if (sList.size() > num) {
            int i = size / num;

            if ((i * num) < size) {
                i = i + 1;
            }

            for (int s = 0; s < i; s++) {
                List<T> a = new ArrayList<T>();
                int i1 = s * num;
                int i2 = num + (s * num);

                if (i2 > size) {
                    i2 = size;
                }

                for (int n = i1; n < i2; n++) {
                    a.add(sList.get(n));
                }

                eList.add(a);
            }

            return eList;
        } else {
            eList.add(sList);

            return eList;
        }
    }
}
View Code

静态String池

/**
 * 静态 String 池
 */
public interface StringPool {
    String AMPERSAND = "&";
    String AND = "and";
    String AT = "@";
    String ASTERISK = "*";
    String STAR = ASTERISK;
    String SLASH = "/";
    String BACK_SLASH = "\\";
    String DOUBLE_SLASH = "#//";
    String COLON = ":";
    String COMMA = ",";
    String DASH = "-";
    String DOLLAR = "$";
    String DOT = ".";
    String EMPTY = "";
    String EMPTY_JSON = "{}";
    String EQUALS = "=";
    String FALSE = "false";
    String HASH = "#";
    String HAT = "^";
    String LEFT_BRACE = "{";
    String LEFT_BRACKET = "(";
    String LEFT_CHEV = "<";
    String NEWLINE = "\n";
    String N = "n";
    String NO = "no";
    String NULL = "null";
    String OFF = "off";
    String ON = "on";
    String PERCENT = "%";
    String PIPE = "|";
    String PLUS = "+";
    String QUESTION_MARK = "?";
    String EXCLAMATION_MARK = "!";
    String QUOTE = "\"";
    String RETURN = "\r";
    String TAB = "\t";
    String RIGHT_BRACE = "}";
    String RIGHT_BRACKET = ")";
    String RIGHT_CHEV = ">";
    String SEMICOLON = ";";
    String SINGLE_QUOTE = "'";
    String BACKTICK = "`";
    String SPACE = " ";
    String TILDA = "~";
    String LEFT_SQ_BRACKET = "[";
    String RIGHT_SQ_BRACKET = "]";
    String TRUE = "true";
    String UNDERSCORE = "_";
    String UTF_8 = "UTF-8";
    String GBK = "GBK";
    String ISO_8859_1 = "ISO-8859-1";
    String Y = "y";
    String YES = "yes";
    String ONE = "1";
    String ZERO = "0";
    String TWO = "2";
    String DOLLAR_LEFT_BRACE = "${";
    String UNKNOWN = "unknown";
    String UNDEFINED = "undefined";
    String GET = "GET";
    String POST = "POST";
    String COLON_STA = ":*";
}
View Code

字符串工具类

package com.oristand.common.util;
import org.springframework.lang.Nullable;
import org.springframework.util.PatternMatchUtils;
import org.springframework.web.util.HtmlUtils;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
/**
 * 继承自Spring util的工具类,减少jar依赖
 *
 */
public class StringUtil extends org.springframework.util.StringUtils
{
    public static final int INDEX_NOT_FOUND = -1;
    //判断是否null或空值,或全部空格
    public static boolean isEmpty(Object str)
    {
        if (str == null || str.toString()
            .equals(""))
        {
            return true;
        }
        if (str.toString()
            .trim()
            .equals(""))
        {
            return true;
        }
        return false;
    }
    /**
     * 检查 参数String 是否为有意义的字符串<br>
     * 不为null,且不为空
     *
     * @param string
     * @return
     */
    public static boolean isValid(String string)
    {
        if (string == null || string.isEmpty())
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    /**
     * 检查 参数StringBuffer 是否为有意义的字符串<br>
     * 不为null,且不为空
     *
     * @param
     * @return
     */
    public static boolean isValid(StringBuffer sb)
    {
        if (sb == null || sb.length() == 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    /**
     * 检查 参数StringBuilder 是否为有意义的字符串<br>
     * 不为null,且不为空
     *
     * @param
     * @return
     */
    public static boolean isValid(StringBuilder sb)
    {
        if (sb == null || sb.length() == 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    /**
     * 检查 参数Object 是否为有意义的对象<br>
     * 不为null,且不为空
     *
     * @param object
     * @return
     */
    public static boolean isValid(Object object)
    {
        if (object == null || object.toString()
            .length() == 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    /**
     * 中文:/[\u4e00-\u9fa5]/
     * 日文:/[\u0800-\u4e00]/
     * 韩文:/[\uac00-\ud7ff]/
     *
     * @param str
     * @return
     */
    public static boolean isJapanesChar(String str)
    {
        boolean temp = false;
        Pattern p = Pattern.compile("[ࠀ-一]");
        Matcher m = p.matcher(str);
        if (m.find())
        {
            temp = true;
        }
        return temp;
    }
    public static String getString(String str)
    {
        if (str == null || "".equals(str))
        {
            return "";
        }
        else
        {
            return str;
        }
    }
    private static boolean isMatch(String regex, String orginal)
    {
        if (orginal == null || orginal.trim()
            .equals(""))
        {
            return false;
        }
        Pattern pattern = Pattern.compile(regex);
        Matcher isNum = pattern.matcher(orginal);
        return isNum.matches();
    }
    /**
     * 是否是小数
     * @param orginal
     * @return
     */
    public static boolean isDecimal(String orginal)
    {
        return isMatch("[-+]{0,1}\\d+\\.\\d*|[-+]{0,1}\\d*\\.\\d+", orginal);
    }
    //判断是否null或空值,或全部空格
    public static boolean isEmptyOrNull(Object str)
    {
        if (str == null || str.toString()
            .equals("")) return true;
        if (str.toString()
            .trim()
            .equals("")) return true;
        if (str.toString()
            .trim()
            .toUpperCase()
            .equals("NULL")) return true;
        return false;
    }
    /**
     * 是否是正整数
     * @param orginal
     * @return
     */
    public static boolean isPositiveInteger(String orginal)
    {
        return isMatch("^\\+{0,1}[1-9]\\d*", orginal);
    }
    /**
     * 是否是负整数
     * @param orginal
     * @return
     */
    public static boolean isNegativeInteger(String orginal)
    {
        return isMatch("^-[1-9]\\d*", orginal);
    }
    /**
     * 是否是整数
     * @param orginal
     * @return
     */
    public static boolean isWholeNumber(String orginal)
    {
        return isMatch("[+-]{0,1}0", orginal) || isPositiveInteger(orginal) || isNegativeInteger(orginal);
    }
    /**
     * 是否是实数
     * @param orginal
     * @return
     */
    public static boolean isRealNumber(Object orginal)
    {
        if (isEmptyOrNull(orginal)) return false;
        return isWholeNumber(orginal.toString()) || isDecimal(orginal.toString());
    }
    public static String getNumberValuePro(Object a)
    {
        if (isEmpty(a))
        {
            return "0";
        }
        if (isRealNumber(a))
        {
            return a.toString();
        }
        return "0";
    }
    public static String getStringValue(Object a)
    {
        if (isEmpty(a))
        {
            return "";
        }
        return a.toString();
    }
    public static String getUsFormatCreateDate(Object obj)
    {
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date orderDate;
        try
        {
            if (isEmptyOrNull(obj))
            {
                orderDate = new Date();
            }
            else
            {
                orderDate = sdf1.parse(getStringValue(obj));
            }
            sdf2.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
            String orderDateStr = sdf2.format(orderDate);
            return orderDateStr;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 逗号拼接List元素
     * @param list
     * @return
     */
    public static String listToStr(List < String > list)
    {
        if (list == null || list.size() == 0)
        {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (String t: list)
        {
            sb.append(String.valueOf(t) + ",");
        }
        if (sb.length() > 1)
        {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }
    /**
     * 截取字符串
     *
     * @param s
     * @param maxlength
     * @return
     */
    public static String substringpro(String s, int begin, int maxlength)
    {
        try
        {
            int tempcz = s.length() - maxlength; //相差的字节数
            if (tempcz <= 0)
            {
                return s;
            }
            else
            {
                return s.substring(begin, maxlength);
            }
        }
        catch (Exception e)
        {
            return s;
        }
    }
    /**
     * Check whether the given {@code CharSequence} contains actual <em>text</em>.
     * <p>More specifically, this method returns {@code true} if the
     * {@code CharSequence} is not {@code null}, its length is greater than
     * 0, and it contains at least one non-whitespace character.
     * <pre class="code">
     * StringUtil.isBlank(null) = true
     * StringUtil.isBlank("") = true
     * StringUtil.isBlank(" ") = true
     * StringUtil.isBlank("12345") = false
     * StringUtil.isBlank(" 12345 ") = false
     * </pre>
     *
     * @param cs the {@code CharSequence} to check (may be {@code null})
     * @return {@code true} if the {@code CharSequence} is not {@code null},
     * its length is greater than 0, and it does not contain whitespace only
     * @see Character#isWhitespace
     */
    public static boolean isBlank(final CharSequence cs)
    {
        return !StringUtil.hasText(cs);
    }
    /**
     * <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
     * <pre>
     * StringUtil.isNotBlank(null)      = false
     * StringUtil.isNotBlank("")        = false
     * StringUtil.isNotBlank(" ")       = false
     * StringUtil.isNotBlank("bob")     = true
     * StringUtil.isNotBlank("  bob  ") = true
     * </pre>
     *
     * @param cs the CharSequence to check, may be null
     * @return {@code true} if the CharSequence is
     * not empty and not null and not whitespace
     * @see Character#isWhitespace
     */
    public static boolean isNotBlank(final CharSequence cs)
    {
        return StringUtil.hasText(cs);
    }
    /**
     * 是否全为 Blank
     *
     * @param css CharSequence
     * @return boolean
     */
    public static boolean isAllBlank(final CharSequence...css)
    {
        return Stream.of(css)
            .allMatch(StringUtil::isBlank);
    }
    /**
     * 判断一个字符串是否是数字
     *
     * @param cs the CharSequence to check, may be null
     * @return {boolean}
     */
    public static boolean isNumeric(final CharSequence cs)
    {
        if (isBlank(cs))
        {
            return false;
        }
        for (int i = cs.length(); --i >= 0;)
        {
            int chr = cs.charAt(i);
            if (chr < 48 || chr > 57)
            {
                return false;
            }
        }
        return true;
    }
    /**
     * 将字符串中特定模式的字符转换成map中对应的值
     * <p>
     * use: format("my name is ${name}, and i like ${like}!", {"name":"xx", "like": "Java"})
     *
     * @param message 需要转换的字符串
     * @param params  转换所需的键值对集合
     * @return 转换后的字符串
     */
    public static String format(@Nullable String message, @Nullable Map < String, Object > params)
    {
        // message 为 null 返回空字符串
        if (message == null)
        {
            return StringPool.EMPTY;
        }
        // 参数为 null 或者为空
        if (params == null || params.isEmpty())
        {
            return message;
        }
        // 替换变量
        StringBuilder sb = new StringBuilder((int)(message.length() * 1.5));
        int cursor = 0;
        for (int start, end;
            (start = message.indexOf(StringPool.DOLLAR_LEFT_BRACE, cursor)) != -1 && (end = message.indexOf(StringPool.RIGHT_BRACE, start)) != -1;)
        {
            sb.append(message, cursor, start);
            String key = message.substring(start + 2, end);
            Object value = params.get(StringUtil.trimWhitespace(key));
            sb.append(value == null ? StringPool.EMPTY : value);
            cursor = end + 1;
        }
        sb.append(message.substring(cursor));
        return sb.toString();
    }
    /**
     * 同 log 格式的 format 规则
     * <p>
     * use: format("my name is {}, and i like {}!", "xx", "Java")
     *
     * @param message   需要转换的字符串
     * @param arguments 需要替换的变量
     * @return 转换后的字符串
     */
    public static String format(@Nullable String message, @Nullable Object...arguments)
    {
        // message 为 null 返回空字符串
        if (message == null)
        {
            return StringPool.EMPTY;
        }
        // 参数为 null 或者为空
        if (arguments == null || arguments.length == 0)
        {
            return message;
        }
        StringBuilder sb = new StringBuilder((int)(message.length() * 1.5));
        int cursor = 0;
        int index = 0;
        int argsLength = arguments.length;
        for (int start, end;
            (start = message.indexOf('{', cursor)) != -1 && (end = message.indexOf('}', start)) != -1 && index < argsLength;)
        {
            sb.append(message, cursor, start);
            sb.append(arguments[index]);
            cursor = end + 1;
            index++;
        }
        sb.append(message.substring(cursor));
        return sb.toString();
    }
    /**
     * Convert a {@code Collection} into a delimited {@code String} (e.g., CSV).
     * <p>Useful for {@code toString()} implementations.
     *
     * @param coll the {@code Collection} to convert
     * @return the delimited {@code String}
     */
    public static String join(Collection < ? > coll)
    {
        return StringUtil.collectionToCommaDelimitedString(coll);
    }
    /**
     * Convert a {@code Collection} into a delimited {@code String} (e.g. CSV).
     * <p>Useful for {@code toString()} implementations.
     *
     * @param coll  the {@code Collection} to convert
     * @param delim the delimiter to use (typically a ",")
     * @return the delimited {@code String}
     */
    public static String join(Collection < ? > coll, String delim)
    {
        return StringUtil.collectionToDelimitedString(coll, delim);
    }
    /**
     * Convert a {@code String} array into a comma delimited {@code String}
     * (i.e., CSV).
     * <p>Useful for {@code toString()} implementations.
     *
     * @param arr the array to display
     * @return the delimited {@code String}
     */
    public static String join(Object[] arr)
    {
        return StringUtil.arrayToCommaDelimitedString(arr);
    }
    /**
     * Convert a {@code String} array into a delimited {@code String} (e.g. CSV).
     * <p>Useful for {@code toString()} implementations.
     *
     * @param arr   the array to display
     * @param delim the delimiter to use (typically a ",")
     * @return the delimited {@code String}
     */
    public static String join(Object[] arr, String delim)
    {
        return StringUtil.arrayToDelimitedString(arr, delim);
    }
    /**
     * 字符串是否符合指定的 表达式
     *
     * <p>
     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
     * </p>
     *
     * @param pattern 表达式
     * @param str     字符串
     * @return 是否匹配
     */
    public static boolean simpleMatch(@Nullable String pattern, @Nullable String str)
    {
        return PatternMatchUtils.simpleMatch(pattern, str);
    }
    /**
     * 字符串是否符合指定的 表达式
     *
     * <p>
     * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy"
     * </p>
     *
     * @param patterns 表达式 数组
     * @param str      字符串
     * @return 是否匹配
     */
    public static boolean simpleMatch(@Nullable String[] patterns, String str)
    {
        return PatternMatchUtils.simpleMatch(patterns, str);
    }
    /**
     * 生成uuid
     *
     * @return UUID
     */
    public static String randomUUID()
    {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        return new UUID(random.nextLong(), random.nextLong())
            .toString()
            .replace(StringPool.DASH, StringPool.EMPTY);
    }
    /**
     * 转义HTML用于安全过滤
     *
     * @param html html
     * @return {String}
     */
    public static String escapeHtml(String html)
    {
        return StringUtil.isBlank(html) ? StringPool.EMPTY : HtmlUtils.htmlEscape(html);
    }
    /**
     * 清理字符串,清理出某些不可见字符
     *
     * @param txt 字符串
     * @return {String}
     */
    public static String cleanChars(String txt)
    {
        return txt.replaceAll("[  `·•�\\f\\t\\v\\s]", "");
    }
    private static final String S_INT = "0123456789";
    private static final String S_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static final String S_ALL = S_INT + S_STR;
    /**
     * 有序的格式化文本,使用{number}做为占位符<br>
     * 例:<br>
     * 通常使用:format("this is {0} for {1}", "a", "b") =》 this is a for b<br>
     *
     * @param pattern   文本格式
     * @param arguments 参数
     * @return 格式化后的文本
     */
    public static String indexedFormat(CharSequence pattern, Object...arguments)
    {
        return MessageFormat.format(pattern.toString(), arguments);
    }
    /**
     * 切分字符串,不去除切分后每个元素两边的空白符,不去除空白项
     *
     * @param str       被切分的字符串
     * @param separator 分隔符字符
     * @param limit     限制分片数,-1不限制
     * @return 切分后的集合
     */
    public static List < String > split(CharSequence str, char separator, int limit)
    {
        return split(str, separator, limit, false, false);
    }
    /**
     * 分割 字符串 删除常见 空白符
     *
     * @param str       字符串
     * @param delimiter 分割符
     * @return 字符串数组
     */
    public static String[] splitTrim(@Nullable String str, @Nullable String delimiter)
    {
        return StringUtil.delimitedListToStringArray(str, delimiter, " \t\n\n\f");
    }
    /**
     * 切分字符串,去除切分后每个元素两边的空白符,去除空白项
     *
     * @param str       被切分的字符串
     * @param separator 分隔符字符
     * @return 切分后的集合
     * @since 3.1.2
     */
    public static List < String > splitTrim(CharSequence str, char separator)
    {
        return splitTrim(str, separator, -1);
    }
    /**
     * 切分字符串,去除切分后每个元素两边的空白符,去除空白项
     *
     * @param str       被切分的字符串
     * @param separator 分隔符字符
     * @return 切分后的集合
     * @since 3.2.0
     */
    public static List < String > splitTrim(CharSequence str, CharSequence separator)
    {
        return splitTrim(str, separator, -1);
    }
    /**
     * 切分字符串,去除切分后每个元素两边的空白符,去除空白项
     *
     * @param str       被切分的字符串
     * @param separator 分隔符字符
     * @param limit     限制分片数,-1不限制
     * @return 切分后的集合
     * @since 3.1.0
     */
    public static List < String > splitTrim(CharSequence str, char separator, int limit)
    {
        return split(str, separator, limit, true, true);
    }
    /**
     * 切分字符串,去除切分后每个元素两边的空白符,去除空白项
     *
     * @param str       被切分的字符串
     * @param separator 分隔符字符
     * @param limit     限制分片数,-1不限制
     * @return 切分后的集合
     * @since 3.2.0
     */
    public static List < String > splitTrim(CharSequence str, CharSequence separator, int limit)
    {
        return split(str, separator, limit, true, true);
    }
    /**
     * 切分字符串,不限制分片数量
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > split(CharSequence str, char separator, boolean isTrim, boolean ignoreEmpty)
    {
        return split(str, separator, 0, isTrim, ignoreEmpty);
    }
    /**
     * 切分字符串
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param limit       限制分片数,-1不限制
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > split(CharSequence str, char separator, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        if (null == str)
        {
            return new ArrayList < > (0);
        }
        return StrSpliter.split(str.toString(), separator, limit, isTrim, ignoreEmpty);
    }
    /**
     * 切分字符串
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param limit       限制分片数,-1不限制
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.2.0
     */
    public static List < String > split(CharSequence str, CharSequence separator, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        if (null == str)
        {
            return new ArrayList < > (0);
        }
        final String separatorStr = (null == separator) ? null : separator.toString();
        return StrSpliter.split(str.toString(), separatorStr, limit, isTrim, ignoreEmpty);
    }
    /**
     * 切分字符串
     *
     * @param str       被切分的字符串
     * @param separator 分隔符
     * @return 字符串
     */
    public static String[] split(CharSequence str, CharSequence separator)
    {
        if (str == null)
        {
            return new String[]
            {};
        }
        final String separatorStr = (null == separator) ? null : separator.toString();
        return StrSpliter.splitToArray(str.toString(), separatorStr, 0, false, false);
    }
    /**
     * 根据给定长度,将给定字符串截取为多个部分
     *
     * @param str 字符串
     * @param len 每一个小节的长度
     * @return 截取后的字符串数组
     * @see StrSpliter#splitByLength(String, int)
     */
    public static String[] split(CharSequence str, int len)
    {
        if (null == str)
        {
            return new String[]
            {};
        }
        return StrSpliter.splitByLength(str.toString(), len);
    }
    /**
     * 指定字符是否在字符串中出现过
     *
     * @param str        字符串
     * @param searchChar 被查找的字符
     * @return 是否包含
     * @since 3.1.2
     */
    public static boolean contains(CharSequence str, char searchChar)
    {
        return indexOf(str, searchChar) > -1;
    }
    /**
     * 是否包含特定字符,忽略大小写,如果给定两个参数都为<code>null</code>,返回true
     *
     * @param str     被检测字符串
     * @param testStr 被测试是否包含的字符串
     * @return 是否包含
     */
    public static boolean containsIgnoreCase(CharSequence str, CharSequence testStr)
    {
        if (null == str)
        {
            // 如果被监测字符串和
            return null == testStr;
        }
        return str.toString()
            .toLowerCase()
            .contains(testStr.toString()
                .toLowerCase());
    }
    /**
     * 改进JDK subString<br>
     * index从0开始计算,最后一个字符为-1<br>
     * 如果from和to位置一样,返回 "" <br>
     * 如果from或to为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length<br>
     * 如果经过修正的index中from大于to,则互换from和to example: <br>
     * abcdefgh 2 3 =》 c <br>
     * abcdefgh 2 -3 =》 cde <br>
     *
     * @param str       String
     * @param fromIndex 开始的index(包括)
     * @param toIndex   结束的index(不包括)
     * @return 字串
     */
    public static String sub(CharSequence str, int fromIndex, int toIndex)
    {
        if (isEmpty(str))
        {
            return StringPool.EMPTY;
        }
        int len = str.length();
        if (fromIndex < 0)
        {
            fromIndex = len + fromIndex;
            if (fromIndex < 0)
            {
                fromIndex = 0;
            }
        }
        else if (fromIndex > len)
        {
            fromIndex = len;
        }
        if (toIndex < 0)
        {
            toIndex = len + toIndex;
            if (toIndex < 0)
            {
                toIndex = len;
            }
        }
        else if (toIndex > len)
        {
            toIndex = len;
        }
        if (toIndex < fromIndex)
        {
            int tmp = fromIndex;
            fromIndex = toIndex;
            toIndex = tmp;
        }
        if (fromIndex == toIndex)
        {
            return StringPool.EMPTY;
        }
        return str.toString()
            .substring(fromIndex, toIndex);
    }
    /**
     * 截取分隔字符串之前的字符串,不包括分隔字符串<br>
     * 如果给定的字符串为空串(null或"")或者分隔字符串为null,返回原字符串<br>
     * 如果分隔字符串为空串"",则返回空串,如果分隔字符串未找到,返回原字符串
     * <p>
     * 栗子:
     *
     * <pre>
     * StringUtil.subBefore(null, *)      = null
     * StringUtil.subBefore("", *)        = ""
     * StringUtil.subBefore("abc", "a")   = ""
     * StringUtil.subBefore("abcba", "b") = "a"
     * StringUtil.subBefore("abc", "c")   = "ab"
     * StringUtil.subBefore("abc", "d")   = "abc"
     * StringUtil.subBefore("abc", "")    = ""
     * StringUtil.subBefore("abc", null)  = "abc"
     * </pre>
     *
     * @param string          被查找的字符串
     * @param separator       分隔字符串(不包括)
     * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
     * @return 切割后的字符串
     * @since 3.1.1
     */
    public static String subBefore(CharSequence string, CharSequence separator, boolean isLastSeparator)
    {
        if (isEmpty(string) || separator == null)
        {
            return null == string ? null : string.toString();
        }
        final String str = string.toString();
        final String sep = separator.toString();
        if (sep.isEmpty())
        {
            return StringPool.EMPTY;
        }
        final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
        if (pos == INDEX_NOT_FOUND)
        {
            return str;
        }
        return str.substring(0, pos);
    }
    /**
     * 截取分隔字符串之后的字符串,不包括分隔字符串<br>
     * 如果给定的字符串为空串(null或""),返回原字符串<br>
     * 如果分隔字符串为空串(null或""),则返回空串,如果分隔字符串未找到,返回空串
     * <p>
     * 栗子:
     *
     * <pre>
     * StringUtil.subAfter(null, *)      = null
     * StringUtil.subAfter("", *)        = ""
     * StringUtil.subAfter(*, null)      = ""
     * StringUtil.subAfter("abc", "a")   = "bc"
     * StringUtil.subAfter("abcba", "b") = "cba"
     * StringUtil.subAfter("abc", "c")   = ""
     * StringUtil.subAfter("abc", "d")   = ""
     * StringUtil.subAfter("abc", "")    = "abc"
     * </pre>
     *
     * @param string          被查找的字符串
     * @param separator       分隔字符串(不包括)
     * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
     * @return 切割后的字符串
     * @since 3.1.1
     */
    public static String subAfter(CharSequence string, CharSequence separator, boolean isLastSeparator)
    {
        if (isEmpty(string))
        {
            return null == string ? null : string.toString();
        }
        if (separator == null)
        {
            return StringPool.EMPTY;
        }
        final String str = string.toString();
        final String sep = separator.toString();
        final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
        if (pos == INDEX_NOT_FOUND)
        {
            return StringPool.EMPTY;
        }
        return str.substring(pos + separator.length());
    }
    /**
     * 截取指定字符串中间部分,不包括标识字符串<br>
     * <p>
     * 栗子:
     *
     * <pre>
     * StringUtil.subBetween("wx[b]yz", "[", "]") = "b"
     * StringUtil.subBetween(null, *, *)          = null
     * StringUtil.subBetween(*, null, *)          = null
     * StringUtil.subBetween(*, *, null)          = null
     * StringUtil.subBetween("", "", "")          = ""
     * StringUtil.subBetween("", "", "]")         = null
     * StringUtil.subBetween("", "[", "]")        = null
     * StringUtil.subBetween("yabcz", "", "")     = ""
     * StringUtil.subBetween("yabcz", "y", "z")   = "abc"
     * StringUtil.subBetween("yabczyabcz", "y", "z")   = "abc"
     * </pre>
     *
     * @param str    被切割的字符串
     * @param before 截取开始的字符串标识
     * @param after  截取到的字符串标识
     * @return 截取后的字符串
     * @since 3.1.1
     */
    public static String subBetween(CharSequence str, CharSequence before, CharSequence after)
    {
        if (str == null || before == null || after == null)
        {
            return null;
        }
        final String str2 = str.toString();
        final String before2 = before.toString();
        final String after2 = after.toString();
        final int start = str2.indexOf(before2);
        if (start != INDEX_NOT_FOUND)
        {
            final int end = str2.indexOf(after2, start + before2.length());
            if (end != INDEX_NOT_FOUND)
            {
                return str2.substring(start + before2.length(), end);
            }
        }
        return null;
    }
    /**
     * 截取指定字符串中间部分,不包括标识字符串<br>
     * <p>
     * 栗子:
     *
     * <pre>
     * StringUtil.subBetween(null, *)            = null
     * StringUtil.subBetween("", "")             = ""
     * StringUtil.subBetween("", "tag")          = null
     * StringUtil.subBetween("tagabctag", null)  = null
     * StringUtil.subBetween("tagabctag", "")    = ""
     * StringUtil.subBetween("tagabctag", "tag") = "abc"
     * </pre>
     *
     * @param str            被切割的字符串
     * @param beforeAndAfter 截取开始和结束的字符串标识
     * @return 截取后的字符串
     * @since 3.1.1
     */
    public static String subBetween(CharSequence str, CharSequence beforeAndAfter)
    {
        return subBetween(str, beforeAndAfter, beforeAndAfter);
    }
    /**
     * 去掉指定前缀
     *
     * @param str    字符串
     * @param prefix 前缀
     * @return 切掉后的字符串,若前缀不是 preffix, 返回原字符串
     */
    public static String removePrefix(CharSequence str, CharSequence prefix)
    {
        if (isEmpty(str) || isEmpty(prefix))
        {
            return StringPool.EMPTY;
        }
        final String str2 = str.toString();
        if (str2.startsWith(prefix.toString()))
        {
            return subSuf(str2, prefix.length());
        }
        return str2;
    }
    /**
     * 忽略大小写去掉指定前缀
     *
     * @param str    字符串
     * @param prefix 前缀
     * @return 切掉后的字符串,若前缀不是 prefix, 返回原字符串
     */
    public static String removePrefixIgnoreCase(CharSequence str, CharSequence prefix)
    {
        if (isEmpty(str) || isEmpty(prefix))
        {
            return StringPool.EMPTY;
        }
        final String str2 = str.toString();
        if (str2.toLowerCase()
            .startsWith(prefix.toString()
                .toLowerCase()))
        {
            return subSuf(str2, prefix.length());
        }
        return str2;
    }
    /**
     * 去掉指定后缀
     *
     * @param str    字符串
     * @param suffix 后缀
     * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
     */
    public static String removeSuffix(CharSequence str, CharSequence suffix)
    {
        if (isEmpty(str) || isEmpty(suffix))
        {
            return StringPool.EMPTY;
        }
        final String str2 = str.toString();
        if (str2.endsWith(suffix.toString()))
        {
            return subPre(str2, str2.length() - suffix.length());
        }
        return str2;
    }
    /**
     * 去掉指定后缀,并小写首字母
     *
     * @param str    字符串
     * @param suffix 后缀
     * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
     */
    public static String removeSufAndLowerFirst(CharSequence str, CharSequence suffix)
    {
        return firstCharToLower(removeSuffix(str, suffix));
    }
    /**
     * 忽略大小写去掉指定后缀
     *
     * @param str    字符串
     * @param suffix 后缀
     * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
     */
    public static String removeSuffixIgnoreCase(CharSequence str, CharSequence suffix)
    {
        if (isEmpty(str) || isEmpty(suffix))
        {
            return StringPool.EMPTY;
        }
        final String str2 = str.toString();
        if (str2.toLowerCase()
            .endsWith(suffix.toString()
                .toLowerCase()))
        {
            return subPre(str2, str2.length() - suffix.length());
        }
        return str2;
    }
    /**
     * 首字母变小写
     *
     * @param str 字符串
     * @return {String}
     */
    public static String firstCharToLower(String str)
    {
        char firstChar = str.charAt(0);
        if (firstChar >= CharPool.UPPER_A && firstChar <= CharPool.UPPER_Z)
        {
            char[] arr = str.toCharArray();
            arr[0] += CharPool.LOWER_A - CharPool.UPPER_A;
            return new String(arr);
        }
        return str;
    }
    /**
     * 首字母变大写
     *
     * @param str 字符串
     * @return {String}
     */
    public static String firstCharToUpper(String str)
    {
        char firstChar = str.charAt(0);
        if (firstChar >= CharPool.LOWER_A && firstChar <= CharPool.LOWER_Z)
        {
            char[] arr = str.toCharArray();
            arr[0] -= CharPool.LOWER_A - CharPool.UPPER_A;
            return new String(arr);
        }
        return str;
    }
    /**
     * 切割指定位置之前部分的字符串
     *
     * @param string  字符串
     * @param toIndex 切割到的位置(不包括)
     * @return 切割后的剩余的前半部分字符串
     */
    public static String subPre(CharSequence string, int toIndex)
    {
        return sub(string, 0, toIndex);
    }
    /**
     * 切割指定位置之后部分的字符串
     *
     * @param string    字符串
     * @param fromIndex 切割开始的位置(包括)
     * @return 切割后后剩余的后半部分字符串
     */
    public static String subSuf(CharSequence string, int fromIndex)
    {
        if (isEmpty(string))
        {
            return null;
        }
        return sub(string, fromIndex, string.length());
    }
    /**
     * 指定范围内查找指定字符
     *
     * @param str        字符串
     * @param searchChar 被查找的字符
     * @return 位置
     */
    public static int indexOf(final CharSequence str, char searchChar)
    {
        return indexOf(str, searchChar, 0);
    }
    /**
     * 指定范围内查找指定字符
     *
     * @param str        字符串
     * @param searchChar 被查找的字符
     * @param start      起始位置,如果小于0,从0开始查找
     * @return 位置
     */
    public static int indexOf(final CharSequence str, char searchChar, int start)
    {
        if (str instanceof String)
        {
            return ((String) str)
                .indexOf(searchChar, start);
        }
        else
        {
            return indexOf(str, searchChar, start, -1);
        }
    }
    /**
     * 指定范围内查找指定字符
     *
     * @param str        字符串
     * @param searchChar 被查找的字符
     * @param start      起始位置,如果小于0,从0开始查找
     * @param end        终止位置,如果超过str.length()则默认查找到字符串末尾
     * @return 位置
     */
    public static int indexOf(final CharSequence str, char searchChar, int start, int end)
    {
        final int len = str.length();
        if (start < 0 || start > len)
        {
            start = 0;
        }
        if (end > len || end < 0)
        {
            end = len;
        }
        for (int i = start; i < end; i++)
        {
            if (str.charAt(i) == searchChar)
            {
                return i;
            }
        }
        return -1;
    }
    /**
     * 指定范围内查找字符串,忽略大小写<br>
     *
     * <pre>
     * StringUtil.indexOfIgnoreCase(null, *, *)          = -1
     * StringUtil.indexOfIgnoreCase(*, null, *)          = -1
     * StringUtil.indexOfIgnoreCase("", "", 0)           = 0
     * StringUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
     * StringUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
     * StringUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
     * StringUtil.indexOfIgnoreCase("abc", "", 9)        = -1
     * </pre>
     *
     * @param str       字符串
     * @param searchStr 需要查找位置的字符串
     * @return 位置
     * @since 3.2.1
     */
    public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr)
    {
        return indexOfIgnoreCase(str, searchStr, 0);
    }
    /**
     * 指定范围内查找字符串
     *
     * <pre>
     * StringUtil.indexOfIgnoreCase(null, *, *)          = -1
     * StringUtil.indexOfIgnoreCase(*, null, *)          = -1
     * StringUtil.indexOfIgnoreCase("", "", 0)           = 0
     * StringUtil.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
     * StringUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
     * StringUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
     * StringUtil.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
     * StringUtil.indexOfIgnoreCase("abc", "", 9)        = -1
     * </pre>
     *
     * @param str       字符串
     * @param searchStr 需要查找位置的字符串
     * @param fromIndex 起始位置
     * @return 位置
     * @since 3.2.1
     */
    public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex)
    {
        return indexOf(str, searchStr, fromIndex, true);
    }
    /**
     * 指定范围内反向查找字符串
     *
     * @param str        字符串
     * @param searchStr  需要查找位置的字符串
     * @param fromIndex  起始位置
     * @param ignoreCase 是否忽略大小写
     * @return 位置
     * @since 3.2.1
     */
    public static int indexOf(final CharSequence str, CharSequence searchStr, int fromIndex, boolean ignoreCase)
    {
        if (str == null || searchStr == null)
        {
            return INDEX_NOT_FOUND;
        }
        if (fromIndex < 0)
        {
            fromIndex = 0;
        }
        final int endLimit = str.length() - searchStr.length() + 1;
        if (fromIndex > endLimit)
        {
            return INDEX_NOT_FOUND;
        }
        if (searchStr.length() == 0)
        {
            return fromIndex;
        }
        if (false == ignoreCase)
        {
            // 不忽略大小写调用JDK方法
            return str.toString()
                .indexOf(searchStr.toString(), fromIndex);
        }
        for (int i = fromIndex; i < endLimit; i++)
        {
            if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true))
            {
                return i;
            }
        }
        return INDEX_NOT_FOUND;
    }
    /**
     * 指定范围内查找字符串,忽略大小写<br>
     *
     * @param str       字符串
     * @param searchStr 需要查找位置的字符串
     * @return 位置
     * @since 3.2.1
     */
    public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr)
    {
        return lastIndexOfIgnoreCase(str, searchStr, str.length());
    }
    /**
     * 指定范围内查找字符串,忽略大小写<br>
     *
     * @param str       字符串
     * @param searchStr 需要查找位置的字符串
     * @param fromIndex 起始位置,从后往前计数
     * @return 位置
     * @since 3.2.1
     */
    public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex)
    {
        return lastIndexOf(str, searchStr, fromIndex, true);
    }
    /**
     * 指定范围内查找字符串<br>
     *
     * @param str        字符串
     * @param searchStr  需要查找位置的字符串
     * @param fromIndex  起始位置,从后往前计数
     * @param ignoreCase 是否忽略大小写
     * @return 位置
     * @since 3.2.1
     */
    public static int lastIndexOf(final CharSequence str, final CharSequence searchStr, int fromIndex, boolean ignoreCase)
    {
        if (str == null || searchStr == null)
        {
            return INDEX_NOT_FOUND;
        }
        if (fromIndex < 0)
        {
            fromIndex = 0;
        }
        fromIndex = Math.min(fromIndex, str.length());
        if (searchStr.length() == 0)
        {
            return fromIndex;
        }
        if (!ignoreCase)
        {
            // 不忽略大小写调用JDK方法
            return str.toString()
                .lastIndexOf(searchStr.toString(), fromIndex);
        }
        for (int i = fromIndex; i > 0; i--)
        {
            if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true))
            {
                return i;
            }
        }
        return INDEX_NOT_FOUND;
    }
    /**
     * 返回字符串 searchStr 在字符串 str 中第 ordinal 次出现的位置。<br>
     * 此方法来自:Apache-Commons-Lang
     * <p>
     * 栗子(*代表任意字符):
     *
     * <pre>
     * StringUtil.ordinalIndexOf(null, *, *)          = -1
     * StringUtil.ordinalIndexOf(*, null, *)          = -1
     * StringUtil.ordinalIndexOf("", "", *)           = 0
     * StringUtil.ordinalIndexOf("aabaabaa", "a", 1)  = 0
     * StringUtil.ordinalIndexOf("aabaabaa", "a", 2)  = 1
     * StringUtil.ordinalIndexOf("aabaabaa", "b", 1)  = 2
     * StringUtil.ordinalIndexOf("aabaabaa", "b", 2)  = 5
     * StringUtil.ordinalIndexOf("aabaabaa", "ab", 1) = 1
     * StringUtil.ordinalIndexOf("aabaabaa", "ab", 2) = 4
     * StringUtil.ordinalIndexOf("aabaabaa", "", 1)   = 0
     * StringUtil.ordinalIndexOf("aabaabaa", "", 2)   = 0
     * </pre>
     *
     * @param str       被检查的字符串,可以为null
     * @param searchStr 被查找的字符串,可以为null
     * @param ordinal   第几次出现的位置
     * @return 查找到的位置
     * @since 3.2.3
     */
    public static int ordinalIndexOf(String str, String searchStr, int ordinal)
    {
        if (str == null || searchStr == null || ordinal <= 0)
        {
            return INDEX_NOT_FOUND;
        }
        if (searchStr.length() == 0)
        {
            return 0;
        }
        int found = 0;
        int index = INDEX_NOT_FOUND;
        do {
            index = str.indexOf(searchStr, index + 1);
            if (index < 0)
            {
                return index;
            }
            found++;
        } while (found < ordinal);
        return index;
    }
    /**
     * 截取两个字符串的不同部分(长度一致),判断截取的子串是否相同<br>
     * 任意一个字符串为null返回false
     *
     * @param str1       第一个字符串
     * @param start1     第一个字符串开始的位置
     * @param str2       第二个字符串
     * @param start2     第二个字符串开始的位置
     * @param length     截取长度
     * @param ignoreCase 是否忽略大小写
     * @return 子串是否相同
     * @since 3.2.1
     */
    public static boolean isSubEquals(CharSequence str1, int start1, CharSequence str2, int start2, int length, boolean ignoreCase)
    {
        if (null == str1 || null == str2)
        {
            return false;
        }
        return str1.toString()
            .regionMatches(ignoreCase, start1, str2.toString(), start2, length);
    }
    /**
     * 比较两个字符串(大小写敏感)。
     *
     * <pre>
     * equalsIgnoreCase(null, null)   = true
     * equalsIgnoreCase(null, &quot;abc&quot;)  = false
     * equalsIgnoreCase(&quot;abc&quot;, null)  = false
     * equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
     * equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
     * </pre>
     *
     * @param str1 要比较的字符串1
     * @param str2 要比较的字符串2
     * @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
     */
    public static boolean equals(CharSequence str1, CharSequence str2)
    {
        return equals(str1, str2, false);
    }
    /**
     * 比较两个字符串(大小写不敏感)。
     *
     * <pre>
     * equalsIgnoreCase(null, null)   = true
     * equalsIgnoreCase(null, &quot;abc&quot;)  = false
     * equalsIgnoreCase(&quot;abc&quot;, null)  = false
     * equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
     * equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
     * </pre>
     *
     * @param str1 要比较的字符串1
     * @param str2 要比较的字符串2
     * @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
     */
    public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2)
    {
        return equals(str1, str2, true);
    }
    /**
     * 比较两个字符串是否相等。
     *
     * @param str1       要比较的字符串1
     * @param str2       要比较的字符串2
     * @param ignoreCase 是否忽略大小写
     * @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
     * @since 3.2.0
     */
    public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase)
    {
        if (null == str1)
        {
            // 只有两个都为null才判断相等
            return str2 == null;
        }
        if (null == str2)
        {
            // 字符串2空,字符串1非空,直接false
            return false;
        }
        if (ignoreCase)
        {
            return str1.toString()
                .equalsIgnoreCase(str2.toString());
        }
        else
        {
            return str1.equals(str2);
        }
    }
    /**
     * 创建StringBuilder对象
     *
     * @return StringBuilder对象
     */
    public static StringBuilder builder()
    {
        return new StringBuilder();
    }
    /**
     * 创建StringBuilder对象
     *
     * @param capacity 初始大小
     * @return StringBuilder对象
     */
    public static StringBuilder builder(int capacity)
    {
        return new StringBuilder(capacity);
    }
    /**
     * 创建StringBuilder对象
     *
     * @param strs 初始字符串列表
     * @return StringBuilder对象
     */
    public static StringBuilder builder(CharSequence...strs)
    {
        final StringBuilder sb = new StringBuilder();
        for (CharSequence str: strs)
        {
            sb.append(str);
        }
        return sb;
    }
    /**
     * 创建StringBuilder对象
     *
     * @param sb   初始StringBuilder
     * @param strs 初始字符串列表
     * @return StringBuilder对象
     */
    public static StringBuilder appendBuilder(StringBuilder sb, CharSequence...strs)
    {
        for (CharSequence str: strs)
        {
            sb.append(str);
        }
        return sb;
    }
    /**
     * 获得StringReader
     *
     * @param str 字符串
     * @return StringReader
     */
    public static StringReader getReader(CharSequence str)
    {
        if (null == str)
        {
            return null;
        }
        return new StringReader(str.toString());
    }
    /**
     * 获得StringWriter
     *
     * @return StringWriter
     */
    public static StringWriter getWriter()
    {
        return new StringWriter();
    }
    /**
     * 统计指定内容中包含指定字符的数量
     *
     * @param content       内容
     * @param charForSearch 被统计的字符
     * @return 包含数量
     */
    public static int count(CharSequence content, char charForSearch)
    {
        int count = 0;
        if (isEmpty(content))
        {
            return 0;
        }
        int contentLength = content.length();
        for (int i = 0; i < contentLength; i++)
        {
            if (charForSearch == content.charAt(i))
            {
                count++;
            }
        }
        return count;
    }
    /**
     * 下划线转驼峰
     *
     * @param para 字符串
     * @return String
     */
    public static String underlineToHump(String para)
    {
        StringBuilder result = new StringBuilder();
        String[] a = para.split("_");
        for (String s: a)
        {
            if (result.length() == 0)
            {
                result.append(s.toLowerCase());
            }
            else
            {
                result.append(s.substring(0, 1)
                    .toUpperCase());
                result.append(s.substring(1)
                    .toLowerCase());
            }
        }
        return result.toString();
    }
    /**
     * 驼峰转下划线
     *
     * @param para 字符串
     * @return String
     */
    public static String humpToUnderline(String para)
    {
        para = firstCharToLower(para);
        StringBuilder sb = new StringBuilder(para);
        int temp = 0;
        for (int i = 0; i < para.length(); i++)
        {
            if (Character.isUpperCase(para.charAt(i)))
            {
                sb.insert(i + temp, "_");
                temp += 1;
            }
        }
        return sb.toString()
            .toLowerCase();
    }
    /**
     * 横线转驼峰
     *
     * @param para 字符串
     * @return String
     */
    public static String lineToHump(String para)
    {
        StringBuilder result = new StringBuilder();
        String[] a = para.split("-");
        for (String s: a)
        {
            if (result.length() == 0)
            {
                result.append(s.toLowerCase());
            }
            else
            {
                result.append(s.substring(0, 1)
                    .toUpperCase());
                result.append(s.substring(1)
                    .toLowerCase());
            }
        }
        return result.toString();
    }
    /**
     * 驼峰转横线
     *
     * @param para 字符串
     * @return String
     */
    public static String humpToLine(String para)
    {
        para = firstCharToLower(para);
        StringBuilder sb = new StringBuilder(para);
        int temp = 0;
        for (int i = 0; i < para.length(); i++)
        {
            if (Character.isUpperCase(para.charAt(i)))
            {
                sb.insert(i + temp, "-");
                temp += 1;
            }
        }
        return sb.toString()
            .toLowerCase();
    }
    /**
     * trimToEmpty
     *
     * @param str 字符串
     * @return String
     */
    public static String trimToEmpty(String str)
    {
        return str == null ? "" : str.trim();
    }
    /**
     * 替换是否忽略大小写
     *
     * @param text 字符串
     * @param searchString 旧的字符串
     * @param replacement 新的字符串
     * @param ignoreCase true:忽略,false:不忽略
     * @return String
     */
    public static String replaceIgnoreCase(String text, String searchString, String replacement, boolean ignoreCase)
    {
        return replace(text, searchString, replacement, -1, ignoreCase);
    }
    private static String replace(String text, String searchString, String replacement, int max, boolean ignoreCase)
    {
        if (!isEmpty(text) && !isEmpty(searchString) && replacement != null && max != 0)
        {
            if (ignoreCase)
            {
                searchString = searchString.toLowerCase();
            }
            int start = 0;
            int end = indexOf(text, searchString, start, ignoreCase);
            if (end == -1)
            {
                return text;
            }
            else
            {
                int replLength = searchString.length();
                int increase = replacement.length() - replLength;
                increase = increase < 0 ? 0 : increase;
                increase *= max < 0 ? 16 : (max > 64 ? 64 : max);
                StringBuilder buf;
                for (buf = new StringBuilder(text.length() + increase); end != -1; end = indexOf(text, searchString, start, ignoreCase))
                {
                    buf.append(text, start, end)
                        .append(replacement);
                    start = end + replLength;
                    --max;
                    if (max == 0)
                    {
                        break;
                    }
                }
                buf.append(text, start, text.length());
                return buf.toString();
            }
        }
        else
        {
            return text;
        }
    }
    /**
     * 正则替换字符串
     *
     * @param content 字符串
     * @param pattern 正则表达式
     * @param newString 新的替换字符串
     * @return String
     */
    public static String regReplace(String content, String pattern, String newString)
    {
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(content);
        String result = m.replaceAll(newString);
        return result;
    }
}
View Code

字符串切分类

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 字符串切分器
 *
 * @author Looly
 */
public class StrSpliter
{
    //---------------------------------------------------------------------------------------------- Split by char
    /**
     * 切分字符串路径,仅支持Unix分界符:/
     *
     * @param str 被切分的字符串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > splitPath(String str)
    {
        return splitPath(str, 0);
    }
    /**
     * 切分字符串路径,仅支持Unix分界符:/
     *
     * @param str 被切分的字符串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static String[] splitPathToArray(String str)
    {
        return toArray(splitPath(str));
    }
    /**
     * 切分字符串路径,仅支持Unix分界符:/
     *
     * @param str   被切分的字符串
     * @param limit 限制分片数
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > splitPath(String str, int limit)
    {
        return split(str, StringPool.SLASH, limit, true, true);
    }
    /**
     * 切分字符串路径,仅支持Unix分界符:/
     *
     * @param str   被切分的字符串
     * @param limit 限制分片数
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static String[] splitPathToArray(String str, int limit)
    {
        return toArray(splitPath(str, limit));
    }
    /**
     * 切分字符串
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.2.1
     */
    public static List < String > splitTrim(String str, char separator, boolean ignoreEmpty)
    {
        return split(str, separator, 0, true, ignoreEmpty);
    }
    /**
     * 切分字符串
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > split(String str, char separator, boolean isTrim, boolean ignoreEmpty)
    {
        return split(str, separator, 0, isTrim, ignoreEmpty);
    }
    /**
     * 切分字符串,大小写敏感,去除每个元素两边空白符
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param limit       限制分片数,-1不限制
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > splitTrim(String str, char separator, int limit, boolean ignoreEmpty)
    {
        return split(str, separator, limit, true, ignoreEmpty, false);
    }
    /**
     * 切分字符串,大小写敏感
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param limit       限制分片数,-1不限制
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        return split(str, separator, limit, isTrim, ignoreEmpty, false);
    }
    /**
     * 切分字符串,忽略大小写
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param limit       限制分片数,-1不限制
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.2.1
     */
    public static List < String > splitIgnoreCase(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        return split(str, separator, limit, isTrim, ignoreEmpty, true);
    }
    /**
     * 切分字符串
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param limit       限制分片数,-1不限制
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @param ignoreCase  是否忽略大小写
     * @return 切分后的集合
     * @since 3.2.1
     */
    public static List < String > split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase)
    {
        if (StringUtil.isEmpty(str))
        {
            return new ArrayList < String > (0);
        }
        if (limit == 1)
        {
            return addToList(new ArrayList < String > (1), str, isTrim, ignoreEmpty);
        }
        final ArrayList < String > list = new ArrayList < > (limit > 0 ? limit : 16);
        int len = str.length();
        int start = 0;
        for (int i = 0; i < len; i++)
        {
            if (Objects.equals(separator, str.charAt(i)))
            {
                addToList(list, str.substring(start, i), isTrim, ignoreEmpty);
                start = i + 1;
                //检查是否超出范围(最大允许limit-1个,剩下一个留给末尾字符串)
                if (limit > 0 && list.size() > limit - 2)
                {
                    break;
                }
            }
        }
        return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
    }
    /**
     * 切分字符串为字符串数组
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param limit       限制分片数
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static String[] splitToArray(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        return toArray(split(str, separator, limit, isTrim, ignoreEmpty));
    }
    //---------------------------------------------------------------------------------------------- Split by String
    /**
     * 切分字符串,不忽略大小写
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符串
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > split(String str, String separator, boolean isTrim, boolean ignoreEmpty)
    {
        return split(str, separator, -1, isTrim, ignoreEmpty, false);
    }
    /**
     * 切分字符串,去除每个元素两边空格,忽略大小写
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符串
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.2.1
     */
    public static List < String > splitTrim(String str, String separator, boolean ignoreEmpty)
    {
        return split(str, separator, true, ignoreEmpty);
    }
    /**
     * 切分字符串,不忽略大小写
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符串
     * @param limit       限制分片数
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        return split(str, separator, limit, isTrim, ignoreEmpty, false);
    }
    /**
     * 切分字符串,去除每个元素两边空格,忽略大小写
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符串
     * @param limit       限制分片数
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.2.1
     */
    public static List < String > splitTrim(String str, String separator, int limit, boolean ignoreEmpty)
    {
        return split(str, separator, limit, true, ignoreEmpty);
    }
    /**
     * 切分字符串,忽略大小写
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符串
     * @param limit       限制分片数
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.2.1
     */
    public static List < String > splitIgnoreCase(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        return split(str, separator, limit, isTrim, ignoreEmpty, true);
    }
    /**
     * 切分字符串,去除每个元素两边空格,忽略大小写
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符串
     * @param limit       限制分片数
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.2.1
     */
    public static List < String > splitTrimIgnoreCase(String str, String separator, int limit, boolean ignoreEmpty)
    {
        return split(str, separator, limit, true, ignoreEmpty, true);
    }
    /**
     * 切分字符串
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符串
     * @param limit       限制分片数
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @param ignoreCase  是否忽略大小写
     * @return 切分后的集合
     * @since 3.2.1
     */
    public static List < String > split(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase)
    {
        if (StringUtil.isEmpty(str))
        {
            return new ArrayList < String > (0);
        }
        if (limit == 1)
        {
            return addToList(new ArrayList < String > (1), str, isTrim, ignoreEmpty);
        }
        if (StringUtil.isEmpty(separator))
        {
            return split(str, limit);
        }
        else if (separator.length() == 1)
        {
            return split(str, separator.charAt(0), limit, isTrim, ignoreEmpty, ignoreCase);
        }
        final ArrayList < String > list = new ArrayList < > ();
        int len = str.length();
        int separatorLen = separator.length();
        int start = 0;
        int i = 0;
        while (i < len)
        {
            i = StringUtil.indexOf(str, separator, start, ignoreCase);
            if (i > -1)
            {
                addToList(list, str.substring(start, i), isTrim, ignoreEmpty);
                start = i + separatorLen;
                //检查是否超出范围(最大允许limit-1个,剩下一个留给末尾字符串)
                if (limit > 0 && list.size() > limit - 2)
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }
        return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
    }
    /**
     * 切分字符串为字符串数组
     *
     * @param str         被切分的字符串
     * @param separator   分隔符字符
     * @param limit       限制分片数
     * @param isTrim      是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty 是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static String[] splitToArray(String str, String separator, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        return toArray(split(str, separator, limit, isTrim, ignoreEmpty));
    }
    //---------------------------------------------------------------------------------------------- Split by Whitespace
    /**
     * 使用空白符切分字符串<br>
     * 切分后的字符串两边不包含空白符,空串或空白符串并不做为元素之一
     *
     * @param str   被切分的字符串
     * @param limit 限制分片数
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > split(String str, int limit)
    {
        if (StringUtil.isEmpty(str))
        {
            return new ArrayList < String > (0);
        }
        if (limit == 1)
        {
            return addToList(new ArrayList < String > (1), str, true, true);
        }
        final ArrayList < String > list = new ArrayList < > ();
        int len = str.length();
        int start = 0;
        for (int i = 0; i < len; i++)
        {
            if (StringUtil.isEmpty(str.charAt(i)))
            {
                addToList(list, str.substring(start, i), true, true);
                start = i + 1;
                if (limit > 0 && list.size() > limit - 2)
                {
                    break;
                }
            }
        }
        return addToList(list, str.substring(start, len), true, true);
    }
    /**
     * 切分字符串为字符串数组
     *
     * @param str   被切分的字符串
     * @param limit 限制分片数
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static String[] splitToArray(String str, int limit)
    {
        return toArray(split(str, limit));
    }
    //---------------------------------------------------------------------------------------------- Split by regex
    /**
     * 通过正则切分字符串
     *
     * @param str              字符串
     * @param separatorPattern 分隔符正则{@link Pattern}
     * @param limit            限制分片数
     * @param isTrim           是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty      是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static List < String > split(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        if (StringUtil.isEmpty(str))
        {
            return new ArrayList < String > (0);
        }
        if (limit == 1)
        {
            return addToList(new ArrayList < String > (1), str, isTrim, ignoreEmpty);
        }
        if (null == separatorPattern)
        {
            return split(str, limit);
        }
        final Matcher matcher = separatorPattern.matcher(str);
        final ArrayList < String > list = new ArrayList < > ();
        int len = str.length();
        int start = 0;
        while (matcher.find())
        {
            addToList(list, str.substring(start, matcher.start()), isTrim, ignoreEmpty);
            start = matcher.end();
            if (limit > 0 && list.size() > limit - 2)
            {
                break;
            }
        }
        return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);
    }
    /**
     * 通过正则切分字符串为字符串数组
     *
     * @param str              被切分的字符串
     * @param separatorPattern 分隔符正则{@link Pattern}
     * @param limit            限制分片数
     * @param isTrim           是否去除切分字符串后每个元素两边的空格
     * @param ignoreEmpty      是否忽略空串
     * @return 切分后的集合
     * @since 3.0.8
     */
    public static String[] splitToArray(String str, Pattern separatorPattern, int limit, boolean isTrim, boolean ignoreEmpty)
    {
        return toArray(split(str, separatorPattern, limit, isTrim, ignoreEmpty));
    }
    //---------------------------------------------------------------------------------------------- Split by length
    /**
     * 根据给定长度,将给定字符串截取为多个部分
     *
     * @param str 字符串
     * @param len 每一个小节的长度
     * @return 截取后的字符串数组
     */
    public static String[] splitByLength(String str, int len)
    {
        int partCount = str.length() / len;
        int lastPartCount = str.length() % len;
        int fixPart = 0;
        if (lastPartCount != 0)
        {
            fixPart = 1;
        }
        final String[] strs = new String[partCount + fixPart];
        for (int i = 0; i < partCount + fixPart; i++)
        {
            if (i == partCount + fixPart - 1 && lastPartCount != 0)
            {
                strs[i] = str.substring(i * len, i * len + lastPartCount);
            }
            else
            {
                strs[i] = str.substring(i * len, i * len + len);
            }
        }
        return strs;
    }
    //---------------------------------------------------------------------------------------------------------- Private method start
    /**
     * 将字符串加入List中
     *
     * @param list        列表
     * @param part        被加入的部分
     * @param isTrim      是否去除两端空白符
     * @param ignoreEmpty 是否略过空字符串(空字符串不做为一个元素)
     * @return 列表
     */
    private static List < String > addToList(List < String > list, String part, boolean isTrim, boolean ignoreEmpty)
    {
        part = part.toString();
        if (isTrim)
        {
            part = part.trim();
        }
        if (false == ignoreEmpty || false == part.isEmpty())
        {
            list.add(part);
        }
        return list;
    }
    /**
     * List转Array
     *
     * @param list List
     * @return Array
     */
    private static String[] toArray(List < String > list)
    {
        return list.toArray(new String[list.size()]);
    }
    //---------------------------------------------------------------------------------------------------------- Private method end
}
View Code

获取Token工具类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;


@Slf4j
@Component
public class TokenUtil
{
    @Autowired
    private RestTemplateUtil restTemplateUtil;
    public String getToken(String username, String password, String url)
    {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        //设置参数
        JSONObject json = new JSONObject();
        json.put("username", username);
        json.put("password", password);
        HttpEntity < Object > requestEntity = new HttpEntity < > (json, httpHeaders);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity < String > responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
        String result = responseEntity.getBody();
        log.info(result);
        JSONObject object = JSONObject.parseObject(result);
        Integer code = object.getInteger("code");
        if (code == HttpStatus.OK.value())
        {
            return object.getString("token");
        }
        else
        {
            log.error("获取token失败");
            return "";
        }
    }
}
View Code

 

posted @ 2022-06-06 18:58  佛祖让我来巡山  阅读(73)  评论(0编辑  收藏  举报

佛祖让我来巡山博客站 - 创建于 2018-08-15

开发工程师个人站,内容主要是网站开发方面的技术文章,大部分来自学习或工作,部分来源于网络,希望对大家有所帮助。

Bootstrap中文网