天天看點

整理Java相關的工具類Utils,持續更新中,建議收藏【目前更新至24】

文章目錄

  • ​​1.BigDecimalUtil​​
  • ​​2.CaptchaUtil 圖檔驗證碼工具類​​
  • ​​3.CoordinateTransformUtil 坐标系轉換工具類​​
  • ​​4.DateUtil 日期加減工具類​​
  • ​​5.EmailUtil email發送工具類​​
  • ​​6.EncodeDecodeUtil 加密工具類​​
  • ​​7.GzipUtil 壓縮工具類​​
  • ​​8.HttpClient http遠端調用工具類​​
  • ​​9.JwtUtil jwt工具類​​
  • ​​10.LanguageUtil 語種工具類​​
  • ​​11.MD5 MD5加密工具類​​
  • ​​12.ObjectDeepCopyUtil 對象深度拷貝工具類​​
  • ​​13.OrderNoUtil 訂單号工具類​​
  • ​​14.PoolPrintUtil 線程池列印工具類​​
  • ​​15.RandomUtil 手機驗證碼生成工具類​​
  • ​​16.ResponseEntity 統一結果傳回類​​
  • ​​17.ResponseUtil 結果響應工具類​​
  • ​​18.XmlUtil xml轉換map工具類​​
  • ​​19.RedisExpire緩存有效期​​
  • ​​20.Result操作結果集封裝​​
  • ​​21.ResultUtil傳回結果工具類​​
  • ​​22.Http狀态碼枚舉類​​
  • ​​23.CommonUtil集合判空工具類​​
  • ​​24.gateway身份認證過濾器​​
BigDecimalUtil BigDecimalUtil計算工具類
CaptchaUtil 圖檔驗證碼工具類
CoordinateTransformUtil 坐标系轉換工具類
DateUtil 日期加減工具類
EmailUtil email發送工具類
EncodeDecodeUtil 加密工具類
GzipUtil 壓縮工具類
HttpClient http遠端調用工具類
JwtUtil jwt工具類
LanguageUtil 語種工具類
MD5 MD5加密工具類
ObjectDeepCopyUtil 對象深度拷貝工具類
OrderNoUtil 訂單号工具類
PoolPrintUtil 線程池列印工具類
RandomUtil 手機驗證碼生成工具類
ResponseEntity 統一結果傳回類
ResponseUtil 結果響應工具類
XmlUtil xml轉換map工具類
RedisExpire Redis緩存有效期工具類
Result 操作結果集封裝
ResultUtil 傳回結果工具類
HttpEnum 狀态碼枚舉類
CommonUtil 集合判空工具類

1.BigDecimalUtil

public class BigDecimalUtil {

    /**
     * x, y轉成BigDecimal後相減
     * @param x x值(double類型)
     * @param y y值 (double類型)
     * @return result
     */
    public static double subtract(double x, double y) {
        BigDecimal d1 = BigDecimal.valueOf(x);
        BigDecimal d2 = BigDecimal.valueOf(y);
        return d1.subtract(d2).doubleValue();
    }

    /**
     * x, y轉成BigDecimal後相減,獲得的結果再向上取整
     * @param x x值(double類型)
     * @param y y值 (double類型)
     * @return result
     */
    public static double subtractUp(double x, double y) {
        double value = subtract(x, y);
        return roundUp(value);
    }

    /**
     * x, y轉成BigDecimal後相減,獲得的結果再向下取整
     * @param x x值(double類型)
     * @param y y值 (double類型)
     * @return result
     */
    public static double subtractDown(double x, double y) {
        double value = subtract(x, y);
        return roundDown(value);
    }

    /**
     * x, y轉成BigDecimal後相減
     * @param x x值(double類型)
     * @param y y值 (double類型)
     * @return result
     */
    public static double add(double x, double y) {
        BigDecimal d1 = BigDecimal.valueOf(x);
        BigDecimal d2 = BigDecimal.valueOf(y);
        return d1.add(d2).doubleValue();
    }

    /**
     * x, y轉成BigDecimal後相乘
     * @param x x值(double類型)
     * @param y y值 (double類型)
     * @return result
     */
    public static double multiply(double x, double y) {
        BigDecimal d1 = BigDecimal.valueOf(x);
        BigDecimal d2 = BigDecimal.valueOf(y);
        return d1.multiply(d2).doubleValue();
    }

    /**
     * x, y轉成BigDecimal後相除
     * @param x x值(double類型)
     * @param y y值 (double類型)
     * @return result
     */
    public static double divide(double x, double y, int scale) {
        BigDecimal d1 = BigDecimal.valueOf(x);
        BigDecimal d2 = BigDecimal.valueOf(y);
        return d1.divide(d2, scale).doubleValue();
    }

    /**
     * 向上取整,整數向上取整
     * @param val val
     * @return result
     */
    public static double roundUp(double val) {
        return roundUp(val, 0);
    }


    /**
     * 向上取整,可設定精度
     * @param val val
     * @param scale 精度
     * @return result
     */
    public static double roundUp(double val, int scale) {
        BigDecimal dec = BigDecimal.valueOf(val);
        return dec.setScale(scale, RoundingMode.UP).doubleValue();
    }

    /**
     * 向下取整,可設定精度
     * @param val val
     * @return result
     */
    public static double roundDown(double val) {
        return roundDown(val, 0);
    }

    /**
     * 向下取整,可設定精度
     * @param val val
     * @param scale 精度
     * @return result
     */
    public static double roundDown(double val, int scale) {
        BigDecimal dec = BigDecimal.valueOf(val);
        return dec.setScale(scale, RoundingMode.DOWN).doubleValue();
    }

    /**
     * 四舍五入
     * @param val val
     * @return result
     */
    public static double roundHalfUp(double val) {
        return roundHalfUp(val, 0);
    }

    /**
     * 四舍五入,可設定精度
     * @param val
     * @param scale
     * @return
     */
    public static double roundHalfUp(double val, int scale) {
        BigDecimal dec = BigDecimal.valueOf(val);
        return dec.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

}      

2.CaptchaUtil 圖檔驗證碼工具類

public class CaptchaUtil {

    static char[] chars = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    /**
     * 生成一個位數為count的随機驗證碼
     *
     * @param count
     * @return
     */
    public static String genCaptcha(int count) {
        StringBuilder captcha = new StringBuilder();

        for (int i = 0; i < count; i++) {
            char c = chars[ThreadLocalRandom.current().nextInt(chars.length)];//随機選取一個字母或數字
            captcha.append(c);
        }
        return captcha.toString();
    }

    /**
     * 為一個驗證碼生成一個圖檔
     * <p>
     * 特性:
     * - 顔色随機
     * - 上下位置随機
     * - 左右位置随機,但字元之間不會重疊
     * - 左右随機旋轉一個角度
     * - 避免字元出界
     * - 随機顔色的小字元做背景幹擾
     * - 根據字元大小自動調整圖檔大小、自動計算幹擾字元的個數
     *
     * @param captcha
     * @return
     * @author XuJijun
     */
    public static BufferedImage genCaptchaImg(String captcha) {
        ThreadLocalRandom r = ThreadLocalRandom.current();

        int count = captcha.length();
        int fontSize = 80; //code的字型大小
        int fontMargin = fontSize / 4; //字元間隔
        int width = (fontSize + fontMargin) * count + fontMargin; //圖檔長度
        int height = (int) (fontSize * 1.2); //圖檔高度,根據字型大小自動調整;調整這個系數可以調整字型占圖檔的比例
        int avgWidth = width / count;    //字元平均占位寬度
        int maxDegree = 26;    //最大旋轉度數

        //背景顔色
        Color bkColor = Color.WHITE;
        //驗證碼的顔色
        Color[] catchaColor = {Color.MAGENTA, Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN, Color.ORANGE, Color.PINK};

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        //填充底色為灰白
        g.setColor(bkColor);
        g.fillRect(0, 0, width, height);

        //畫邊框
        g.setColor(Color.WHITE);
        g.drawRect(0, 0, width - 1, height - 1);

        //畫幹擾字母、數字
        int dSize = fontSize / 3; //調整分母大小以調整幹擾字元大小
        Font font = new Font("Fixedsys", Font.PLAIN, dSize);
        g.setFont(font);
        int dNumber = width * height / dSize / dSize;//根據面積計算幹擾字母的個數
        for (int i = 0; i < dNumber; i++) {
            char d_code = chars[r.nextInt(chars.length)];
            g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
            g.drawString(String.valueOf(d_code), r.nextInt(width), r.nextInt(height));
        }

        //開始畫驗證碼:

        // 建立字型
        font = new Font(Font.MONOSPACED, Font.ITALIC | Font.BOLD, fontSize);
        // 設定字型
        g.setFont(font);

        for (int i = 0; i < count; i++) {
            char c = captcha.charAt(i);
            g.setColor(catchaColor[r.nextInt(catchaColor.length)]);//随機選取一種顔色

            //随機旋轉一個角度[-maxDegre, maxDegree]
            int degree = r.nextInt(-maxDegree, maxDegree + 1);

            //偏移系數,和旋轉角度成反比,以避免字元在圖檔中越出邊框
            double offsetFactor = 1 - (Math.abs(degree) / (maxDegree + 1.0));//加上1,避免出現結果為0

            g.rotate(degree * Math.PI / 180); //旋轉一個角度
            int x = (int) (fontMargin + r.nextInt(avgWidth - fontSize) * offsetFactor); //橫向偏移的距離
            int y = (int) (fontSize + r.nextInt(height - fontSize) * offsetFactor); //上下偏移的距離

            g.drawString(String.valueOf(c), x, y); //x,y是字元的左下角,偏離原點的距離!!!

            g.rotate(-degree * Math.PI / 180); //畫完一個字元之後,旋轉回原來的角度
            g.translate(avgWidth, 0);//移動到下一個畫畫的原點
            //System.out.println(c+": x="+x+" y="+y+" degree="+degree+" offset="+offsetFactor);

            //X、Y坐标在合适的範圍内随機,不旋轉:
            //g.drawString(String.valueOf(c), width/count*i+r.nextInt(width/count-fontSize), fontSize+r.nextInt(height-fontSize));
        }

        g.dispose();

        return image;
    }
}      

3.CoordinateTransformUtil 坐标系轉換工具類

public class CoordinateTransformUtil {
    static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    // π
    static double pi = 3.1415926535897932384626;
    // 長半軸
    static double a = 6378245.0;
    // 扁率
    static double ee = 0.00669342162296594323;


    /**
     * 将原本坐标系的經緯度轉換成新的坐标系的經緯度
     * @param newCoordinateType 新坐标系,如baidu,wgs84
     * @param originalCoordinateType 原坐标系,如baidu,wgs84
     * @param lat 原緯度
     * @param lon 原經度
     * @return 新坐标系的經緯度
     */
    public static double[] convertLatLonByCoordinate(String newCoordinateType, String originalCoordinateType, double lat, double lon) {
        if (originalCoordinateType == null) {
            return null;
        }

        boolean bd09ToWgs84 = (originalCoordinateType.equalsIgnoreCase("bd09") || originalCoordinateType.equalsIgnoreCase("baidu")
                && (newCoordinateType.equalsIgnoreCase("google")) || newCoordinateType.equalsIgnoreCase("wgs84"));
        boolean gcj02toWgs84 = (originalCoordinateType.equalsIgnoreCase("gaode") || originalCoordinateType.equalsIgnoreCase("gcj02")
                && (newCoordinateType.equalsIgnoreCase("google")) || newCoordinateType.equalsIgnoreCase("wgs84"));

        boolean wgs84ToBd09 = (originalCoordinateType.equalsIgnoreCase("google") || originalCoordinateType.equalsIgnoreCase("wgs84"))
                && (newCoordinateType.equalsIgnoreCase("bd09") || newCoordinateType.equalsIgnoreCase("baidu"));
        boolean gcj02ToBd09 = (originalCoordinateType.equalsIgnoreCase("gaode") || originalCoordinateType.equalsIgnoreCase("gcj02"))
                && (newCoordinateType.equalsIgnoreCase("bd09") || newCoordinateType.equalsIgnoreCase("baidu"));

        boolean wgs84ToGcj02 = (originalCoordinateType.equalsIgnoreCase("google") || originalCoordinateType.equalsIgnoreCase("wgs84"))
                && (newCoordinateType.equalsIgnoreCase("gaode") || newCoordinateType.equalsIgnoreCase("gcj02"));
        boolean bd09ToGcj02 = (originalCoordinateType.equalsIgnoreCase("bd09") || originalCoordinateType.equalsIgnoreCase("baidu"))
                && (newCoordinateType.equalsIgnoreCase("gaode") || newCoordinateType.equalsIgnoreCase("gcj02"));

        if (originalCoordinateType.equals(newCoordinateType)) {
            return new double[]{lat, lon};
        } else if (bd09ToWgs84) {
            return bd09towgs84(lon, lat);
        } else if (gcj02toWgs84) {
            return gcj02towgs84(lon, lat);
        } else if (wgs84ToBd09) {
            return wgs84tobd09(lon, lat);
        } else if (gcj02ToBd09) {
            return gcj02tobd09(lon, lat);
        } else if (wgs84ToGcj02) {
            return wgs84togcj02(lon, lat);
        } else if (bd09ToGcj02) {
            return bd09togcj02(lon, lat);
        } else {
            return null;
        }
    }

    /**
     * 百度坐标系(BD-09)轉WGS坐标
     *
     * @param lng 百度坐标緯度
     * @param lat 百度坐标經度
     * @return WGS84坐标數組
     */
    public static double[] bd09towgs84(double lng, double lat) {
        double[] gcj = bd09togcj02(lng, lat);
        double[] wgs84 = gcj02towgs84(gcj[0], gcj[1]);
        return wgs84;
    }

    /**
     * WGS坐标轉百度坐标系(BD-09)
     *
     * @param lng WGS84坐标系的經度
     * @param lat WGS84坐标系的緯度
     * @return 百度坐标數組
     */
    public static double[] wgs84tobd09(double lng, double lat) {
        double[] gcj = wgs84togcj02(lng, lat);
        double[] bd09 = gcj02tobd09(gcj[0], gcj[1]);
        return bd09;
    }

    /**
     * 火星坐标系(GCJ-02)轉百度坐标系(BD-09)
     *
     * 谷歌、高德——>百度
     * @param lng 火星坐标經度
     * @param lat 火星坐标緯度
     * @return 百度坐标數組
     */
    public static double[] gcj02tobd09(double lng, double lat) {
        double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_pi);
        double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_pi);
        double bd_lng = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new double[] { bd_lng, bd_lat };
    }

    /**
     * 百度坐标系(BD-09)轉火星坐标系(GCJ-02)
     *
     * 百度——>谷歌、高德
     * @param bd_lon 百度坐标緯度
     * @param bd_lat 百度坐标經度
     * @return 火星坐标數組
     */
    public static double[] bd09togcj02(double bd_lon, double bd_lat) {
        double x = bd_lon - 0.0065;
        double y = bd_lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
        double gg_lng = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        return new double[] { gg_lng, gg_lat };
    }

    /**
     * WGS84轉GCJ02(火星坐标系)
     *
     * @param lng WGS84坐标系的經度
     * @param lat WGS84坐标系的緯度
     * @return 火星坐标數組
     */
    public static double[] wgs84togcj02(double lng, double lat) {
        if (out_of_china(lng, lat)) {
            return new double[] { lng, lat };
        }
        double dlat = transformlat(lng - 105.0, lat - 35.0);
        double dlng = transformlng(lng - 105.0, lat - 35.0);
        double radlat = lat / 180.0 * pi;
        double magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        double sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);
        double mglat = lat + dlat;
        double mglng = lng + dlng;
        return new double[] { mglng, mglat };
    }

    /**
     * GCJ02(火星坐标系)轉GPS84
     *
     * @param lng 火星坐标系的經度
     * @param lat 火星坐标系緯度
     * @return WGS84坐标數組
     */
    public static double[] gcj02towgs84(double lng, double lat) {
        if (out_of_china(lng, lat)) {
            return new double[] { lng, lat };
        }
        double dlat = transformlat(lng - 105.0, lat - 35.0);
        double dlng = transformlng(lng - 105.0, lat - 35.0);
        double radlat = lat / 180.0 * pi;
        double magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        double sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);
        double mglat = lat + dlat;
        double mglng = lng + dlng;
        return new double[] { lng * 2 - mglng, lat * 2 - mglat };
    }

    /**
     * 緯度轉換
     *
     * @param lng
     * @param lat
     * @return
     */
    public static double transformlat(double lng, double lat) {
        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
        ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(lat / 12.0 * pi) + 320 * Math.sin(lat * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    /**
     * 經度轉換
     *
     * @param lng
     * @param lat
     * @return
     */
    public static double transformlng(double lng, double lat) {
        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
        ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lng * pi) + 40.0 * Math.sin(lng / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(lng / 12.0 * pi) + 300.0 * Math.sin(lng / 30.0 * pi)) * 2.0 / 3.0;
        return ret;
    }

    /**
     * 判斷是否在國内,不在國内不做偏移
     *
     * @param lng
     * @param lat
     * @return
     */
    public static boolean out_of_china(double lng, double lat) {
        if (lng < 72.004 || lng > 137.8347) {
            return true;
        } else if (lat < 0.8293 || lat > 55.8271) {
            return true;
        }
        return false;
    }

}      

4.DateUtil 日期加減工具類

public class DateUtil {

    private static final String dateFormat = "yyyy-MM-dd";

    /**
     * 格式化日期
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(date);

    }

    /**
     * 在日期date上增加amount天 。
     *
     * @param date   處理的日期,非null
     * @param amount 要加的天數,可能為負數
     */
    public static Date addDays(Date date, int amount) {
        Calendar now =Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.DATE,now.get(Calendar.DATE)+amount);
        return now.getTime();
    }

    public static void main(String[] args) {
        System.out.println(DateUtil.formatDate(new Date()));
        System.out.println(DateUtil.formatDate(DateUtil.addDays(new Date(), -1)));
    }
}      

5.EmailUtil email發送工具類

public class EmailUtil {

    private static Session session;
    private static String  user;

    private MimeMessage msg;
    private String      text;
    private String      html;
    private List<MimeBodyPart> attachments = new ArrayList<MimeBodyPart>();

    private EmailUtil() {
    }

    public static Properties defaultConfig(Boolean debug) {
        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.debug", "false");
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.debug", null != debug ? debug.toString() : "false");
        props.put("mail.smtp.timeout", "10000");
        props.put("mail.smtp.port", "465");
        return props;
    }

    /**
     * smtp entnterprise qq
     *
     * @param debug
     * @return
     */
    public static Properties SMTP_ENT_QQ(boolean debug) {
        Properties props = defaultConfig(debug);
        props.put("mail.smtp.host", "smtp.exmail.qq.com");
        return props;
    }

    /**
     * smtp qq
     *
     * @param debug enable debug
     * @return
     */
    public static Properties SMTP_QQ(boolean debug) {
        Properties props = defaultConfig(debug);
        props.put("mail.smtp.host", "smtp.qq.com");
        return props;
    }

    /**
     * smtp 163
     *
     * @param debug enable debug
     * @return
     */
    public static Properties SMTP_163(Boolean debug) {
        Properties props = defaultConfig(debug);
        props.put("mail.smtp.host", "smtp.163.com");
        return props;
    }

    /**
     * config username and password
     *
     * @param props    email property config
     * @param username email auth username
     * @param password email auth password
     */
    public static void config(Properties props, final String username, final String password) {
        props.setProperty("username", username);
        props.setProperty("password", password);
        config(props);
    }

    public static void config(Properties props) {
        final String username = props.getProperty("username");
        final String password = props.getProperty("password");
        user = username;
        session = Session.getInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
    }

    /**
     * set email subject
     *
     * @param subject subject title
     * @return
     * @throws MessagingException
     */
    public static EmailUtil subject(String subject) throws MessagingException {
        EmailUtil emailUtil = new EmailUtil();
        emailUtil.msg = new MimeMessage(session);
        emailUtil.msg.setSubject(subject, "UTF-8");
        return emailUtil;
    }

    /**
     * set email from
     *
     * @param nickName from nickname
     * @return
     * @throws MessagingException
     */
    public EmailUtil from(String nickName) throws MessagingException {
        return from(nickName, user);
    }

    /**
     * set email nickname and from user
     *
     * @param nickName
     * @param from
     * @return
     * @throws MessagingException
     */
    public EmailUtil from(String nickName, String from) throws MessagingException {
        try {
            nickName = MimeUtility.encodeText(nickName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        msg.setFrom(new InternetAddress(nickName + " <" + from + ">"));
        return this;
    }

    public EmailUtil replyTo(String... replyTo) throws MessagingException {
        String result = Arrays.asList(replyTo).toString().replaceAll("(^\\[|\\]$)", "").replace(", ", ",");
        msg.setReplyTo(InternetAddress.parse(result));
        return this;
    }

    public EmailUtil replyTo(String replyTo) throws MessagingException {
        msg.setReplyTo(InternetAddress.parse(replyTo.replace(";", ",")));
        return this;
    }

    public EmailUtil to(String... to) throws Exception {
        return addRecipients(to, Message.RecipientType.TO);
    }

    public EmailUtil to(String to) throws MessagingException {
        return addRecipient(to, Message.RecipientType.TO);
    }

    public EmailUtil cc(String... cc) throws MessagingException {
        return addRecipients(cc, Message.RecipientType.CC);
    }

    public EmailUtil cc(String cc) throws MessagingException {
        return addRecipient(cc, Message.RecipientType.CC);
    }

    public EmailUtil bcc(String... bcc) throws MessagingException {
        return addRecipients(bcc, Message.RecipientType.BCC);
    }

    public EmailUtil bcc(String bcc) throws MessagingException {
        return addRecipient(bcc, Message.RecipientType.BCC);
    }

    private EmailUtil addRecipients(String[] recipients, Message.RecipientType type) throws MessagingException {
        String result = Arrays.asList(recipients).toString().replace("(^\\[|\\]$)", "").replace(", ", ",");
        msg.setRecipients(type, InternetAddress.parse(result));
        return this;
    }

    private EmailUtil addRecipient(String recipient, Message.RecipientType type) throws MessagingException {
        msg.setRecipients(type, InternetAddress.parse(recipient.replace(";", ",")));
        return this;
    }

    public EmailUtil text(String text) {
        this.text = text;
        return this;
    }

    public EmailUtil html(String html) {
        this.html = html;
        return this;
    }

    public EmailUtil attach(File file) throws MessagingException {
        attachments.add(createAttachment(file, null));
        return this;
    }

    public EmailUtil attach(File file, String fileName) throws MessagingException {
        attachments.add(createAttachment(file, fileName));
        return this;
    }

    private MimeBodyPart createAttachment(File file, String fileName) throws MessagingException {
        MimeBodyPart   attachmentPart = new MimeBodyPart();
        FileDataSource fds            = new FileDataSource(file);
        attachmentPart.setDataHandler(new DataHandler(fds));
        try {
            attachmentPart.setFileName(null == fileName ? MimeUtility.encodeText(fds.getName()) : MimeUtility.encodeText(fileName));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return attachmentPart;
    }

    public void send() throws MessagingException {
        if (text == null && html == null)
            throw new NullPointerException("At least one context has to be provided: Text or Html");

        MimeMultipart cover;
        boolean       usingAlternative = false;
        boolean       hasAttachments   = attachments.size() > 0;

        if (text != null && html == null) {
            // TEXT ONLY
            cover = new MimeMultipart("mixed");
            cover.addBodyPart(textPart());
        } else if (text == null && html != null) {
            // HTML ONLY
            cover = new MimeMultipart("mixed");
            cover.addBodyPart(htmlPart());
        } else {
            // HTML + TEXT
            cover = new MimeMultipart("alternative");
            cover.addBodyPart(textPart());
            cover.addBodyPart(htmlPart());
            usingAlternative = true;
        }

        MimeMultipart content = cover;
        if (usingAlternative && hasAttachments) {
            content = new MimeMultipart("mixed");
            content.addBodyPart(toBodyPart(cover));
        }

        for (MimeBodyPart attachment : attachments) {
            content.addBodyPart(attachment);
        }

        msg.setContent(content);
        msg.setSentDate(new Date());
        Transport.send(msg);
    }

    private MimeBodyPart toBodyPart(MimeMultipart cover) throws MessagingException {
        MimeBodyPart wrap = new MimeBodyPart();
        wrap.setContent(cover);
        return wrap;
    }

    private MimeBodyPart textPart() throws MessagingException {
        MimeBodyPart bodyPart = new MimeBodyPart();
        bodyPart.setText(text);
        return bodyPart;
    }

    private MimeBodyPart htmlPart() throws MessagingException {
        MimeBodyPart bodyPart = new MimeBodyPart();
        bodyPart.setContent(html, "text/html; charset=utf-8");
        return bodyPart;
    }

}      

6.EncodeDecodeUtil 加密工具類

public class EncodeDecodeUtil {

    private static final char[] HEX = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static final String DEFAULT_CHARSET = "utf-8";


    /**
     * 對字元串進行MD5加密
     * @param str 待加密字元串
     * @return 加密後的字元串
     */
    public static String encodeWithMD5(String str) {
        return encode("MD5", str);
    }

    /**
     * 對字元串進行SHA1加密
     * @param str 待加密字元串
     * @return 加密後的字元串
     */
    public static String encodeWithSHA1(String str) {
        return encode("SHA1", str);
    }

    /**
     * 對字元串進行SHA-256加密
     * @param str 待加密字元串
     * @return 加密後的字元串
     */
    public static String encodeWithSHA256(String str) {
        return encode("SHA-256", str);
    }

    /**
     * 通過加密算法加密字元串
     */
    public static String encode(String algorithm, String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public static String encodeBase64(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        try {
            return Base64.getEncoder().encodeToString(str.getBytes(DEFAULT_CHARSET));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String decodeBase64(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        try {
            byte[] bytes = Base64.getDecoder().decode(str);
            return new String(bytes, DEFAULT_CHARSET);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String decodeUrl(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        try {
            return java.net.URLDecoder.decode(str, "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String encodeUrl(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        try {
            return java.net.URLEncoder.encode(str, "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文轉換成十六進制的字元串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }

}      

7.GzipUtil 壓縮工具類

public class GzipUtil {

    private static Logger logger = LoggerFactory.getLogger(GZIPUtil.class);
    public static final String GZIP_ENCODE_UTF_8 = "UTF-8";

    /**
     * 字元串壓縮為GZIP位元組數組
     *
     * @param str
     * @return
     */
    public static byte[] compress(String str) {
        return compress(str, GZIP_ENCODE_UTF_8);
    }

    /**
     * 字元串壓縮為GZIP位元組數組
     *
     * @param str
     * @param encoding
     * @return
     */
    public static byte[] compress(String str, String encoding) {
        if (str == null || str.length() == 0) {
            return null;
        }
        byte[] bytes = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            GZIPOutputStream gzip;
            try {
                gzip = new GZIPOutputStream(out);
                gzip.write(str.getBytes(encoding));
                gzip.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
            bytes = out.toByteArray();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }

        return bytes;
    }

    public static byte[] compress(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        byte[] byteArr = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            GZIPOutputStream gzip = null;
            try {
                gzip = new GZIPOutputStream(out);
                gzip.write(bytes);

            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }finally {
                if(gzip!=null){
                     gzip.close();
                }
            }
            byteArr = out.toByteArray();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return byteArr;
    }

    /**
     * GZIP解壓縮
     *
     * @param bytes
     * @return
     */
    public static byte[] uncompress(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        byte[] byteArr = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            ByteArrayInputStream in = new ByteArrayInputStream(bytes);
            GZIPInputStream ungzip = new GZIPInputStream(in);
            try {
                byte[] buffer = new byte[256];
                int n;
                while ((n = ungzip.read(buffer)) >= 0) {
                    out.write(buffer, 0, n);
                }
                in.close();

            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }finally {
                  ungzip.close();
            }
            byteArr = out.toByteArray();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return byteArr;
    }

    /**
     * @param bytes
     * @return
     */
    public static String uncompress2Str(byte[] bytes) {
        return uncompress2Str(bytes, GZIP_ENCODE_UTF_8);
    }

    /**
     * @param bytes
     * @param encoding
     * @return
     */
    public static String uncompress2Str(byte[] bytes, String encoding) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        String str = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            ByteArrayInputStream in = new ByteArrayInputStream(bytes);
            try {
                GZIPInputStream ungzip = new GZIPInputStream(in);
                byte[] buffer = new byte[256];
                int n;
                while ((n = ungzip.read(buffer)) >= 0) {
                    out.write(buffer, 0, n);
                }
                in.close();
                ungzip.close();
                str = out.toString(encoding);
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return str;
    }
}      

8.HttpClient http遠端調用工具類

//遠端調用工具類
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class HttpClient {
  private String url;
  private Map<String, String> param;
  private int statusCode;
  private String content;
  private String xmlParam;
  private boolean isHttps;

  public boolean isHttps() {
    return isHttps;
  }

  public void setHttps(boolean isHttps) {
    this.isHttps = isHttps;
  }

  public String getXmlParam() {
    return xmlParam;
  }

  public void setXmlParam(String xmlParam) {
    this.xmlParam = xmlParam;
  }

  public HttpClient(String url, Map<String, String> param) {
    this.url = url;
    this.param = param;
  }

  public HttpClient(String url) {
    this.url = url;
  }

  public void setParameter(Map<String, String> map) {
    param = map;
  }

  public void addParameter(String key, String value) {
    if (param == null)
      param = new HashMap<String, String>();
    param.put(key, value);
  }

  public void post() throws ClientProtocolException, IOException {
    HttpPost http = new HttpPost(url);
    setEntity(http);
    execute(http);
  }

  public void put() throws ClientProtocolException, IOException {
    HttpPut http = new HttpPut(url);
    setEntity(http);
    execute(http);
  }

  public void get() throws ClientProtocolException, IOException {
    if (param != null) {
      StringBuilder url = new StringBuilder(this.url);
      boolean isFirst = true;
      for (String key : param.keySet()) {
        if (isFirst)
          url.append("?");
        else
          url.append("&");
        url.append(key).append("=").append(param.get(key));
      }
      this.url = url.toString();
    }
    HttpGet http = new HttpGet(url);
    execute(http);
  }

  /**
   * set http post,put param
   */
  private void setEntity(HttpEntityEnclosingRequestBase http) {
    if (param != null) {
      List<NameValuePair> nvps = new LinkedList<NameValuePair>();
      for (String key : param.keySet())
        nvps.add(new BasicNameValuePair(key, param.get(key))); // 參數
      http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 設定參數
    }
    if (xmlParam != null) {
      http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
    }
  }

  private void execute(HttpUriRequest http) throws ClientProtocolException,
      IOException {
    CloseableHttpClient httpClient = null;
    try {
      if (isHttps) {
        SSLContext sslContext = new SSLContextBuilder()
            .loadTrustMaterial(null, new TrustStrategy() {
              // 信任所有
              public boolean isTrusted(X509Certificate[] chain,
                  String authType)
                  throws CertificateException {
                return true;
              }
            }).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
            sslContext);
        httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
            .build();
      } else {
        httpClient = HttpClients.createDefault();
      }
      CloseableHttpResponse response = httpClient.execute(http);
      try {
        if (response != null) {
          if (response.getStatusLine() != null)
            statusCode = response.getStatusLine().getStatusCode();
          HttpEntity entity = response.getEntity();
          // 響應内容
          content = EntityUtils.toString(entity, Consts.UTF_8);
        }
      } finally {
        response.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      httpClient.close();
    }
  }

  public int getStatusCode() {
    return statusCode;
  }

  public String getContent() throws ParseException, IOException {
    return content;
  }

}      

9.JwtUtil jwt工具類

public class JwtUtils {
    public static final long EXPIRATION = 1000 * 60 * 60 * 24;
    public static final String SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";

    /**
     * 根據使用者id和nickname生成一個token
     * @param id
     * @param nickname
     * @return
     */
    public static String getToken(String id, String nickname) {
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject("online-encourage")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
                .claim("id", id)
                .claim("nickname", nickname)
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();
    }

    /**
     * 判斷token是否過期
     * @param token
     * @return
     */
    public static boolean isExpiration(String token) {
        if (StringUtils.isEmpty(token)) {
            return false;
        }
        Date expiration = getClaimByToken(token).getExpiration();
        return expiration.before(new Date());
    }

    /**
     * 解析token
     * @param token
     * @return
     */
    public static Claims getClaimByToken(String token) {
        return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
    }

    /**
     * 擷取token并解析--得到使用者id
     * @param request
     * @return
     */
    public static String getUserIdByToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        System.out.println("token為:--->>>>>>>>>>>>>>"+token);
        if (StringUtils.isEmpty(token)) {
            return "";
        }
        return (String) getClaimByToken(token).get("id");
    }
}      

10.LanguageUtil 語種工具類

public class LanguageUtil {


    /**
     * 是否隻有數字
     */
    public static boolean isNumeric(String str) {
        return str != null && str.length() > 0 && Pattern.matches("[0-9]*", str);
    }

    /**
     * 是否隻有字母
     */
    public static boolean isOnlyLetter(String str) {
        return str != null && str.length() > 0 && Pattern.matches("^[A-Za-z]+$", str);
    }

    /**
     * 是否隻有字母和空格
     */
    public static boolean isLetter(String str) {
        return str != null && str.length() > 0 && Pattern.matches("^[A-Za-z\\u0020]+$", str);
    }

    /**
     * 是否隻有漢字和空格
     */
    public static boolean isChinese(String str) {
        return str != null && str.length() > 0 && Pattern.matches("^[\\u4e00-\\u9fa5\\u0020]+$", str);
    }

    /**
     * 是否隻有英文和數字
     */
    public static boolean isLetterAndNumber(String str) {
        return str != null && str.length() > 0 && Pattern.matches("^[0-9A-Za-z\\u0020]+$", str);
    }

    /**
     * 是否隻有中文和數字
     */
    public static boolean isChineseAndNumber(String str) {
        return str != null && str.length() > 0 && Pattern.matches("^[0-9\\u4e00-\\u9fa5\\u0020]+$", str);
    }

    /**
     * 是否隻有韓文和數字
     */
    public static boolean isKoreanAndNumber(String str) {
        return str != null && str.length() > 0 && Pattern.matches("^[0-9\\uac00-\\ud7a3\\u0020]+$", str);
    }

    /**
     * 是否隻有日文和數字
     */
    public static boolean isJapanAndNumber(String str) {
        return str != null && str.length() > 0 && Pattern.matches("^[0-9\\u0800-\\u4e00\\u0020]+$", str);
    }

}      

11.MD5 MD5加密工具類

public final class MD5 {

    public static String encrypt(String strSrc) {
        try {
            char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                    '9', 'a', 'b', 'c', 'd', 'e', 'f' };
            byte[] bytes = strSrc.getBytes();
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(bytes);
            bytes = md.digest();
            int j = bytes.length;
            char[] chars = new char[j * 2];
            int k = 0;
            for (int i = 0; i < bytes.length; i++) {
                byte b = bytes[i];
                chars[k++] = hexChars[b >>> 4 & 0xf];
                chars[k++] = hexChars[b & 0xf];
            }
            return new String(chars);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException("MD5加密出錯!!+" + e);
        }
    }

}      

12.ObjectDeepCopyUtil 對象深度拷貝工具類

public class ObjectDeepCopyUtil {

    /**
     * 單個對象的深拷貝,srcObj對應的需實作java.io.Serializable接口
     * @param srcObj obj
     * @return new  obj
     */
    public static Object depthClone(Object srcObj) {
        Object cloneObj = null;
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream oo = new ObjectOutputStream(out);
            oo.writeObject(srcObj);
            ByteArrayInputStream in = new ByteArrayInputStream(
                    out.toByteArray());
            ObjectInputStream oi = new ObjectInputStream(in);
            cloneObj = oi.readObject();
        } catch (Exception ex) {
            return null;
        }
        return cloneObj;
    }

    /**
     * 多個對象的深拷貝,srcObj對應的需實作java.io.Serializable接口
     * @param list obj
     * @return new list obj
     */
    public static <T> List<T> listDepthClone(List<T> list) {
        List<T> newList = new ArrayList<>();
        for (Object item : list) {
            if (item == null) {
                continue;
            }
            Object val = depthClone(item);
            if (val != null) {
                newList.add((T) val);
            }
        }
        return newList;
    }

}      

13.OrderNoUtil 訂單号工具類

public class OrderNoUtil {

    /**日期+随機數拼接 ---保證訂單号唯一
     * 擷取訂單号
     * @return
     */
    public static String getOrderNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String newDate = sdf.format(new Date());
        String result = "";
        Random random = new Random();
        for (int i = 0; i < 3; i++) {
            result += random.nextInt(10);
        }
        return newDate + result;
    }

}      

14.PoolPrintUtil 線程池列印工具類

public class PoolPrintUtil {

    /**
     * 列印線程池狀态
     * @param executor 線程池
     * @param logger logger
     */
    public void printThreadPoolStatus(ThreadPoolExecutor executor, Logger logger) {
        int poolSize = executor.getPoolSize();
        int corePoolSize = executor.getCorePoolSize();
        int activeCount = executor.getActiveCount();
        long completedTaskCount = executor.getCompletedTaskCount();
        long taskCount = executor.getTaskCount();
        int queueCount = executor.getQueue().size();
        int largestPoolSize = executor.getLargestPoolSize();
        int maximumPoolSize = executor.getMaximumPoolSize();
        long time = executor.getKeepAliveTime(TimeUnit.MILLISECONDS);
        boolean isShutDown = executor.isShutdown();
        boolean isTerminated = executor.isTerminated();

        String info = String.format("初始線程數:%s、核心線程數:%s、正在執行的任務數量:%s、已完成任務數量:%s、任務總數:%s、" +
                "隊列裡緩存的任務數量:%s、池中存在的最大線程數:%s、最大允許的線程數:%s、線程空閑時間:%s、線程池是否關閉:%s、" +
                "線程池是否終止:%s", poolSize, corePoolSize, activeCount, completedTaskCount, taskCount, queueCount,
                largestPoolSize, maximumPoolSize, time, isShutDown, isTerminated);
        logger.info(info);
    }

    public void printThreadPoolStatus(Logger logger, ThreadPoolExecutor... executors) {
        for (int i=0; i< executors.length; i++) {
            printThreadPoolStatus(executors[i], logger);
        }
    }

}      

15.RandomUtil 手機驗證碼生成工具類

//用于生成四位或者六位随機數,多用于驗證碼
public class RandomUtil {

    private static final Random random = new Random();

    private static final DecimalFormat fourdf = new DecimalFormat("0000");

    private static final DecimalFormat sixdf = new DecimalFormat("000000");

    public static String getFourBitRandom() {
        return fourdf.format(random.nextInt(10000));
    }

    public static String getSixBitRandom() {
        return sixdf.format(random.nextInt(1000000));
    }

    /**
     * 給定數組,抽取n個資料
     *
     * @param list
     * @param n
     * @return
     */
    public static ArrayList getRandom(List list, int n) {

        Random random = new Random();
        HashMap<Object, Object> hashMap = new HashMap<Object, Object>();
        // 生成随機數字并存入HashMap
        for (int i = 0; i < list.size(); i++) {
            int number = random.nextInt(100) + 1;
            hashMap.put(number, i);
        }
        // 從HashMap導入數組
        Object[] robjs = hashMap.values().toArray();
        ArrayList r = new ArrayList();
        // 周遊數組并列印資料
        for (int i = 0; i < n; i++) {
            r.add(list.get((int) robjs[i]));
            System.out.print(list.get((int) robjs[i]) + "\t");
        }
        System.out.print("\n");
        return r;
    }
}      

16.ResponseEntity 統一結果傳回類

@Data
@Accessors(chain = true)
@ApiModel(value = "統一結果傳回類")
public class ResponseEntity {
    @ApiModelProperty(value = "是否成功")
    private Boolean success;

    @ApiModelProperty(value = "狀态碼")
    private Integer code;

    @ApiModelProperty(value = "傳回消息")
    private String msg;

    @ApiModelProperty(value = "傳回資料")
    private Map<String, Object> data = new HashMap<>();

    private ResponseEntity() {}

    public static ResponseEntity ok() {
        return new ResponseEntity()
                .setSuccess(true)
                .setCode(ResultCode.SUCCESS_CODE)
                .setMsg("成功");
    }

    public static ResponseEntity error() {
        return new ResponseEntity()
                .setSuccess(false)
                .setCode(ResultCode.FAIL_CODE)
                .setMsg("失敗");
    }

//    鍊式程式設計
    public ResponseEntity success(Boolean success) {
        this.setSuccess(success);
        return this;
    }
    public ResponseEntity code(Integer code) {
        this.setCode(code);
        return this;
    }
    public ResponseEntity msg(String msg) {
        this.setMsg(msg);
        return this;
    }
    public ResponseEntity data(String key, Object val) {
        this.data.put(key, val);
        return this;
    }
}      

17.ResponseUtil 結果響應工具類

public class ResponseUtil {

    public static void out(HttpServletResponse response, ResponseEntity r) {
        ObjectMapper mapper = new ObjectMapper();
        response.setStatus(HttpStatus.OK.value());
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        try {
            mapper.writeValue(response.getWriter(), r);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}      

18.XmlUtil xml轉換map工具類

public class XmlUtils {
  /**
   * 将xml string 轉化為map
   * 
   * @param xmlDoc
   * @return
   * @throws IOException
   * @throws JDOMException
   */
  @SuppressWarnings("unchecked")
  public static Map<String, Object> xmlToMap(String xmlDoc) throws JDOMException, IOException {
    // 建立一個新的字元串
    StringReader read = new StringReader(xmlDoc);
    // 建立新的輸入源SAX 解析器将使用 InputSource 對象來确定如何讀取 XML 輸入
    InputSource source = new InputSource(read);
    // 建立一個新的SAXBuilder
    SAXBuilder sb = new SAXBuilder();

    Map<String, Object> xmlMap = new HashMap<String, Object>();

    Document doc = sb.build(source); // 通過輸入源構造一個Document
    Element root = doc.getRootElement(); // 取的根元素

    List<Element> cNodes = root.getChildren(); // 得到根元素所有子元素的集合(根元素的子節點,不包括孫子節點)
    Element et = null;
    for (int i = 0; i < cNodes.size(); i++) {
      et = (Element) cNodes.get(i); // 循環依次得到子元素
      xmlMap.put(et.getName(), et.getText());
    }
    return xmlMap;
  }

  /**
   * 将xml string 轉化為map
   *
   * @param xmlDoc
   * @return
   * @throws IOException
   * @throws JDOMException
   */
  @SuppressWarnings("unchecked")
  public static Map<String, Object> secondLevelXmlToMap(String xmlDoc) throws JDOMException, IOException {
    // 建立一個新的字元串
    StringReader read = new StringReader(xmlDoc);
    // 建立新的輸入源SAX 解析器将使用 InputSource 對象來确定如何讀取 XML 輸入
    InputSource source = new InputSource(read);
    // 建立一個新的SAXBuilder
    SAXBuilder sb = new SAXBuilder();

    Map<String, Object> xmlMap = new HashMap<String, Object>();

    Document doc = sb.build(source); // 通過輸入源構造一個Document
    Element root = doc.getRootElement(); // 取的根元素

    List<Element> cNodes = root.getChildren(); // 得到根元素所有子元素的集合(根元素的子節點,不包括孫子節點)
    Element et = null;
    for (int i = 0; i < cNodes.size(); i++) {
      et = (Element) cNodes.get(i); // 循環依次得到子元素
      List<Element> etChildrens = et.getChildren();
      for (int j = 0 ; j < etChildrens.size() ; j++){
        Element ChildrenEt = (Element) etChildrens.get(j); // 循環依次得到子元素
        xmlMap.put(ChildrenEt.getName(), ChildrenEt.getText());
      }
    }
    return xmlMap;
  }
}      

19.RedisExpire緩存有效期

/**
 * Redis 緩存有效時間(機關:秒)
 */
public class RedisExpire {

    // 1分鐘
    public static final long MINUTE = 60;
    // 2分鐘 60*2
    public static final long MINUTE_TWO = 120;
    // 3分鐘 60*3
    public static final long MINUTE_THR = 180;
    // 5分鐘 60*5
    public static final long MINUTE_FIV = 300;
    // 10分鐘 60*10
    public static final long MINUTE_TEN = 600;
    // 20分鐘
    public static final long MINUTE_TWENTY = 1200;
    // 30分鐘 60*30
    public static final long MINUTE_THIRTY = 1800;
    // 1小時 60*60*1
    public static final long HOUR = 3600;
    // 2小時  60*60*2
    public static final long HOUR_TWO = 7200;
    // 4小時
    public static final long HOUR_FOUR = 14400;
    // 1天 60*60*24
    public static final long DAY = 86400;
    // 2天 60*60*24*2
    public static final long DAY_TWO = 172800;
    // 1周 60*60*24*7
    public static final long WEEK = 604800;
    // 1月 60*60*24*30
    public static final long MONTH = 2592000;
    // 1年 60*60*24*365
    public static final long YEAR = 31536000;

}      

20.Result操作結果集封裝

public class Result<T>  implements Serializable {

    private static final long serialVersionUID = 1L;
    
    private int code;
    private String msg;
    private T data;

    public Result(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    public Result(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Result() {

    }

    /**
     * 建構消息内容
     * @param msg
     * @return
     */
    public Result buildMessage(String msg){
        this.setMsg(msg);
        return this;
    }

    /**
     * 建構消息data的值,key預設為data
     * @param obj data值
     * @return
     */
    public Result buildData(T obj){
        this.setData(obj);
        return this;

    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}      

21.ResultUtil傳回結果工具類

/**
 * 傳回結果工具類
 */
public class ResultUtil {

    /**
     * 請求成功
     * @return
     */
    public static Result success() {
        return new Result(HttpCodeEnum.OK.getCode(),HttpCodeEnum.OK.getMessage());
    }

    /**
     * 請求成功(無消息)
     * @return
     */
    public static Result successAndNoMsg() {
        return new Result(HttpCodeEnum.OK.getCode(),"");
    }

    /**
     * 成功請求
     *
     * @param data
     * @return
     */
    public static Result success(Object data) {
        return new Result(HttpCodeEnum.OK.getCode(), HttpCodeEnum.OK.getMessage() , data);
    }

    /**
     * 成功請求(無消息)
     *
     * @param data
     * @return
     */
    public static Result successAndNoMsg(Object data) {
        return new Result(HttpCodeEnum.OK.getCode(), "", data);
    }

    /**
     * 操作失敗
     * @return
     */
    public static Result fail() {
        return new Result(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMessage());
    }
    /**
     * 操作失敗
     * @return
     */
    public static Result fail(Object data) {
        return new Result(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMessage() ,data);
    }
    
    /**
     * 伺服器錯誤
     * @return
     */
    public static Result error() {
        return new Result(HttpCodeEnum.INTERNAL_SERVER_ERROR.getCode(),HttpCodeEnum.INTERNAL_SERVER_ERROR.getMessage());
    }


    /**
     * 伺服器錯誤
     * @param data
     * @return
     */
    public static Result error(Object data) {
        return new Result(HttpCodeEnum.INTERNAL_SERVER_ERROR.getCode(),HttpCodeEnum.INTERNAL_SERVER_ERROR.getMessage(), data);
    }
    /**
     * 參數錯誤
     * @return
     */
    public static Result paramError() {
        return new Result(HttpCodeEnum.INVALID_REQUEST.getCode(), HttpCodeEnum.INVALID_REQUEST.getMessage());
    }

    /**
     * 參數錯誤
     * @param data
     * @return
     */
    public static Result paramError(Object data) {
        return new Result(HttpCodeEnum.INVALID_REQUEST.getCode(), HttpCodeEnum.INVALID_REQUEST.getMessage(), data);
    }

    /**
     * 認證到期
     * @return
     */
    public static Result authExpired() {
        return new Result(HttpCodeEnum.AUTH_EXPIRED.getCode(), HttpCodeEnum.AUTH_EXPIRED.getMessage());
    }

    /**
     * 沒有權限
     * @return
     */
    public static Result unAuthorized() {
        return new Result(HttpCodeEnum.UNAUTHORIZED.getCode(), HttpCodeEnum.UNAUTHORIZED.getMessage());
    }

    /**
     * 沒有權限
     * @param data
     * @return
     */
    public static Result unAuthorized(Object data) {
        return new Result(HttpCodeEnum.UNAUTHORIZED.getCode(),HttpCodeEnum.UNAUTHORIZED.getMessage(),data);
    }


    /**
     *  禁止通路
     * @return
     */
    public static Result forbidden() {
        return new Result(HttpCodeEnum.FORBIDDEN.getCode(),HttpCodeEnum.FORBIDDEN.getMessage());
    }

    /**
     * 禁止通路
     * @param data
     * @return
     */
    public static Result forbidden(Object data) {
        return new Result(HttpCodeEnum.FORBIDDEN.getCode(),HttpCodeEnum.FORBIDDEN.getMessage(), data);
    }


    /**
     * 資源不存在
     * @return
     */
    public static Result notFound() {
        return new Result(HttpCodeEnum.NOT_FOUND.getCode(),HttpCodeEnum.NOT_FOUND.getMessage());
    }


    /**
     * 資源不存在
     * @param data
     * @return
     */
    public static Result notFound(Object data) {
        return new Result(HttpCodeEnum.NOT_FOUND.getCode(),HttpCodeEnum.NOT_FOUND.getMessage(), data);
    }


    /**
     * 請求的格式不正确
     * @return
     */
    public static Result notAcceptable() {
        return new Result(HttpCodeEnum.NOT_ACCEPTABLE.getCode(),HttpCodeEnum.NOT_ACCEPTABLE.getMessage());
    }


    /**
     * 請求的格式不正确
     * @param data
     * @return
     */
    public static Result notAcceptable(Object data) {
        return new Result(HttpCodeEnum.NOT_ACCEPTABLE.getCode(),HttpCodeEnum.NOT_ACCEPTABLE.getMessage(), data);
    }


    /**
     * 資料已經被删除
     * @return
     */
    public static Result gone() {
        return new Result(HttpCodeEnum.GONE.getCode(),HttpCodeEnum.GONE.getMessage());
    }


    /**
     * 資料已經被删除
     * @param data
     * @return
     */
    public static Result gone(Object data) {
        return new Result(HttpCodeEnum.GONE.getCode(),HttpCodeEnum.GONE.getMessage(), data);
    }

    /**
     * 實體參數校驗錯誤
     * @return
     */
    public static Result unprocesableEntity() {
        return new Result(HttpCodeEnum.UNPROCESABLE_ENTITY.getCode(),HttpCodeEnum.UNPROCESABLE_ENTITY.getMessage());
    }

    /**
     * 實體參數校驗錯誤
     * @param data
     * @return
     */
    public static Result unprocesableEntity(Object data) {
        return new Result(HttpCodeEnum.UNPROCESABLE_ENTITY.getCode(),HttpCodeEnum.UNPROCESABLE_ENTITY.getMessage(), data);
    }

    /**
     * 未知錯誤
     * @return
     */
    public static Result unKnowError() {
        return new Result(HttpCodeEnum.UN_KNOW_ERROR.getCode(),HttpCodeEnum.UN_KNOW_ERROR.getMessage());
    }

    /**
     * 未知錯誤
     * @param data
     * @return
     */
    public static Result unKnowError(Object data) {
        return new Result(HttpCodeEnum.UN_KNOW_ERROR.getCode(),HttpCodeEnum.UN_KNOW_ERROR.getMessage(), data);
    }

    /**
     * 業務邏輯驗證未通過
     * @return
     */
    public static Result verificationFailed() {
        return new Result(HttpCodeEnum.VERIFICATION_FAILED.getCode(),HttpCodeEnum.VERIFICATION_FAILED.getMessage());
    }

    /**
     * 業務邏輯驗證未通過
     * @param data
     * @return
     */
    public static Result verificationFailed(Object data) {
        return new Result(HttpCodeEnum.VERIFICATION_FAILED.getCode(),HttpCodeEnum.VERIFICATION_FAILED.getMessage(), data);
    }

    /**
     * 自定義傳回
     * @param e
     * @return
     */
    public static Result custom(HttpCodeEnum e) {
        return new Result(e.getCode(),e.getMessage());
    }
    /**
     * 自定義傳回
     * @param error
     * @return
     */
    public static Result custom(int code,String error) {
        return new Result(code,error);
    }

    /**
     * 自定義傳回
     * @param error
     * @param data
     * @return
     */
    public static Result custom(int code,String error,Object data) {
        return new Result(code,error,data);
    }

}      

22.Http狀态碼枚舉類

/**
 * 
 * http 狀态碼
 * ----------------------------------------------------------------------------
 * 200 OK - [GET]:伺服器成功傳回使用者請求的資料,該操作是幂等的(Idempotent)。
 * 400 INVALID REQUEST - [POST/PUT/PATCH]:使用者發出的請求有錯誤,伺服器沒有進行建立或修改資料的操作,該操作是幂等的。
 * 401 Unauthorized - [*]:表示使用者沒有權限(令牌、使用者名、密碼錯誤)。
 * 403 Forbidden - [*] 表示使用者得到授權(與401錯誤相對),但是通路是被禁止的。
 * 404 NOT FOUND - [*]:使用者發出的請求針對的是不存在的記錄,伺服器沒有進行操作,該操作是幂等的。
 * 406 Not Acceptable - [GET]:使用者請求的格式不可得(比如使用者請求JSON格式,但是隻有XML格式)。
 * 410 Gone -[GET]:使用者請求的資源被永久删除,且不會再得到的。
 * 422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個對象時,發生一個驗證錯誤。
 * 500 INTERNAL SERVER ERROR - [*]:伺服器發生錯誤,使用者将無法判斷發出的請求是否成功。
 * 600 UN_KNOW_ERROR - 未知錯誤
 * ----------------------------------------------------------------------------
 */
public enum HttpCodeEnum {

    OK(200,"操作成功"),
    INVALID_REQUEST(400,"參數錯誤"),
    UNAUTHORIZED(401,"沒有權限"),
    FORBIDDEN(403,"禁止通路"),
    NOT_FOUND(404,"資源不存在"),
    NOT_ACCEPTABLE(406,"請求的格式不正确"),
    GONE(410,"資料被删除"),
    UNPROCESABLE_ENTITY(422,"參數驗證錯誤"),
    INTERNAL_SERVER_ERROR(500,"伺服器發生錯誤"),
    UN_KNOW_ERROR(500,"未知錯誤"),
    FAIL(501,"操作失敗"),

    MODEL_NOT_EXIST(1000, "模型不存在"),
    VERIFICATION_FAILED(1001, "業務邏輯驗證未通過"),
    USERNAME_OR_PASSWORD_ERR(2000,"使用者未登入或token已失效"),
    DELETE_DEFAULT_PHOTO_ERR(2001,"預設頭像不可删除"),
    AUTH_EXPIRED(3000,"認證到期"),
    TOKEN_ERR(3001, "token無效");

    private final int code;
    private final String message;

    HttpCodeEnum(final int code, final String message){
        this.code=code;
        this.message=message;
    }

    public String getMessage() {
        return message;
    }

    public int getCode() {
        return code;
    }

}      

23.CommonUtil集合判空工具類

public class CommonUtil {

    /**
     * 判斷集合為空
     * @param collection
     * @return
     */
    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty() || collection.size() <= 0;
    }

    /**
     * 判斷集合非空
     * @param collection
     * @return
     */
    public static boolean isNotEmpty(Collection<?> collection) {
        return !isEmpty(collection);
    }

    /**
     * 随機生成UUID
     * @return
     */
    public static String getUUID(){
        UUID uuid = UUID.randomUUID();
        return uuid.toString().replaceAll("-","");
    }
}      

24.gateway身份認證過濾器

/**
 * 身份認證過濾器
 * @author: Ronin
 * @since: 2021/10/5
 * @email:
 * 統一認證的實作方式是自定義實作全局過濾器,在過濾器裡面可以處理白名單放行、認證校驗、動态處理請求參數等
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private SystemPropertiesConfig systemPropertiesConfig;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 白名單Path
        Set<String> whiteList = this.getWhiteList();
        String path = exchange.getRequest().getPath().toString();

        // 首頁接口、圖書接口正則比對
        boolean indexMatch = Pattern.matches("/index[^\\s]*", path);
        boolean bookMatch = Pattern.matches("/book/[^\\s]*", path);

        // 白名單接口、開放接口放行
        if (whiteList.contains(path) || bookMatch || indexMatch) {
            return chain.filter(exchange);
        }

        String[] segments = path.split("/");
        if (!whiteList.contains(segments[1])) {
            // 認證
            String token = exchange.getRequest().getHeaders().getFirst("token");
            Result<User> result = JwtUtil.validationToken(token);
            if (result.getCode() == HttpCodeEnum.OK.getCode()) {
                // 認證通過
                User user = result.getData();
                // 追加請求頭使用者資訊
                Consumer<HttpHeaders> httpHeaders = httpHeader -> {
                    httpHeader.set("userId",user.getId().toString());
                    httpHeader.set("nickName",user.getNickName());
                };
                ServerHttpRequest serverHttpRequest = exchange.getRequest()
                        .mutate()
                        .headers(httpHeaders)
                        .build();
                exchange.mutate().request(serverHttpRequest).build();
                return chain.filter(exchange);
            }
            // 認證過期、失敗,均傳回401
            ServerHttpResponse response = exchange.getResponse();
            byte[] bits = JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8);
            DataBuffer buffer = response.bufferFactory().wrap(bits);
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            // 指定編碼,否則在浏覽器中會中文亂碼
            response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            return response.writeWith(Mono.just(buffer));
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * 請求白名單
     * @return
     */
    private Set<String> getWhiteList(){
        String whitelists = this.systemPropertiesConfig.getWhitelist();
        if (StringUtils.isEmpty(whitelists)) {
            return new HashSet<>();
        }
        Set<String> whiteList = new HashSet<>();
        String[] whiteArray = whitelists.split(",");
        for (int i = 0; i < whiteArray.length; i++) {
            whiteList.add(whiteArray[i]);
        }
        return whiteList;
    }
}