常用工具类

1、DateUtil

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 *
 * @author yangyongjie
 * @date 2019/9/24
 * @desc
 */
public class DateUtil {
    private DateUtil() {
    }

    private static final Logger LOGGER = LoggerFactory.getLogger(DateUtil.class);

    public static final String YYYYMMDD_HHMMSS = "yyyy-MM-dd HH:mm:ss";

    public static final String YYYYMMDD = "yyyy-MM-dd";

    public static final String YYYYMMHHMMSSS = "yyyyMMddHHmmssS";


    public static String getMonth(Timestamp time) {
        return new SimpleDateFormat("yyyyMM").format(time);
    }

    /**
     * 将Date格式化为字符串,默认yyyy-MM-dd HH:mm:ss格式
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return formatDate(date, YYYYMMDD_HHMMSS);
    }

    /**
     * 将Date格式化为字符串根据传入的格式
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return null;
        }
        if (StringUtils.isEmpty(pattern)) {
            return formatDate(date);
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * 将指定格式的日期字符串解析为Date
     *
     * @param dateStr
     * @param pattern
     * @return
     */
    public static Date parseDate(String dateStr, String pattern) {
        if (StringUtils.isEmpty(dateStr) || StringUtils.isEmpty(pattern)) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            LOGGER.error("解析日期字符串异常" + e.getMessage(), e);
        }
        return date;
    }

    /**
     * 讲默认格式的日期字符串解析为Date
     *
     * @param dateStr
     * @return
     */
    public static Date parseDate(String dateStr) {
        return parseDate(dateStr, YYYYMMDD_HHMMSS);
    }

    /**
     * 获取当前时间的时间戳
     *
     * @return
     */
    public static String getTimeInMillis() {
        long timeInMillis = Calendar.getInstance().getTimeInMillis();
        return timeInMillis + "";
    }

    /**
     * 获取当前时间的字符串
     *
     * @return
     */
    public static String getCurrentDate() {
        return formatDate(new Date(), YYYYMMDD_HHMMSS);
    }

    /**
     * 获取当前时间的秒数
     *
     * @return
     */
    public static int currentTimeSec() {
        return (int) (System.currentTimeMillis() / 1000);
    }

    /**
     * 获取当前时间往后的第几天的时间,为负表示前几天的时间
     *
     * @param i
     * @return
     */
    public static Date getBeforeOrNextDay(int i) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, i);
        return calendar.getTime();
    }

    /**
     * 获得当前时间的n秒前或后
     *
     * @param origin
     * @param seconds
     * @return
     */
    public static Date getIntervalSeconds(Date origin, long seconds) {
        return new Date(origin.getTime() + seconds * 1000L);
    }

}
View Code

 

2、LogUtil:用于发送错误日志邮件

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 日志工具类,用来发送错误邮件
 *
 * @author yangyongjie
 * @date 2019/11/1
 * @desc
 */
public class LogUtil {
    private LogUtil() {
    }

    private static final Logger LOGGER = LoggerFactory.getLogger(LogUtil.class);

    /**
     * 创建一个用于发送邮件的线程池,核心线程数为1,最大线程数为5,线程空闲时间为60s,拒绝策略为打印日志
     */
    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
            1,
            5,
            60,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(100),
            new CustomThreadFactory("sendErrorMail"),
            (r, executor) -> {
                // 只打印日志,什么都不做
                LOGGER.error("Task{},rejected from{}", r.toString(), executor.toString());
            });

    /**
     * 打印日志并发送错误邮件
     *
     * @param msg
     * @param t
     */
    public static void LogAndMail(String msg, Throwable t) {
        // 获取调用此工具类的该方法 的调用方信息
        // 查询当前线程的堆栈信息
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        // 按照规则,此方法的上一级调用类为
        StackTraceElement ste = stackTrace[2];
        String className = ste.getClassName();
        String methodName = ste.getMethodName();
        LOGGER.error("{}#{},{}," + t.getMessage(), className, methodName, msg, t);
        // 异步发送邮件
        String ms = "[" + ThreadContext.currentThreadContext().getThreadId() + "]" + msg;
        executor.execute(() -> ErrorMailUtil.sendErrorMail(ms, t, 3));
    }

    /**
     * 只发送错误邮件不打印日志
     *
     * @param msg
     */
    public static void sendErrorLogMail(String msg, Throwable t) {
        // 异步发送邮件
        String ms = "[" + ThreadContext.currentThreadContext().getThreadId() + "]" + msg + assembleStackTrace(t);
        executor.execute(() -> ErrorMailUtil.sendErrorMail(ms, t, 3));
    }

    /**
     * 组装异常堆栈
     *
     * @param t
     * @return
     */
    public static String assembleStackTrace(Throwable t) {
        StringWriter sw = new StringWriter();
        PrintWriter ps = new PrintWriter(sw);
        t.printStackTrace(ps);
        return sw.toString();
    }
}
View Code

 

3、HttpParamUtil:

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Http 参数处理相关工具类
 *
 * @author yangyongjie
 * @date 2019/10/28
 * @desc
 */
public class HttpParamUtil {

    private HttpParamUtil() {
    }

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpParamUtil.class);

    /**
     * 获取request中的body信息 JSON格式
     *
     * @param request
     * @return
     */
    public static String getRequestBody(HttpServletRequest request) {
        StringBuilder bodyDataBuilder = new StringBuilder();
        BufferedReader br = null;
        try {
            br = request.getReader();
            String str;
            while ((str = br.readLine()) != null) {
                bodyDataBuilder.append(str);
            }
            br.close();
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage(), e);
                }
            }
        }

       /* InputStream is = null;
        try {
            is = request.getInputStream();
            byte[] b = new byte[4096];
            for (int n; (n = is.read(b)) != -1; ) {
                bodyDataBuilder.append(new String(b, 0, n));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }*/
        String bodyString = bodyDataBuilder.toString();
        LOGGER.info("bodyString={}", bodyString);
        return bodyString;
    }

    /**
     * 获取request中的body信息,并组装好按“参数=参数值”的格式
     *
     * @param request
     * @return
     */
    public static String getAssembleRequestBody(HttpServletRequest request) {
        String bodyString = getRequestBody(request);
        Map<String, Object> originMap = JacksonUtil.toObject(bodyString, Map.class);
        Map<String, Object> sortedParams = getSortedMap(originMap);
        String assembleBody = getSignContent(sortedParams);
        return assembleBody;
    }

    /**
     * 根据requestBody中的原始map获取解析后并组装的参数字符串,根据&符拼接
     *
     * @param originMap
     * @return
     */
    public static String getAssembleParam(Map<String, Object> originMap) {
        return getSignContent(getSortedMap(originMap));
    }


    /**
     * 将body转成按key首字母排好序
     *
     * @return
     */
    public static Map<String, Object> getSortedMap(Map<String, Object> originMap) {
        Map<String, Object> sortedParams = new TreeMap<String, Object>();
        if (originMap != null && originMap.size() > 0) {
            sortedParams.putAll(originMap);
        }
        return sortedParams;
    }

    /**
     * 将排序好的map的key和value拼接成字符串
     *
     * @param sortedParams
     * @return
     */
    public static String getSignContent(Map<String, Object> sortedParams) {
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(sortedParams.keySet());
        Collections.sort(keys);
        int index = 0;
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            Object value = sortedParams.get(key);
            if (StringUtils.isNotEmpty(key) && value != null) {
                content.append((index == 0 ? "" : "&") + key + "=" + value);
                index++;
            }
        }
        return content.toString();
    }

    /**
     * Json转实体对象
     *
     * @param jsonStr
     * @param clazz   目标生成实体对象
     * @return
     */
    public static <T> T fromJsonToObject(String jsonStr, Class clazz) {
        T results = null;
        try {
            results = (T) JacksonUtil.toObject(jsonStr, clazz);
        } catch (Exception e) {
        }
        return results;
    }

    /**
     * 对请求参数进行校验,目前只进行非空校验
     *
     * @param tarObj 目标实体类
     * @return 校验成功返回true
     */
    public static <T> boolean paramCheck(T tarObj) {
        try {
            Class<T> tarClass = (Class<T>) tarObj.getClass();
            List<Field> fields = new ArrayList<>();
            fields.addAll(Arrays.asList(tarClass.getDeclaredFields()));
            Class supClass = tarClass.getSuperclass();
            while (supClass != null) {
                fields.addAll(Arrays.asList(supClass.getDeclaredFields()));
                supClass = supClass.getSuperclass();
            }
            for (Field field : fields) {
                field.setAccessible(true);
                ParamVerify verify = field.getAnnotation(ParamVerify.class);
                if (verify != null) {
                    //非空校验,后续若需增加校验类型,应抽离
                    if (verify.nullable() == CheckEnum.NOTNULL) {
                        Object val = field.get(tarObj);
                        if (val == null || "".equals(val.toString())) {
                            return false;
                        }
                    }
                }
            }
        } catch (Exception ex) {
            LOGGER.info("Param verify error");
            return false;
        }
        return true;
    }

}

/**
 * 字段校验注解,目前只进行非空校验,可扩展,用在字段上
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ParamVerify {
    /**
     * 是否允许为空
     */
    CheckEnum nullable() default CheckEnum.NULL;
}

public enum CheckEnum {
    NOTNULL,
    NULL
View Code

  优化版:

查看代码

import com.xiaomi.mitv.uvcas.common.annotation.DateCheck;
import com.xiaomi.mitv.uvcas.common.annotation.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Http请求参数处理工具类
 */
public class ParamUtil {

    private ParamUtil() {
    }

    private static final Logger LOGGER = LoggerFactory.getLogger(ParamUtil.class);

    /**
     * 获取request中的body信息 JSON格式
     *
     * @param request
     * @return
     */
    public static String getRequestBody(HttpServletRequest request) {
        StringBuilder bodyDataBuilder = new StringBuilder();
        BufferedReader br = null;
        try {
            br = request.getReader();
            String str;
            while ((str = br.readLine()) != null) {
                bodyDataBuilder.append(str);
            }
            br.close();
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage(), e);
                }
            }
        }
        String bodyString = bodyDataBuilder.toString();
        LOGGER.info("bodyString={}", bodyString);
        return bodyString;
    }

    /**
     * 获取request中的body信息,并组装好按“参数=参数值”的格式
     *
     * @param request
     * @return
     */
    public static String getAssembleRequestBody(HttpServletRequest request) {
        String bodyString = getRequestBody(request);
        Map<String, Object> originMap = JacksonUtil.toObject(bodyString, Map.class);
        Map<String, Object> sortedParams = getSortedMap(originMap);
        String assembleBody = getSignContent(sortedParams);
        return assembleBody;
    }

    /**
     * 根据requestBody中的原始map获取解析后并组装的参数字符串,根据&符拼接
     *
     * @param originMap
     * @return
     */
    public static String getAssembleParam(Map<String, Object> originMap) {
        return getSignContent(getSortedMap(originMap));
    }


    /**
     * 将body转成按key首字母排好序
     *
     * @return
     */
    public static Map<String, Object> getSortedMap(Map<String, Object> originMap) {
        Map<String, Object> sortedParams = new TreeMap<String, Object>();
        if (originMap != null && originMap.size() > 0) {
            sortedParams.putAll(originMap);
        }
        return sortedParams;
    }

    /**
     * 将排序好的map的key和value拼接成字符串
     *
     * @param sortedParams
     * @return
     */
    public static String getSignContent(Map<String, Object> sortedParams) {
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(sortedParams.keySet());
        Collections.sort(keys);
        int index = 0;
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            Object value = sortedParams.get(key);
            if (StringUtils.isNotEmpty(key) && value != null) {
                content.append((index == 0 ? "" : "&") + key + "=" + value);
                index++;
            }
        }
        return content.toString();
    }

    /**
     * 对请求参数进行校验
     *
     * @param tarObj 目标实体类
     * @return 校验成功返回true
     */
    public static <T> boolean paramCheck(T tarObj) {
        if (tarObj == null) {
            return false;
        }
        try {
            Class<T> tarClass = (Class<T>) tarObj.getClass();
            List<Field> fields = getFields(tarClass);
            return fieldCheck(fields, tarObj);
        } catch (Exception ex) {
            LOGGER.info("Param check error" + ex.getMessage(), ex);
            return false;
        }
    }

    /**
     * 请求集合参数校验
     *
     * @param tarObjs
     * @param tarClass
     * @param <T>
     * @return
     */
    public static <T> boolean paramCheck(List<T> tarObjs, Class<T> tarClass) {
        if (tarObjs == null) {
            return false;
        }
        try {
            List<Field> fields = new ArrayList<>();
            fields.addAll(Arrays.asList(tarClass.getDeclaredFields()));
            Class supClass = tarClass.getSuperclass();
            while (supClass != null) {
                fields.addAll(Arrays.asList(supClass.getDeclaredFields()));
                supClass = supClass.getSuperclass();
            }
            for (T tarObj : tarObjs) {
                boolean pass = fieldCheck(fields, tarObj);
                if (!pass) {
                    return false;
                }
            }
        } catch (Exception ex) {
            LOGGER.info("Param check error" + ex.getMessage(), ex);
            return false;
        }
        return true;
    }


    /**
     * 获取指定字节码文件对应的属性集合
     *
     * @param tarClass
     * @param <T>
     * @return
     */
    private static <T> List<Field> getFields(Class<T> tarClass) {
        List<Field> fields = new ArrayList<>();
        fields.addAll(Arrays.asList(tarClass.getDeclaredFields()));
        Class supClass = tarClass.getSuperclass();
        while (supClass != null) {
            fields.addAll(Arrays.asList(supClass.getDeclaredFields()));
            supClass = supClass.getSuperclass();
        }
        return fields;
    }

    /**
     * 属性校验
     *
     * @param fields
     * @param tarObj
     * @param <T>
     * @return
     * @throws IllegalAccessException
     */
    private static <T> boolean fieldCheck(List<Field> fields, T tarObj) throws IllegalAccessException {
        for (Field field : fields) {
            field.setAccessible(true);
            // 非空字段校验
            NonNull nonNull = field.getAnnotation(NonNull.class);
            if (nonNull != null) {
                Object val = field.get(tarObj);
                if (val == null || "".equals(val.toString())) {
                    LOGGER.info("field:{}为空", field.getName());
                    return false;
                }

            }
            // 日期字符串格式校验
            DateCheck dateCheck = field.getAnnotation(DateCheck.class);
            if (dateCheck != null) {
                Object val = field.get(tarObj);
                String format = dateCheck.format();
                try {
                    LocalDate.parse((CharSequence) val, DateTimeFormatter.ofPattern(format));
                } catch (DateTimeParseException e) {
                    LOGGER.info("field:{}日期不合法,值为{}", field.getName(), val);
                    return false;
                }
            }
        }
        return true;
    }

}

 

4、DigestUtil:(MD5,SHA1)

查看代码
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * 摘要工具类
 *
 * @author yangyongjie
 * @date 2022/6/22
 */
public class DigestUtil {
    private DigestUtil() {
    }

    public static String getMd5(String message) {
        return message != null && message.length() != 0 ? getDigest(message.getBytes(), "MD5") : "";
    }

    public static String getSha1(String message) {
        return message != null && message.length() != 0 ? getDigest(message.getBytes(), "SHA1") : "";
    }

    public static String getDigest(byte[] bytes, String digestType) {
        if (bytes == null) {
            return "";
        } else {
            String digest = "";
            try {
                MessageDigest algorithm = MessageDigest.getInstance(digestType);
                algorithm.reset();
                algorithm.update(bytes);
                digest = toHexString(algorithm.digest());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return digest;
        }
    }

    private static String toHexString(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        int length = bytes.length;

        for (int i = 0; i < length; ++i) {
            byte b = bytes[i];
            String str;
            for (str = Integer.toHexString(255 & b); str.length() < 2; str = "0" + str) {
            }
            hexString.append(str);
        }
        return hexString.toString();
    }

    /**
     * 获取文件字节流的MD5
     *
     * @param data
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    public static String md5Hex(InputStream data) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[1024];

            for (int read = data.read(buffer, 0, 1024); read > -1; read = data.read(buffer, 0, 1024)) {
                digest.update(buffer, 0, read);
            }
            byte[] digestByte = digest.digest();
            // 摘要字节数组转成16进制字符串
            return toHexString(digestByte);
        } catch (Exception e) {
            return UUID.randomUUID().toString().replace("-", "");
        }
    }

}

 

5、IpUtil

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * 获取用户ip工具类
 */
public class IpUtil {

    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        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.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (ip.equals("127.0.0.1")) {
                // 根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ip = inet.getHostAddress();
            }
        }
        // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
        // "***.***.***.***".length()
        if (ip != null && ip.length() > 15) {
            // = 15
            if (ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

    /**
     * 将 ip 字符串转换为 int 类型的数字
     * <p>
     * 思路就是将 ip 的每一段数字转为 8 位二进制数,并将它们放在结果的适当位置上
     *
     * @param ipString ip字符串,如 127.0.0.1
     * @return ip字符串对应的 int 值
     */
    public static int ip2Int(String ipString) {
        // 取 ip 的各段
        String[] ipSlices = ipString.split("\\.");
        int len = ipSlices.length;
        int rs = 0;
        for (int i = 0; i < len; i++) {
            // 将 ip 的每一段解析为 int,并根据位置左移 8 位
            int intSlice = Integer.parseInt(ipSlices[i]) << 8 * (len - i - 1);
            // 求或
            rs = rs | intSlice;
        }
        return rs;
    }

    /**
     * 将 int 转换为 ip 字符串
     *
     * @param ipInt 用 int 表示的 ip 值
     * @return ip字符串,如 127.0.0.1
     */
    public static String int2Ip(int ipInt) {
        int len = 4;
        String[] ipString = new String[len];
        for (int i = 0; i < len; i++) {
            // 每 8 位为一段,这里取当前要处理的最高位的位置
            int pos = (len - i - 1) * 8;
            // 取当前处理的 ip 段的值
            int and = ipInt & (255 << pos);
            // 将当前 ip 段转换为 0 ~ 255 的数字,注意这里必须使用无符号右移
            ipString[i] = String.valueOf(and >>> pos);
        }
        return String.join(".", ipString);
    }

    public static void main(String[] args) {
        String ip1 = "1.10.0.0";
        int intIp = ip2Int(ip1);
        String ip2 = int2Ip(intIp);
        System.out.println(ip2.equals(ip1));
    }
}
View Code

 

6、ByteUtil

public class ByteUtil {
    private ByteUtil() {
    }

    public static byte[] toByteArray(int value) {
        byte[] bytes = new byte[4];
        bytes[3] = (byte) (value & 0xff);
        bytes[2] = (byte) (value >> 8 & 0xff);
        bytes[1] = (byte) (value >> 16 & 0xff);
        bytes[0] = (byte) (value >> 24 & 0xff);
        return bytes;
    }

    public static byte[] toByteArray(long value) {
        byte[] bytes = new byte[8];
        bytes[7] = (byte) (value & 0xff);
        bytes[6] = (byte) (value >> 8  & 0xff);
        bytes[5] = (byte) (value >> 16 & 0xff);
        bytes[4] = (byte) (value >> 24 & 0xff);
        bytes[3] = (byte) (value >> 32 & 0xff);
        bytes[2] = (byte) (value >> 40 & 0xff);
        bytes[1] = (byte) (value >> 48 & 0xff);
        bytes[0] = (byte) (value >> 56 & 0xff);
        return bytes;
    }
}
View Code

 

7、StringUtil

查看代码

import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义字符串工具类
 */
public class StringUtil {
    private StringUtil() {
    }

    private static final AtomicInteger AI = new AtomicInteger(1);

    /**
     * 返回UUID
     *
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 返回唯一ID,对ID唯一性要求不高时可用此方式
     *
     * @return
     */
    public static String getOnlyId() {
        // 当前毫秒数
        long currentMills = System.currentTimeMillis();
        // 拼接一个自增数
        int value = AI.getAndIncrement();
        if (value == 999) {
            AI.set(1);
        }
        // 不满三位前面补0
        String num = String.format("%3d", value).replace(" ", "0");
        return currentMills + num;
    }

    /**
     * 检查指定的字符串列表是否不为空。
     */
    public static boolean areNotEmpty(String... values) {
        boolean result = true;
        if (values == null || values.length == 0) {
            result = false;
        } else {
            for (String value : values) {
                result &= !isEmpty(value);
            }
        }
        return result;
    }

    /**
     * 有一个为空,则为true
     *
     * @param values
     * @return
     */
    public static boolean haveEmpty(String... values) {
        if (values == null || values.length == 0) {
            return true;
        } else {
            for (String value : values) {
                if (isEmpty(value)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查指定的字符串是否为空。
     * <ul>
     * <li>SysUtils.isEmpty(null) = true</li>
     * <li>SysUtils.isEmpty("") = true</li>
     * <li>SysUtils.isEmpty("   ") = true</li>
     * <li>SysUtils.isEmpty("abc") = false</li>
     * </ul>
     *
     * @param cs 待检查的字符串
     * @return true/false
     */
    public static boolean isEmpty(final CharSequence cs) {
//        return cs == null || cs.length() == 0;
        if (cs == null || cs.length() == 0) {
            return true;
        }
        for (int i = 0; i < cs.length(); i++) {
            if (!Character.isWhitespace(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public static boolean isNotEmpty(final CharSequence cs) {
        return !isEmpty(cs);
    }

    /**
     * 两个字符串是否相等
     *
     * @param cs1
     * @param cs2
     * @return
     */
    public static boolean equals(final CharSequence cs1, final CharSequence cs2) {
        if (cs1 == cs2) {
            return true;
        }
        if (cs1 == null || cs2 == null) {
            return false;
        }
        if (cs1.length() != cs2.length()) {
            return false;
        }
        if (cs1 instanceof String && cs2 instanceof String) {
            return cs1.equals(cs2);
        }
        // Step-wise comparison
        final int length = cs1.length();
        for (int i = 0; i < length; i++) {
            if (cs1.charAt(i) != cs2.charAt(i)) {
                return false;
            }
        }
        return true;
    }

}

 

8、result

  ①:HandleResult(属性带默认值)

查看代码

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

public class HandleResult {

    private Integer code = 0;

    private String message = "success";

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private Object data;

    public HandleResult() {
    }

    public HandleResult(ResponseEnum response) {
        this.code = response.getCode();
        this.message = response.getMessage();
    }

    public HandleResult(Object data) {
        this.data = data;
    }

    public HandleResult fail(ResponseEnum response) {
        this.code = response.getCode();
        this.message = response.getMessage();
        return this;
    }

    @JsonIgnore
    public boolean isSuccess() {
        return ResponseEnum.SUCCESS.getCode().equals(code);
    }

    public Integer getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

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

  ②:CommonResult

import com.fasterxml.jackson.annotation.JsonInclude;
import com.xiaomi.mitv.uvcas.common.enums.ResponseEnum;

/**
 * 公共返回结果类
 *
 * @author yangyongjie
 */
public class CommonResult {
    private String code;
    private String msg;
    /**
     * 返回结果,如果为null则不序列化此字段
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Object data;

    public CommonResult() {
        this.code = ResponseEnum.SUCCESS.getCode();
        this.msg = ResponseEnum.SUCCESS.getMsg();
    }

    /**
     * 默认成功
     */
    public CommonResult(Object obj) {
        this.code = ResponseEnum.SUCCESS.getCode();
        this.msg = ResponseEnum.SUCCESS.getMsg();
        this.data = obj;
    }

    /**
     * 成功返回
     */
    public static CommonResult success() {
        return new CommonResult();
    }

    /**
     * 失败返回
     */
    public static CommonResult fail(ResponseEnum responseEnum) {
        CommonResult result = new CommonResult();
        result.code = responseEnum.getCode();
        result.msg = responseEnum.getMsg();
        return result;
    }

    public String getCode() {
        return code;
    }

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

    public String getMsg() {
        return msg;
    }

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

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}
View Code

 

9、ZlibUtil

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

public class ZlibUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ZlibUtil.class);

    private ZlibUtil() {
    }

    public static byte[] compress(byte[] data) {
        byte[] output;
        Deflater deflater = new Deflater();
        deflater.reset();
        deflater.setInput(data);
        deflater.finish();
        try(ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length)) {
            byte[] buf = new byte[1024];
            while (!deflater.finished()) {
                int i = deflater.deflate(buf);
                bos.write(buf, 0, i);
            }
            output = bos.toByteArray();
        } catch (Exception e) {
            output = data;
            LOGGER.info(e.getMessage(), e);
        }
        deflater.end();
        return output;
    }

    public static byte[] decompress(byte[] data) {
        byte[] output;
        Inflater inflater = new Inflater();
        inflater.reset();
        inflater.setInput(data);
        try(ByteArrayOutputStream o = new ByteArrayOutputStream(data.length)) {
            byte[] buf = new byte[1024];
            while (!inflater.finished()) {
                int i = inflater.inflate(buf);
                o.write(buf, 0, i);
            }
            output = o.toByteArray();
        } catch (Exception e) {
            output = data;
            LOGGER.info(e.getMessage(), e);
        }
        inflater.end();
        return output;
    }

}
View Code

 

 10、BeanUtil  map和Object互相转换

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

public class BeanUtil {
    private BeanUtil() {
    }

    /**
     * object转换成map
     */
    public static Map<String, Object> Obj2Map(Object obj) {
        Map<String, Object> map = new HashMap<>(8);
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                map.put(field.getName(), field.get(obj));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    /**
     * map转换为object
     *
     * @param map
     * @param clz
     * @return
     * @throws Exception
     */
    public static <T> T map2Obj(Map<String, Object> map, Class<T> clz) {
        try {
            T obj = clz.newInstance();
            Field[] declaredFields = obj.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                field.set(obj, map.get(field.getName()));
            }
            return obj;
        } catch (Exception e) {
            // 打印日志省略
            return null;
        }
    }
}
View Code

 

11、ClassUtils

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.jeesite.common.codec.EncodeUtils;

/**
 * Class工具类,借鉴ibatis的io包的ResolverUtil类。
 * @author ThinkGem
 * @version 2016-4-28
 */
public class ClassUtils {
    
    /*
     * An instance of Log to use for logging in this class.
     */
    private static final Log log = LogFactory.getLog(ClassUtils.class);

    /**
     * A simple interface that specifies how to test classes to determine if they
     * are to be included in the results produced by the ResolverUtil.
     */
    public static interface Test {
        /**
         * Will be called repeatedly with candidate classes. Must return True if a class
         * is to be included in the results, false otherwise.
         */
        boolean matches(Class<?> type);
    }

    /**
     * 查询实现类,继承与parentType,并不是当前类,不是抽象类。
     * 
     * A Test that checks to see if each class is assignable to the provided class. Note
     * that this test will match the parent type itself if it is presented for matching.
     */
    public static class IsA implements Test {
        private Class<?> parent;

        /** Constructs an IsA test using the supplied Class as the parent class/interface. */
        public IsA(Class<?> parentType) {
            this.parent = parentType;
        }

        /** Returns true if type is assignable to the parent type supplied in the constructor. */
        @Override
        public boolean matches(Class<?> type) {
            return type != null && parent.isAssignableFrom(type)    // 是继承与该类
                    && !type.getName().equals(parent.getName())        // 不包含当前类
                    && !Modifier.isAbstract(type.getModifiers());    // 不包含抽象类
        }

        @Override
        public String toString() {
            return "is assignable to " + parent.getSimpleName();
        }
    }

    /**
     * 查询设置此注解的类。
     * 
     * A Test that checks to see if each class is annotated with a specific annotation. If it
     * is, then the test returns true, otherwise false.
     */
    public static class AnnotatedWith implements Test {
        private Class<? extends Annotation> annotation;

        /** Constructs an AnnotatedWith test for the specified annotation type. */
        public AnnotatedWith(Class<? extends Annotation> annotation) {
            this.annotation = annotation;
        }

        /** Returns true if the type is annotated with the class provided to the constructor. */
        @Override
        public boolean matches(Class<?> type) {
            return type != null && type.isAnnotationPresent(annotation);
        }

        @Override
        public String toString() {
            return "annotated with @" + annotation.getSimpleName();
        }
    }

    /** The set of matches being accumulated. */
    private Set<Class<?>> matches = new HashSet<Class<?>>();

    /**
     * The ClassLoader to use when looking for classes. If null then the ClassLoader returned
     * by Thread.currentThread().getContextClassLoader() will be used.
     */
    private ClassLoader classloader;

    /**
     * Provides access to the classes discovered so far. If no calls have been made to
     * any of the {@code find()} methods, this set will be empty.
     *
     * @return the set of classes that have been discovered.
     */
    public Set<Class<?>> getClasses() {
        return matches;
    }

    /**
     * Returns the classloader that will be used for scanning for classes. If no explicit
     * ClassLoader has been set by the calling, the context class loader will be used.
     *
     * @return the ClassLoader that will be used to scan for classes
     */
    public ClassLoader getClassLoader() {
        return classloader == null ? Thread.currentThread().getContextClassLoader() : classloader;
    }

    /**
     * Sets an explicit ClassLoader that should be used when scanning for classes. If none
     * is set then the context classloader will be used.
     *
     * @param classloader a ClassLoader to use when scanning for classes
     */
    public void setClassLoader(ClassLoader classloader) {
        this.classloader = classloader;
    }

    /**
     * 查询实现类,继承与parentType,并不是当前类,不是抽象类。
     * 
     * Attempts to discover classes that are assignable to the type provided. In the case
     * that an interface is provided this method will collect implementations. In the case
     * of a non-interface class, subclasses will be collected.  Accumulated classes can be
     * accessed by calling {@link #getClasses()}.
     *
     * @param parent the class of interface to find subclasses or implementations of
     * @param packageNames one or more package names to scan (including subpackages) for classes
     */
    public static <T> Set<Class<?>> findImplementations(Class<?> parent, String... packageNames) {
        if (packageNames == null) {
            return new HashSet<Class<?>>();
        }
        ClassUtils cu = new ClassUtils();
        Test test = new IsA(parent);
        for (String pkg : packageNames) {
            cu.find(test, pkg);
        }
        return cu.getClasses();
    }

    /**
     * 查询设置此注解的类。
     * 
     * Attempts to discover classes that are annotated with the annotation. Accumulated
     * classes can be accessed by calling {@link #getClasses()}.
     * 
     * @param annotation the annotation that should be present on matching classes
     * @param packageNames one or more package names to scan (including subpackages) for classes
     */
    public static Set<Class<?>> findAnnotated(Class<? extends Annotation> annotation, String... packageNames) {
        if (packageNames == null) {
            return new HashSet<Class<?>>();
        }
        ClassUtils cu = new ClassUtils();
        Test test = new AnnotatedWith(annotation);
        for (String pkg : packageNames) {
            cu.find(test, pkg);
        }
        return cu.getClasses();
    }

    /**
     * Scans for classes starting at the package provided and descending into subpackages.
     * Each class is offered up to the Test as it is discovered, and if the Test returns
     * true the class is retained.  Accumulated classes can be fetched by calling
     * {@link #getClasses()}.
     *
     * @param test an instance of {@link Test} that will be used to filter classes
     * @param packageName the name of the package from which to start scanning for
     *        classes, e.g. {@code net.sourceforge.stripes}
     */
    public ClassUtils find(Test test, String packageName) {
        String path = getPackagePath(packageName);

        try {
            List<String> children = VFS.getInstance().list(path);
            for (String child : children) {
                if (child.endsWith(".class")) {
                    addIfMatching(test, child);
                }
            }
        } catch (IOException ioe) {
            log.error("Could not read package: " + packageName, ioe);
        }

        return this;
    }

    /**
     * Converts a Java package name to a path that can be looked up with a call to
     * {@link ClassLoader#getResources(String)}.
     * 
     * @param packageName The Java package name to convert to a path
     */
    protected String getPackagePath(String packageName) {
        return packageName == null ? null : packageName.replace('.', '/');
    }

    /**
     * Add the class designated by the fully qualified class name provided to the set of
     * resolved classes if and only if it is approved by the Test supplied.
     *
     * @param test the test used to determine if the class matches
     * @param fqn the fully qualified name of a class
     */
    protected void addIfMatching(Test test, String fqn) {
        try {
            String externalName = fqn.substring(0, fqn.indexOf('.')).replace('/', '.');
            ClassLoader loader = getClassLoader();
            log.debug("Checking to see if class " + externalName + " matches criteria [" + test + "]");

            Class<?> type = loader.loadClass(externalName);
            if (test.matches(type)) {
                matches.add((Class<?>) type);
            }
        } catch (Exception t) {
            log.warn("Could not examine class '" + fqn + "'" + " due to a " 
                    + t.getClass().getName() + " with message: " + t.getMessage());
        }
    }
}

/**
 * Provides a very simple API for accessing resources within an application server.
 * 
 * @author Ben Gunter
 */
abstract class VFS {
    private static final Log log = LogFactory.getLog(ClassUtils.class);

    /** The built-in implementations. */
    public static final Class<?>[] IMPLEMENTATIONS = { JBoss6VFS.class, DefaultVFS.class };

    /** The list to which implementations are added by {@link #addImplClass(Class)}. */
    public static final List<Class<? extends VFS>> USER_IMPLEMENTATIONS = new ArrayList<Class<? extends VFS>>();

    /** Singleton instance. */
    private static VFS instance;

    /**
     * Get the singleton {@link VFS} instance. If no {@link VFS} implementation can be found for the
     * current environment, then this method returns null.
     */
    @SuppressWarnings("unchecked")
    public static VFS getInstance() {
        if (instance != null) {
            return instance;
        }

        // Try the user implementations first, then the built-ins
        List<Class<? extends VFS>> impls = new ArrayList<Class<? extends VFS>>();
        impls.addAll(USER_IMPLEMENTATIONS);
        impls.addAll(Arrays.asList((Class<? extends VFS>[]) IMPLEMENTATIONS));

        // Try each implementation class until a valid one is found
        VFS vfs = null;
        for (int i = 0; vfs == null || !vfs.isValid(); i++) {
            Class<? extends VFS> impl = impls.get(i);
            try {
                vfs = impl.getDeclaredConstructor().newInstance();
                if (vfs == null || !vfs.isValid()) {
                    log.debug("VFS implementation " + impl.getName() + " is not valid in this environment.");
                }
            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException | NoSuchMethodException | SecurityException e) {
                log.error("Failed to instantiate " + impl, e);
                return null;
            }
        }

        log.debug("Using VFS adapter " + vfs.getClass().getName());
        return VFS.instance = vfs;
    }

    /**
     * Adds the specified class to the list of {@link VFS} implementations. Classes added in this
     * manner are tried in the order they are added and before any of the built-in implementations.
     * 
     * @param clazz The {@link VFS} implementation class to add.
     */
    public static void addImplClass(Class<? extends VFS> clazz) {
        if (clazz != null) {
            USER_IMPLEMENTATIONS.add(clazz);
        }
    }

    /** Get a class by name. If the class is not found then return null. */
    protected static Class<?> getClass(String className) {
        try {
            return Thread.currentThread().getContextClassLoader().loadClass(className);
            //      return ReflectUtil.findClass(className);
        } catch (ClassNotFoundException e) {
            log.debug("Class not found: " + className);
            return null;
        }
    }

    /**
     * Get a method by name and parameter types. If the method is not found then return null.
     * 
     * @param clazz The class to which the method belongs.
     * @param methodName The name of the method.
     * @param parameterTypes The types of the parameters accepted by the method.
     */
    protected static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
        try {
            if (clazz == null) {
                return null;
            } else {
                return clazz.getMethod(methodName, parameterTypes);
            }
        } catch (SecurityException e) {
            log.error("Security exception looking for method " + clazz.getName() + "." + methodName + ".  Cause: " + e);
            return null;
        } catch (NoSuchMethodException e) {
            log.error("Method not found " + clazz.getName() + "." + methodName + "." + methodName + ".  Cause: " + e);
            return null;
        }
    }

    /**
     * Invoke a method on an object and return whatever it returns.
     * 
     * @param method The method to invoke.
     * @param object The instance or class (for static methods) on which to invoke the method.
     * @param parameters The parameters to pass to the method.
     * @return Whatever the method returns.
     * @throws IOException If I/O errors occur
     * @throws StripesRuntimeException If anything else goes wrong
     */
    @SuppressWarnings("unchecked")
    protected static <T> T invoke(Method method, Object object, Object... parameters) throws IOException, RuntimeException {
        try {
            return (T) method.invoke(object, parameters);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            if (e.getTargetException() instanceof IOException) {
                throw (IOException) e.getTargetException();
            } else {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * Get a list of {@link URL}s from the context classloader for all the resources found at the
     * specified path.
     * 
     * @param path The resource path.
     * @return A list of {@link URL}s, as returned by {@link ClassLoader#getResources(String)}.
     * @throws IOException If I/O errors occur
     */
    protected static List<URL> getResources(String path) throws IOException {
        return Collections.list(Thread.currentThread().getContextClassLoader().getResources(path));
    }

    /** Return true if the {@link VFS} implementation is valid for the current environment. */
    public abstract boolean isValid();

    /**
     * Recursively list the full resource path of all the resources that are children of the
     * resource identified by a URL.
     * 
     * @param url The URL that identifies the resource to list.
     * @param forPath The path to the resource that is identified by the URL. Generally, this is the
     *            value passed to {@link #getResources(String)} to get the resource URL.
     * @return A list containing the names of the child resources.
     * @throws IOException If I/O errors occur
     */
    protected abstract List<String> list(URL url, String forPath) throws IOException;

    /**
     * Recursively list the full resource path of all the resources that are children of all the
     * resources found at the specified path.
     * 
     * @param path The path of the resource(s) to list.
     * @return A list containing the names of the child resources.
     * @throws IOException If I/O errors occur
     */
    public List<String> list(String path) throws IOException {
        List<String> names = new ArrayList<String>();
        for (URL url : getResources(path)) {
            names.addAll(list(url, path));
        }
        return names;
    }
}

/**
 * A default implementation of {@link VFS} that works for most application servers.
 * 
 * @author Ben Gunter
 */
class DefaultVFS extends VFS {
    private static final Log log = LogFactory.getLog(ClassUtils.class);

    /** The magic header that indicates a JAR (ZIP) file. */
    private static final byte[] JAR_MAGIC = { 'P', 'K', 3, 4 };

    @Override
    public boolean isValid() {
        return true;
    }

    @Override
    public List<String> list(URL url, String path) throws IOException {
        InputStream is = null;
        try {
            List<String> resources = new ArrayList<String>();

            // First, try to find the URL of a JAR file containing the requested resource. If a JAR
            // file is found, then we'll list child resources by reading the JAR.
            URL jarUrl = findJarForResource(url);
            if (jarUrl != null) {
                is = jarUrl.openStream();
                log.debug("Listing " + url);
                resources = listResources(new JarInputStream(is), path);
            } else {
                List<String> children = new ArrayList<String>();
                try {
                    if (isJar(url)) {
                        // Some versions of JBoss VFS might give a JAR stream even if the resource
                        // referenced by the URL isn't actually a JAR
                        is = url.openStream();
//                        @SuppressWarnings("resource")
                        JarInputStream jarInput = new JarInputStream(is);
                        log.debug("Listing " + url);
                        for (JarEntry entry; (entry = jarInput.getNextJarEntry()) != null;) {
                            log.debug("Jar entry: " + entry.getName());
                            children.add(entry.getName());
                        }
                    } else {
                        /*
                         * Some servlet containers allow reading from directory resources like a
                         * text file, listing the child resources one per line. However, there is no
                         * way to differentiate between directory and file resources just by reading
                         * them. To work around that, as each line is read, try to look it up via
                         * the class loader as a child of the current resource. If any line fails
                         * then we assume the current resource is not a directory.
                         */
                        is = url.openStream();
                        try(BufferedReader reader = new BufferedReader(new InputStreamReader(is))){
                            List<String> lines = new ArrayList<String>();
                            for (String line; (line = reader.readLine()) != null;) {
                                log.debug("Reader entry: " + line);
                                lines.add(line);
                                if (getResources(path + "/" + line).isEmpty()) {
                                    lines.clear();
                                    break;
                                }
                            }
    
                            if (!lines.isEmpty()) {
                                log.debug("Listing " + url);
                                children.addAll(lines);
                            }
                        };
                    }
                } catch (FileNotFoundException e) {
                    /*
                     * For file URLs the openStream() call might fail, depending on the servlet
                     * container, because directories can't be opened for reading. If that happens,
                     * then list the directory directly instead.
                     */
                    if ("file".equals(url.getProtocol())) {
                        File file = new File(url.getFile());
                        log.debug("Listing directory " + file.getAbsolutePath());
                        if (file.isDirectory()) {
                            log.debug("Listing " + url);
                            children = Arrays.asList(file.list());
                        }
                    } else {
                        // No idea where the exception came from so rethrow it
                        throw e;
                    }
                }

                // The URL prefix to use when recursively listing child resources
                String prefix = url.toExternalForm();
                if (!prefix.endsWith("/")) {
                    prefix = prefix + "/";
                }

                // Iterate over immediate children, adding files and recursing into directories
                for (String child : children) {
                    String resourcePath = path + "/" + child;
                    resources.add(resourcePath);
                    URL childUrl = new URL(prefix + child);
                    resources.addAll(list(childUrl, resourcePath));
                }
            }

            return resources;
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e) {}
        }
    }

    /**
     * List the names of the entries in the given {@link JarInputStream} that begin with the
     * specified {@code path}. Entries will match with or without a leading slash.
     * 
     * @param jar The JAR input stream
     * @param path The leading path to match
     * @return The names of all the matching entries
     * @throws IOException If I/O errors occur
     */
    protected List<String> listResources(JarInputStream jar, String path) throws IOException {
        // Include the leading and trailing slash when matching names
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        if (!path.endsWith("/")) {
            path = path + "/";
        }

        // Iterate over the entries and collect those that begin with the requested path
        List<String> resources = new ArrayList<String>();
        for (JarEntry entry; (entry = jar.getNextJarEntry()) != null;) {
            if (!entry.isDirectory()) {
                // Add leading slash if it's missing
                String name = entry.getName();
                if (!name.startsWith("/")) {
                    name = "/" + name;
                }

                // Check file name
                if (name.startsWith(path)) {
                    log.debug("Found resource: " + name);
                    resources.add(name.substring(1)); // Trim leading slash
                }
            }
        }
        return resources;
    }

    /**
     * Attempts to deconstruct the given URL to find a JAR file containing the resource referenced
     * by the URL. That is, assuming the URL references a JAR entry, this method will return a URL
     * that references the JAR file containing the entry. If the JAR cannot be located, then this
     * method returns null.
     * 
     * @param url The URL of the JAR entry.
     * @return The URL of the JAR file, if one is found. Null if not.
     * @throws MalformedURLException
     */
    protected URL findJarForResource(URL url) throws MalformedURLException {
        log.debug("Find JAR URL: " + url);

        // If the file part of the URL is itself a URL, then that URL probably points to the JAR
        try {
            for (;;) {
                url = new URL(url.getFile());
                log.debug("Inner URL: " + url);
            }
        } catch (MalformedURLException e) {
            // This will happen at some point and serves as a break in the loop
        }

        // Look for the .jar extension and chop off everything after that
        StringBuilder jarUrl = new StringBuilder(url.toExternalForm());
        int index = jarUrl.lastIndexOf(".jar");
        if (index >= 0) {
            jarUrl.setLength(index + 4);
            log.debug("Extracted JAR URL: " + jarUrl);
        } else {
            log.debug("Not a JAR: " + jarUrl);
            return null;
        }

        // Try to open and test it
        try {
            URL testUrl = new URL(jarUrl.toString());
            if (isJar(testUrl)) {
                return testUrl;
            } else {
                // WebLogic fix: check if the URL's file exists in the filesystem.
                log.debug("Not a JAR: " + jarUrl);
                jarUrl.replace(0, jarUrl.length(), testUrl.getFile());
                File file = new File(jarUrl.toString());

                // File name might be URL-encoded
                if (!file.exists()) {
                    try {
                        file = new File(URLEncoder.encode(jarUrl.toString(), EncodeUtils.UTF_8));
                    } catch (UnsupportedEncodingException e) {
                        throw new RuntimeException("Unsupported encoding?  UTF-8?  That's unpossible.");
                    }
                }

                if (file.exists()) {
                    log.debug("Trying real file: " + file.getAbsolutePath());
                    testUrl = file.toURI().toURL();
                    if (isJar(testUrl)) {
                        return testUrl;
                    }
                }
            }
        } catch (MalformedURLException e) {
            log.warn("Invalid JAR URL: " + jarUrl);
        }

        log.debug("Not a JAR: " + jarUrl);
        return null;
    }

    /**
     * Converts a Java package name to a path that can be looked up with a call to
     * {@link ClassLoader#getResources(String)}.
     * 
     * @param packageName The Java package name to convert to a path
     */
    protected String getPackagePath(String packageName) {
        return packageName == null ? null : packageName.replace('.', '/');
    }

    /**
     * Returns true if the resource located at the given URL is a JAR file.
     * 
     * @param url The URL of the resource to test.
     */
    protected boolean isJar(URL url) {
        return isJar(url, new byte[JAR_MAGIC.length]);
    }

    /**
     * Returns true if the resource located at the given URL is a JAR file.
     * 
     * @param url The URL of the resource to test.
     * @param buffer A buffer into which the first few bytes of the resource are read. The buffer
     *            must be at least the size of {@link #JAR_MAGIC}. (The same buffer may be reused
     *            for multiple calls as an optimization.)
     */
    protected boolean isJar(URL url, byte[] buffer) {
        InputStream is = null;
        try {
            is = url.openStream();
            is.read(buffer, 0, JAR_MAGIC.length);
            if (Arrays.equals(buffer, JAR_MAGIC)) {
                log.debug("Found JAR: " + url);
                return true;
            }
        } catch (Exception e) {
            // Failure to read the stream means this is not a JAR
        } finally {
            try {
                if (is != null){
                    is.close();
                }
            } catch (Exception e) {
                
            }
        }

        return false;
    }
}

/**
 * A {@link VFS} implementation that works with the VFS API provided by JBoss 6.
 * 
 * @author Ben Gunter
 */
class JBoss6VFS extends VFS {
    private static final Log log = LogFactory.getLog(ClassUtils.class);

    /** A class that mimics a tiny subset of the JBoss VirtualFile class. */
    static class VirtualFile {
        static Class<?> VirtualFile;
        static Method getPathNameRelativeTo, getChildrenRecursively;

        Object virtualFile;

        VirtualFile(Object virtualFile) {
            this.virtualFile = virtualFile;
        }

        String getPathNameRelativeTo(VirtualFile parent) {
            try {
                return invoke(getPathNameRelativeTo, virtualFile, parent.virtualFile);
            } catch (IOException e) {
                // This exception is not thrown by the called method
                log.error("This should not be possible. VirtualFile.getPathNameRelativeTo() threw IOException.");
                return null;
            }
        }

        List<VirtualFile> getChildren() throws IOException {
            List<?> objects = invoke(getChildrenRecursively, virtualFile);
            List<VirtualFile> children = new ArrayList<VirtualFile>(objects.size());
            for (Object object : objects) {
                children.add(new VirtualFile(object));
            }
            return children;
        }
    }

    /** A class that mimics a tiny subset of the JBoss VFS class. */
    static class VFS {
        static Class<?> VFS;
        static Method getChild;

        static VirtualFile getChild(URL url) throws IOException {
            Object o = invoke(getChild, VFS, url);
            return o == null ? null : new VirtualFile(o);
        }
    }

    /** Flag that indicates if this VFS is valid for the current environment. */
    private static Boolean valid;

    /** Find all the classes and methods that are required to access the JBoss 6 VFS. */
    protected static synchronized void initialize() {
        if (valid == null) {
            // Assume valid. It will get flipped later if something goes wrong.
            valid = true;

            // Look up and verify required classes
            VFS.VFS = checkNotNull(getClass("org.jboss.vfs.VFS"));
            VirtualFile.VirtualFile = checkNotNull(getClass("org.jboss.vfs.VirtualFile"));

            // Look up and verify required methods
            VFS.getChild = checkNotNull(getMethod(VFS.VFS, "getChild", URL.class));
            VirtualFile.getChildrenRecursively = checkNotNull(getMethod(VirtualFile.VirtualFile, "getChildrenRecursively"));
            VirtualFile.getPathNameRelativeTo = checkNotNull(getMethod(VirtualFile.VirtualFile, "getPathNameRelativeTo", VirtualFile.VirtualFile));

            // Verify that the API has not changed
            checkReturnType(VFS.getChild, VirtualFile.VirtualFile);
            checkReturnType(VirtualFile.getChildrenRecursively, List.class);
            checkReturnType(VirtualFile.getPathNameRelativeTo, String.class);
        }
    }

    /**
     * Verifies that the provided object reference is null. If it is null, then this VFS is marked
     * as invalid for the current environment.
     * 
     * @param object The object reference to check for null.
     */
    protected static <T> T checkNotNull(T object) {
        if (object == null) {
            setInvalid();
        }
        return object;
    }

    /**
     * Verifies that the return type of a method is what it is expected to be. If it is not, then
     * this VFS is marked as invalid for the current environment.
     * 
     * @param method The method whose return type is to be checked.
     * @param expected A type to which the method's return type must be assignable.
     * @see Class#isAssignableFrom(Class)
     */
    protected static void checkReturnType(Method method, Class<?> expected) {
        if (method != null && !expected.isAssignableFrom(method.getReturnType())) {
            log.error("Method " + method.getClass().getName() + "." + method.getName() + "(..) should return " + expected.getName() + " but returns " //
                    + method.getReturnType().getName() + " instead.");
            setInvalid();
        }
    }

    /** Mark this {@link VFS} as invalid for the current environment. */
    protected static void setInvalid() {
        if (JBoss6VFS.valid != null && JBoss6VFS.valid) {
            log.debug("JBoss 6 VFS API is not available in this environment.");
            JBoss6VFS.valid = false;
        }
    }

    static {
        initialize();
    }

    @Override
    public boolean isValid() {
        return valid;
    }

    @Override
    public List<String> list(URL url, String path) throws IOException {
        VirtualFile directory;
        directory = VFS.getChild(url);
        if (directory == null) {
            return Collections.emptyList();
        }

        if (!path.endsWith("/")) {
            path += "/";
        }

        List<VirtualFile> children = directory.getChildren();
        List<String> names = new ArrayList<String>(children.size());
        for (VirtualFile vf : children) {
            String relative = vf.getPathNameRelativeTo(directory);
            names.add(path + relative);
        }

        return names;
    }
}
View Code

 

12、ReflectUtils

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.poi.ss.usermodel.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jeesite.common.lang.DateUtils;
import com.jeesite.common.lang.ObjectUtils;

/**
 * 反射工具类.
 * 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
 */
@SuppressWarnings("rawtypes")
public class ReflectUtils {
    
    private static final String SETTER_PREFIX = "set";

    private static final String GETTER_PREFIX = "get";

    private static final String CGLIB_CLASS_SEPARATOR = "$$";
    
    private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class);
    
    private static Class baseEntityClass = null;

    /**
     * 调用Getter方法,
     * 支持多级,如:对象名.对象名.方法,
     * 支持静态类及方法调用,
     * 支持Map
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeGetter(Object obj, String propertyName) {
        Object object = obj;
        for (String name : StringUtils.split(propertyName, ".")){
            if (obj instanceof Map){
                object = ((Map)obj).get(name);
            }else{
                String methodName = GETTER_PREFIX + StringUtils.capitalize(name);
                object = invokeMethod(object, methodName, new Class[] {}, new Object[] {});
            }
        }
        return (E)object;
    }

    /**
     * 调用Setter方法,仅匹配方法名,
     * 支持多级,如:对象名.对象名.方法,
     * 支持静态类及方法调用,
     * 支持Map
     */
    @SuppressWarnings("unchecked")
    public static <E> void invokeSetter(Object obj, String propertyName, E value) {
        Object object = obj;
        String[] names = StringUtils.split(propertyName, ".");
        for (int i=0; i<names.length; i++){
            if(i<names.length-1){
                if (obj instanceof Map){
                    object = ((Map)obj).get(names[i]);
                }else{
                    String methodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);                            
                    Object childObj = invokeMethod(object, methodName, new Class[] {}, new Object[] {});
                    // 如果 get 获取对象为空,并且返回值类型继承自 BaseEntity,则 new 对象,并通过 set 赋予它
                    if (childObj == null && object != null){
                        Method method = getAccessibleMethod(object, methodName, new Class[] {});
                        if (method != null) {
                            Class<?> returnType = method.getReturnType();
                            try {
                                if (baseEntityClass == null) {
                                    baseEntityClass = Class.forName("com.jeesite.common.entity.BaseEntity");
                                }
                                if (baseEntityClass.isAssignableFrom(returnType)) {
                                    childObj = returnType.getDeclaredConstructor().newInstance();
                                    methodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
                                    invokeMethodByName(object, methodName, new Object[] { childObj });
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    object = childObj;
                }
            }else{
                if (obj instanceof Map){
                    ((Map)obj).put(names[i], value);
                }else{
                    String methodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
                    invokeMethodByName(object, methodName, new Object[] { value });
                }
            }
        }
    }
    
    /**
     * 直接读取对象属性值,无视private/protected修饰符,不经过getter函数
     */
    @SuppressWarnings("unchecked")
    public static <E> E getFieldValue(final Object obj, final String fieldName) {
        Field field = getAccessibleField(obj, fieldName);
        if (field == null) {
            //throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
            if (obj != null) {
                logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
            }
            return null;
        }
        E result = null;
        try {
            result = (E)field.get(obj);
        } catch (IllegalAccessException e) {
            logger.error("不可能抛出的异常: {}", e.getMessage());
        }
        return result;
    }

    /**
     * 直接设置对象属性值,无视private/protected修饰符,不经过setter函数
     */
    public static <E> void setFieldValue(final Object obj, final String fieldName, final E value) {
        Field field = getAccessibleField(obj, fieldName);
        if (field == null) {
            //throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
            logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
            return;
        }
        try {
            field.set(obj, value);
        } catch (IllegalAccessException e) {
            logger.error("不可能抛出的异常: {}", e.getMessage());
        }
    }

    /**
     * 直接调用对象方法,无视private/protected修饰符,
     * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用,
     * 同时匹配方法名+参数类型,
     * 支持静态类及方法调用
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
            final Object[] args) {
        if (obj == null || methodName == null){
            return null;
        }
        Method method = getAccessibleMethod(obj, methodName, parameterTypes);
        if (method == null) {
            //throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
            if (obj != null) {
                logger.debug("在 [" + (obj.getClass() == Class.class ? obj : obj.getClass()) + "] 中,没有找到 [" + methodName + "] 方法 ");
            }
            return null;
        }
        try {
            return (E)method.invoke(obj.getClass() == Class.class ? null : obj, args);
        } catch (Exception e) {
            String msg = "method: "+method+", obj: "+obj+", args: "+args+"";
            throw convertReflectionExceptionToUnchecked(msg, e);
        }
    }

    /**
     * 直接调用对象方法,无视private/protected修饰符,
     * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用,
     * 只匹配函数名,如果有多个同名函数调用第一个,
     * 支持静态类及方法调用
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
        Method method = getAccessibleMethodByName(obj, methodName, args.length);
        if (method == null) {
            // 如果为空不报错,直接返回空。
//            throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
            if (obj != null) {
                logger.debug("在 [" + (obj.getClass() == Class.class ? obj : obj.getClass()) + "] 中,没有找到 [" + methodName + "] 方法 ");
            }
            return null;
        }
        try {
            // 类型转换(将参数数据类型转换为目标方法参数类型)
            Class<?>[] cs = method.getParameterTypes();
            for (int i=0; i<cs.length; i++){
                if (args[i] != null && !args[i].getClass().equals(cs[i])){
                    if (cs[i] == String.class){
                        args[i] = ObjectUtils.toString(args[i]);
                        if(StringUtils.endsWith((String)args[i], ".0")){
                            args[i] = StringUtils.substringBefore((String)args[i], ".0");
                        }
                    }else if (cs[i] == Integer.class){
                        args[i] = ObjectUtils.toInteger(args[i]);
                    }else if (cs[i] == Long.class){
                        args[i] = ObjectUtils.toLong(args[i]);
                    }else if (cs[i] == Double.class){
                        args[i] = ObjectUtils.toDouble(args[i]);
                    }else if (cs[i] == Float.class){
                        args[i] = ObjectUtils.toFloat(args[i]);
                    }else if (cs[i] == Date.class){
                        if (args[i] instanceof String){
                            args[i] = DateUtils.parseDate(args[i]);
                        }else{
                            // POI Excel 日期格式转换
                            args[i] = DateUtil.getJavaDate((Double)args[i]);
                        }
                    }
                }
            }
            return (E)method.invoke(obj.getClass() == Class.class ? null : obj, args);
        } catch (Exception e) {
            String msg = "method: "+method+", obj: "+obj+", args: "+args+"";
            throw convertReflectionExceptionToUnchecked(msg, e);
        }
    }

    /**
     * 循环向上转型,获取对象的DeclaredField,并强制设置为可访问,
     * 如向上转型到Object仍无法找到,返回null
     */
    public static Field getAccessibleField(final Object obj, final String fieldName) {
        // 为空不报错。直接返回 null
        // Validate.notNull(obj, "object can't be null");
        if (obj == null){
            return null;
        }
        Validate.notBlank(fieldName, "fieldName can't be blank");
        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                Field field = superClass.getDeclaredField(fieldName);
                makeAccessible(field);
                return field;
            } catch (NoSuchFieldException e) {//NOSONAR
                // Field不在当前类定义,继续向上转型
                continue;// new add
            }
        }
        return null;
    }

    /**
     * 循环向上转型,获取对象的DeclaredMethod,并强制设置为可访问,
     * 如向上转型到Object仍无法找到,返回null,
     * 匹配函数名+参数类型。
     * 用于方法需要被多次调用的情况,先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
     */
    public static Method getAccessibleMethod(final Object obj, final String methodName,
            final Class<?>... parameterTypes) {
        // 为空不报错。直接返回 null
        // Validate.notNull(obj, "object can't be null");
        if (obj == null){
            return null;
        }
        Class<?> clazz = obj.getClass();
        if (clazz == Class.class){
            clazz = (Class) obj;
        }
        Validate.notBlank(methodName, "methodName can't be blank");
        for (Class<?> searchType = clazz; searchType != Object.class; searchType = searchType.getSuperclass()) {
            try {
                Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
                makeAccessible(method);
                return method;
            } catch (NoSuchMethodException e) {
                // Method不在当前类定义,继续向上转型
                continue;// new add
            }
        }
        return null;
    }

    /**
     * 循环向上转型,获取对象的DeclaredMethod,并强制设置为可访问,
     * 如向上转型到Object仍无法找到,返回null,
     * 只匹配函数名。
     * 用于方法需要被多次调用的情况,先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
     */
    public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) {
        // 为空不报错。直接返回 null
        // Validate.notNull(obj, "object can't be null");
        if (obj == null){
            return null;
        }
        Class<?> clazz = obj.getClass();
        if (clazz == Class.class){
            clazz = (Class) obj;
        }
        Validate.notBlank(methodName, "methodName can't be blank");
        for (Class<?> searchType = clazz; searchType != Object.class; searchType = searchType.getSuperclass()) {
            Method[] methods = searchType.getDeclaredMethods();
            for (Method method : methods) {
                if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) {
                    makeAccessible(method);
                    return method;
                }
            }
        }
        return null;
    }

    /**
     * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
     */
    public static void makeAccessible(Method method) {
        if ((!Modifier.isPublic(method.getModifiers())
                || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
                && !method.isAccessible()) {
            method.setAccessible(true);
        }
    }

    /**
     * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
     */
    public static void makeAccessible(Field field) {
        if ((!Modifier.isPublic(field.getModifiers())
                || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
                || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {
            field.setAccessible(true);
        }
    }

    /**
     * 通过反射,获得Class定义中声明的泛型参数的类型,注意泛型必须定义在父类处,
     * 如无法找到,返回Object.class,
     * 如 public UserDao extends CrudDao<User>
     * @param clazz The class to introspect
     * @return the first generic declaration, or Object.class if cannot be determined
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> getClassGenricType(final Class clazz) {
        return getClassGenricType(clazz, 0);
    }

    /**
     * 通过反射,获得Class定义中声明的父类的泛型参数的类型,
     * 如无法找到,返回Object.class,
     * 如 public UserDao extends CrudDao<User, Long>
     * @param clazz clazz The class to introspect
     * @param index the Index of the generic ddeclaration,start from 0.
     * @return the index generic declaration, or Object.class if cannot be determined
     */
    public static Class getClassGenricType(final Class clazz, final int index) {
        Type genType = clazz.getGenericSuperclass();
        if (!(genType instanceof ParameterizedType)) {
            logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType");
            return Object.class;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0) {
            logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
                    + params.length);
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
            return Object.class;
        }
        return (Class) params[index];
    }
    
    /**
     * 获取类的Class,如果为内部类,则返回上级类Class
     */
    public static Class<?> getUserClass(Object instance) {
        if (instance == null){
            throw new RuntimeException("Instance must not be null");
        }
        Class clazz = instance.getClass();
        if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
            Class<?> superClass = clazz.getSuperclass();
            if (superClass != null && !Object.class.equals(superClass)) {
                return superClass;
            }
        }
        return clazz;

    }
    
    /**
     * 将反射时的checked exception转换为unchecked exception
     */
    public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) {
        if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
                || e instanceof NoSuchMethodException) {
            return new IllegalArgumentException(msg, e);
        } else if (e instanceof InvocationTargetException) {
            return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException());
        }
        return new RuntimeException(msg, e);
    }
}
View Code

 

13、ObjectUtils

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.nustaq.serialization.FSTConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.NamedThreadLocal;

/**
 * 对象操作工具类,继承 org.apache.commons.lang3.ObjectUtils 类
 * @author ThinkGem
 * @version 2020-3-29
 */
public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {

    private static Logger logger = LoggerFactory.getLogger(ObjectUtils.class);
    private static final boolean isJavaSerialize; 
    
    static {
        String[] ver = StringUtils.split(System.getProperty("java.version"), '.');
        isJavaSerialize = ver.length > 0 && Integer.parseInt(ver[0]) > 1;
    }
    
    /**
     * 转换为 Double 类型
     */
    public static Double toDouble(final Object val) {
        if (val == null) {
            return 0D;
        }
        try {
            String str = val.toString();
            if (StringUtils.contains(str, "*")) {
                Double number = null, d = null;
                for (String s : StringUtils.split(str, "*")) {
                    d = Double.parseDouble(StringUtils.trim(s));
                    if (number == null) {
                        number = d;
                    } else {
                        number *= d;
                    }
                }
                return number;
            }
            return Double.parseDouble(StringUtils.trim(str));
        } catch (Exception e) {
            return 0D;
        }
    }

    /**
     * 转换为 Float 类型
     */
    public static Float toFloat(final Object val) {
        return toDouble(val).floatValue();
    }

    /**
     * 转换为 Long 类型
     */
    public static Long toLong(final Object val) {
        return toDouble(val).longValue();
    }

    /**
     * 转换为 Integer 类型
     */
    public static Integer toInteger(final Object val) {
        return toDouble(val).intValue();
    }

    /**
     * 转换为 Boolean 类型 'true', 'on', 'y', 't', 'yes' or '1'
     *  (case insensitive) will return true. Otherwise, false is returned.
     */
    public static Boolean toBoolean(final Object val) {
        if (val == null) {
            return false;
        }
        return BooleanUtils.toBoolean(val.toString()) || "1".equals(val.toString());
    }

    /**
     * 转换为字符串
     */
    public static String toString(final Object obj) {
        return toString(obj, StringUtils.EMPTY);
    }

    /**
     * 转换为字符串,如果对象为空,则使用 defaultVal 值
     */
    public static String toString(final Object obj, final String defaultVal) {
        return obj == null ? defaultVal : obj.toString();
    }

    /**
     * 转换为字符串,忽略空值。如 null 字符串,则被认为空值,如下:
     *         "" to "" ; null to "" ; "null" to "" ; "NULL" to "" ; "Null" to ""
     */
    public static String toStringIgnoreNull(final Object val) {
        return ObjectUtils.toStringIgnoreNull(val, StringUtils.EMPTY);
    }

    /**
     * 转换为字符串,忽略空值。如 null 字符串,则被认为空值,如下:
     *         "" to defaultVal ; null to defaultVal ; "null" to defaultVal ; "NULL" to defaultVal ; "Null" to defaultVal
     */
    public static String toStringIgnoreNull(final Object val, String defaultVal) {
        String str = ObjectUtils.toString(val);
        return !"".equals(str) && !"null".equals(str.trim().toLowerCase()) ? str : defaultVal;
    }

    /**
     * 拷贝一个对象(但是子对象无法拷贝)
     * @param source
     * @param ignoreProperties
     */
    public static Object copyBean(Object source, String... ignoreProperties){
        if (source == null){
            return null;
        }
        try {
            Object target = source.getClass().getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(source, target, ignoreProperties);
            return target;
        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                | InvocationTargetException | NoSuchMethodException | SecurityException e) {
            throw ExceptionUtils.unchecked(e);
        }
    }
    
    /**
     * 克隆一个对象(完全拷贝)
     * @param source
     */
    public static Object cloneBean(Object source){
        if (source == null){
            return null;
        }
        byte[] bytes = ObjectUtils.serialize(source);
        Object target = ObjectUtils.unserialize(bytes);
        return target;
    }
    
    /**
     * 序列化对象
     * @param object
     * @return
     */
    public static byte[] serialize(Object object) {
        try {
            if (isJavaSerialize) {
                return ObjectUtils.serializeJava(object);
            }else {
                return ObjectUtils.serializeFst(object);
            }
        } catch (Exception e) {
            logger.error("serialize", e);
        }
        return null;
    }

    /**
     * 反序列化对象
     * @param bytes
     * @return
     */
    public static Object unserialize(byte[] bytes) {
        try {
            if (isJavaSerialize) {
                return ObjectUtils.unserializeJava(bytes);
            }else {
                return ObjectUtils.unserializeFst(bytes);
            }
        } catch (Exception e) {
            logger.error("unserialize", e);
        }
        return null;
    }
    
    /**
     * 序列化对象
     * @param object
     * @return
     */
    public static byte[] serializeJava(Object object) {
        if (object == null){
            return null;
        }
        long beginTime = System.currentTimeMillis();
        byte[] bytes = null;
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);) {
            oos.writeObject(object);
            bytes = baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        long totalTime = System.currentTimeMillis() - beginTime;
        if (totalTime > 30000){
            logger.warn(object.getClass() + " serialize time: " + TimeUtils.formatDateAgo(totalTime));
        }
        return bytes;
    }

    /**
     * 反序列化对象
     * @param bytes
     * @return
     */
    public static Object unserializeJava(byte[] bytes) {
        if (bytes == null){
            return null;
        }
        long beginTime = System.currentTimeMillis();
        Object object = null;
        if (bytes.length > 0) {
            try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
                    ObjectInputStream ois = new ObjectInputStream(bais);) {
                object = ois.readObject();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        long totalTime = System.currentTimeMillis() - beginTime;
        if (totalTime > 30000 && object != null){
            logger.warn(object.getClass() + " unserialize time: " + TimeUtils.formatDateAgo(totalTime));
        }
        return object;
    }
    
    private static ThreadLocal<FSTConfiguration> fstConfiguration = 
                new NamedThreadLocal<FSTConfiguration>("FSTConfiguration") {
        public FSTConfiguration initialValue() {
            return FSTConfiguration.createDefaultConfiguration();
        }
    };

    /**
     * FST 序列化对象
     * @param object
     * @return
     */
    public static byte[] serializeFst(Object object) {
        if (object == null){
            return null;
        }
        long beginTime = System.currentTimeMillis();
        byte[] bytes = fstConfiguration.get().asByteArray(object);
        long totalTime = System.currentTimeMillis() - beginTime;
        if (totalTime > 30000){
            logger.warn(object.getClass() + " fst serialize time: " + TimeUtils.formatDateAgo(totalTime));
        }
        return bytes;
    }

    /**
     * FST 反序列化对象
     * @param bytes
     * @return
     */
    public static Object unserializeFst(byte[] bytes) {
        if (bytes == null){
            return null;
        }
        long beginTime = System.currentTimeMillis();
        Object object = fstConfiguration.get().asObject(bytes);
        long totalTime = System.currentTimeMillis() - beginTime;
        if (totalTime > 30000 && object != null){
            logger.warn(object.getClass() + " fst unserialize time: " + TimeUtils.formatDateAgo(totalTime));
        }
        return object;
    }
    
}
View Code

 

14、MDCUtil

import org.slf4j.MDC;

/**
 * 日志相关工具类
 */
public class MDCUtil {
    private MDCUtil() {
    }

    private static final String STR_THREAD_ID = "traceId";

    /**
     * 初始化日志参数并保存在线程副本中
     */
    public static void init() {
        String uuid = StringUtil.getUUID();
        MDC.put(STR_THREAD_ID, uuid);
    }

    /**
     * 移除线程号和线程副本
     */
    public static void remove() {
        MDC.remove(STR_THREAD_ID);
    }

}
View Code

 

15、

查看代码

import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;

public class MacUtil {
    /**
     * 获取本机的Mac地址
     *
     * @return
     */
    public static String getMac() {
        try {
            Process proces = Runtime.getRuntime().exec("ifconfig /all");
            InputStreamReader ir = new InputStreamReader(proces.getInputStream());
            LineNumberReader lnr = new LineNumberReader(ir);
            String line;
            while ((line = lnr.readLine()) != null) {
                if (line.indexOf("PhysicalAddress") > 0) {
                    String macAddr = line.substring(line.indexOf("-") - 2);
                    return macAddr;
                }
            }
        } catch (Exception e) {

        }
        return null;
    }

    private static String getMACAddress() throws UnknownHostException, SocketException {
        // 获取本机的InetAddress对象
        InetAddress inetAddress = InetAddress.getLocalHost();
        // 获得网络接口对象(即网卡),并得到mac地址,mac地址存在于一个byte数组中
        byte[] mac = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();
        // 下面代码是把mac地址拼装成String
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < mac.length; i++) {
            if (i != 0) {
                sb.append("-");
            }
            // mac[i] & 0xFF 是为了把byte转化为正整数
            String s = Integer.toHexString(mac[i] & 0xFF);
            sb.append(s.length() == 1 ? 0 + s : s);
        }
        // 把字符串所有小写字母改为大写成为正规的mac地址并返回
        return sb.toString().toUpperCase();
    }

    public static void main(String[] args) throws SocketException, UnknownHostException {
        String mac = getMACAddress();
        System.out.println(mac);
    }
}

 

END.

posted @ 2021-02-04 16:19  杨岂  阅读(141)  评论(0编辑  收藏  举报