高质量java常用util类

自定义断言工具类

package com.wlc.doc.util;

import com.wlc.doc.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.Map;

/**
 * 描述: 老王专用断言 </br>
 * 时间: 2021-02-25 9:28  </br>
 * 作者:王林冲
 */
@Slf4j
public class AssertUtil extends Assert {

    /**
     * 期望值是等于,不满足期望,则抛异常
     * @param o1 值1
     * @param o2 值2
     * @param message 异常消息
     */
    public static void isEquals(Object o1, Object o2 ,String message) {
        if (!o1.toString().equals(o2.toString())) {
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值是不等于,不满足期望,则抛异常
     * @param o1 值1
     * @param o2 值2
     * @param message 异常消息
     */
    public static void isNotEquals(Object o1, Object o2 ,String message) {
        if (o1.toString().equals(o2.toString())) {
            throw new BusinessException(message);
        }
    }
    /**
     * 期望值等于true,不满足期望值即expression = false,则抛异常
     * @param expression 表达式boolean值
     * @param message 异常消息
     * @param logInfo 异常日志打印对象
     */
    public static void isTrue(boolean expression, String message, Object logInfo) {
        if (!expression) {
            if (!ObjectUtils.isEmpty(logInfo)){
                log.error(logInfo.toString());
            }
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值等于true,不满足期望值即expression = false,则抛异常
     * @param expression 表达式boolean值
     * @param message 异常消息
     */
    public static void isTrue(boolean expression, String message) {
        if (!expression) {
            throw new BusinessException(message);
        }
    }
    /**
     * 期望值等于true,不满足期望值即expression = false,则抛异常
     * @param expression 表达式boolean值
     * @param message 异常消息
     */
    public static void isNotTrue(boolean expression, String message) {
        if (expression) {
            throw new BusinessException(message);
        }
    }
    /**
     * 期望值等于true,不满足期望值即expression = false,则抛异常
     * @param expression 表达式boolean值
     * @param message 异常消息
     * @param logInfo 异常日志打印对象
     */
    public static void isNotTrue(boolean expression, String message, Object logInfo) {
        if (expression) {
            if (!ObjectUtils.isEmpty(logInfo)){
                log.error(logInfo.toString());
            }
            throw new BusinessException(message);
        }
    }
    /**
     * 期望值object = null,若object != null,则抛异常
     * @param object 判断对象
     * @param message 异常消息
     * @param logInfo 异常日志
     */
    public static void isNull(@Nullable Object object, String message, Object logInfo) {
        if (object != null) {
            if (!ObjectUtils.isEmpty(logInfo)){
                log.error(logInfo.toString());
            }
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值object = null,若object != null,则抛异常
     * @param object 判断对象
     * @param message 异常消息
     */
    public static void isNull(@Nullable Object object, String message) {
        if (object != null) {
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值object != null,若object == null,则抛异常
     * @param object 判断对象
     * @param message 异常消息
     * @param logInfo 异常日志
     */
    public static void notNull(@Nullable Object object, String message, Object logInfo) {
        if (object == null) {
            if (!ObjectUtils.isEmpty(logInfo)){
                log.error(logInfo.toString());
            }
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值object != null,若object == null,则抛异常
     * @param object 判断对象
     * @param message 异常消息
     */
    public static void notNull(@Nullable Object object, String message) {
        if (ObjectUtils.isEmpty(object)) {
            throw new BusinessException(message);
        }
    }

    /**
     * textToSearch字符串是否包含 substring ,期望不包含
     * @param textToSearch 大区间str
     * @param substring  小区间str
     * @param message 异常消息
     * @param logInfo 打印日志对象
     */
    public static void doesNotContain(@Nullable String textToSearch, String substring, String message, Object logInfo) {
        if (StringUtils.hasLength(textToSearch) && StringUtils.hasLength(substring) && textToSearch.contains(substring)) {
            if (!ObjectUtils.isEmpty(logInfo)){
                log.error(logInfo.toString());
            }
            throw new BusinessException(message);
        }
    }
    /**
     * textToSearch字符串是否包含 substring ,期望不包含
     * @param textToSearch 大区间str
     * @param substring  小区间str
     * @param message 异常消息
     */
    public static void doesNotContain(@Nullable String textToSearch, String substring, String message) {
        if (StringUtils.hasLength(textToSearch) && StringUtils.hasLength(substring) && textToSearch.contains(substring)) {
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值不为空
     * @param array 判断对象数组
     * @param message 异常消息
     */
    public static void notEmpty(@Nullable Object[] array, String message) {
        if (ObjectUtils.isEmpty(array)) {
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值不为空
     * @param array 判断对象数组
     * @param message 异常消息
     * @param logInfo 输出日志对象
     */
    public static void notEmpty(@Nullable Object[] array, String message, Object logInfo) {
        if (ObjectUtils.isEmpty(array)) {
            if (!ObjectUtils.isEmpty(logInfo)){
                log.error(logInfo.toString());
            }
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值不为空
     * @param collection 判断集合
     * @param message 异常消息提醒
     * @param logInfo 打印异常日志对象
     */
    public static void notEmpty(@Nullable Collection<?> collection, String message, Object logInfo) {
        if (CollectionUtils.isEmpty(collection)) {
            if (!ObjectUtils.isEmpty(logInfo)){
                log.error(logInfo.toString());
            }
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值不为空
     * @param collection 判断集合
     * @param message 异常消息提醒
     */
    public static void notEmpty(@Nullable Collection<?> collection, String message) {
        if (CollectionUtils.isEmpty(collection)) {
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值不为空
     * @param map 判断map
     * @param message 异常消息提醒
     * @param logInfo 打印异常日志对象
     */
    public static void notEmpty(@Nullable Map<?, ?> map, String message, Object logInfo) {
        if (CollectionUtils.isEmpty(map)) {
            if (!ObjectUtils.isEmpty(logInfo)){
                log.error(logInfo.toString());
            }
            throw new BusinessException(message);
        }
    }

    /**
     * 期望值不为空
     * @param map 异常消息提醒
     * @param message 异常消息提醒
     */
    public static void notEmpty(@Nullable Map<?, ?> map, String message) {
        if (CollectionUtils.isEmpty(map)) {
            throw new BusinessException(message);
        }
    }

}

bean 拷贝工具类

package com.wlc.doc.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述: bean 拷贝工具类 </br>
 * 时间: 2021-02-25 9:28  </br>
 * 作者:王林冲
 */
public class BeanCopierUtil {
    private static final Logger log = LoggerFactory.getLogger(BeanCopierUtil.class);

    /**
     * BeanCopier缓存
     */
    private static Map<String, BeanCopier> beanCopierCacheMap = new HashMap<>();

    /**
     * 将source对象的属性拷贝到target对象中去
     */
    public static void copyProperties(Object source, Object target) {
        String cacheKey = source.getClass().toString() + target.getClass().toString();
        if (!beanCopierCacheMap.containsKey(cacheKey)) {
            synchronized (BeanCopierUtil.class) {
                if (!beanCopierCacheMap.containsKey(cacheKey)) {
                    BeanCopier beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
                    beanCopierCacheMap.put(cacheKey, beanCopier);
                }
            }
        }
        beanCopierCacheMap.get(cacheKey).copy(source, target, null);
    }

    /**
     * 对象拷贝
     */
    public static <T> T copyProperties(Object source, Class<T> clazz) {
        T target = null;
        try {
            target = clazz.newInstance();
            BeanCopierUtil.copyProperties(source, target);
        } catch (Exception e) {
            log.error("error", e);
        }
        return target;
    }

    /**
     * 列表复制
     */
    public static <T> List<T> copyList(List source, Class<T> clazz) {
        List<T> target = new ArrayList<>();
        if (!CollectionUtils.isEmpty(source)) {
            for (Object c : source) {
                T obj = copyProperties(c, clazz);
                target.add(obj);
            }
        }
        return target;
    }
}

基于jackson的JsonUtil

package com.utils;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
/**
 * @author 王林冲
 * @date 2018/12/24 11:21 上午
 */
public class JsonUtil {

    public static final ObjectMapper OBJECT_MAPPER = createObjectMapper();
    /**
     * 初始化ObjectMapper
     * @return
     */
    private static ObjectMapper createObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
        // 允许序列化空的POJO类(否则会抛出异常)
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 对象的所有字段全部列入。NON_NULL:不返回 null 值字段
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        // 取消java.util.Date, Calendar默认转换timestamps形式
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS , false);
        objectMapper.registerModule(new JavaTimeModule());
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
        return objectMapper;
    }

    public static String object2Json(Object o) {
        StringWriter sw = new StringWriter();
        JsonGenerator gen = null;
        try {
            gen = new JsonFactory().createGenerator(sw);
            OBJECT_MAPPER.writeValue(gen, o);
        } catch (IOException e) {
            throw new RuntimeException("不能序列化对象为Json", e);
        } finally {
            if (null != gen) {
                try {
                    gen.close();
                } catch (IOException e) {
                    throw new RuntimeException("不能序列化对象为Json", e);
                }
            }
        }
        return sw.toString();
    }

    /**
     * 对象转map
     * @param o 转行对象
     * @return
     */
    public static Map<String, Object> object2Map(Object o) {
        return OBJECT_MAPPER.convertValue(o,Map.class);
    }

    /**
     * map转java对象
     * @param map 参数map
     * @param clazz T字节对象
     * @param <T> 返回对象类型
     * @return
     */
    public static <T> T map2Object(Map map, Class<T> clazz) {
        return OBJECT_MAPPER.convertValue(map,clazz);
    }


    /**
     * 将 json 字段串转换为 对象.
     *
     * @param json  字符串
     * @param clazz 需要转换为的类
     * @return
     */
    public static <T> T json2Object(String json, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (IOException e) {
            throw new RuntimeException("将 Json 转换为对象时异常,数据是:" + json, e);
        }
    }

    /**
     *   将 json 字段串转换为 List.
     * @param json
     * @param clazz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<T> json2List(String json,Class<T> clazz) throws IOException {
        JavaType type = OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz);
        return OBJECT_MAPPER.readValue(json, type);
    }


    /**
     *  将 json 字段串转换为 数据.
     * @param json
     * @param clazz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T>  T[] json2Array(String json,Class<T[]> clazz) throws IOException {
        return OBJECT_MAPPER.readValue(json, clazz);

    }

    public static <T> T node2Object(JsonNode jsonNode, Class<T> clazz) {
        try {
            T t = OBJECT_MAPPER.treeToValue(jsonNode, clazz);
            return t;
        } catch (JsonProcessingException e) {
            throw new RuntimeException("将 Json 转换为对象时异常,数据是:" + jsonNode.toString(), e);
        }
    }

    public static JsonNode object2Node(Object o) {
        try {
            if(o == null) {
                return OBJECT_MAPPER.createObjectNode();
            } else {
                return OBJECT_MAPPER.convertValue(o, JsonNode.class);
            }
        } catch (Exception e) {
            throw new RuntimeException("不能序列化对象为Json", e);
        }
    }

    /**
     * JsonNode转换为Java泛型对象,可以是各种类型。
     *
     * @param <T>
     * @param json String
     * @param tr TypeReference,例如: new TypeReference< List<FamousUser> >(){}
     * @return List对象列表
     */
    public static <T> T json2GenericObject(String json, TypeReference<T> tr) {
        if (json == null || "".equals(json)) {
            throw new RuntimeException("将 Json 转换为对象时异常,数据是:" + json);
        } else {
            try {
                return (T) OBJECT_MAPPER.readValue(json, tr);
            } catch (Exception e) {
                throw new RuntimeException("将 Json 转换为对象时异常,数据是:" + json, e);
            }
        }
    }

}

request请求util

package com.wlc.doc.util;

import cn.hutool.core.util.StrUtil;
import com.google.common.base.Joiner;
import com.sun.istack.internal.NotNull;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 描述: request请求util </br>
 * 时间: 2022-02-08 11:22  </br>
 * 作者:王林冲
 */
public class RequestUtil {
    /**
     * 获取请求的路径,包含controller的映射和方法映射和路径参数
     * @param request
     * @param response
     * @return
     */
    public static String getServletPath(HttpServletRequest request, HttpServletResponse response){
        return request.getServletPath();
    }

    /**
     * 获取真实Url,包含controller的映射和方法映射,去除path的参数
     * @param handler
     * @param url
     * @return
     */
    public static String getRealUrl(Object handler, String url){
        Annotation[][] parameterAnnotations = ((HandlerMethod) handler).getMethod().getParameterAnnotations();
        int i = 0;
        for (Annotation[] annotations : parameterAnnotations) {
            for (Annotation annotation : annotations) {
                if(annotation instanceof PathVariable){
                    i++;
                    break;
                }
            }
        }
        if (i == 0){
            return url;
        }
        List<String> split = Arrays.asList(url.split("\\/"));
        List<String> subList = split.subList(0, split.size() - i);
        String join = Joiner.on("/").join(subList);
        return join;
    }

    /**
     * 获取请求的路径映射,包含controller的映射和方法映射,失灵时不灵
     * @param request
     * @param response
     * @return
     */
    public static String getServletRequestMapping(HttpServletRequest request, HttpServletResponse response){
        String servletPath = getServletPath(request, response);
        //Map<String, String[]> parameterMap = getParameterMap(request, response);
        Map<String, String[]> parameterMap = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
        if (CollectionUtils.isEmpty(parameterMap)){
            return servletPath;
        }
        Integer paramSize = parameterMap.size();
        int count = StrUtil.count(servletPath, "/");
        int subIndex = StrUtil.ordinalIndexOf(servletPath,"/", count - paramSize + 1);
        String result = servletPath.substring(0, subIndex);
        return result;
    }

    /**
     * 获取请求的路径的所有参数map
     * @param request
     * @param response
     * @return
     */
    public static Map<String, String[]> getParameterMap(HttpServletRequest request, HttpServletResponse response){
        return request.getParameterMap();
    }

    /**
     * 获取请求的路径的指定参数的value数组
     * @param paramKey 请求的路径的参数key
     * @param request 请求
     * @param response 响应
     * @return
     */
    public static String[] getParameterArrayByParamKey(@NotNull String paramKey, HttpServletRequest request, HttpServletResponse response){
        Map<String, String[]> parameterMap = getParameterMap(request, response);
        for (String key : parameterMap.keySet()) {
            if (key.equals(paramKey)){
               return parameterMap.get(key);
            }
        }
        return null;
    }
    /**
     * 获取请求的路径的指定参数的value数组中第index的值
     * @param paramKey 请求的路径的参数key
     * @param request 请求
     * @param response 响应 getFirstParameterByParamKey
     * @return
     */
    public static String getIndexParameterByParamKey(@NotNull String paramKey, int index, HttpServletRequest request, HttpServletResponse response){
        String[] parameterArray = getParameterArrayByParamKey(paramKey, request, response);
        for (int i = 0, length = parameterArray.length; i < length; i++ ){
            if (i == index){
                return parameterArray[i];
            }
        }
        return null;
    }

    /**
     * 获取请求的路径的指定参数的value数组中第index的值
     * @param paramKey 请求的路径的参数key
     * @param request 请求
     * @param response 响应
     * @return
     */
    public static String getFirstParameterByParamKey(@NotNull String paramKey, HttpServletRequest request, HttpServletResponse response){
        return getIndexParameterByParamKey(paramKey, 0, request, response);
    }



}

随机编码util,适合唯一兑换码场景

package com.wlc.doc.util;

import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

/**
 * 描述: 随机编码util </br>
 * 时间: 2021-07-15 18:55  </br>
 * 作者:王林冲
 */
public class RnUtil {


    /**
     * 最大值
     */
    public static final long MAX = 1220096908800L; // 36*35*34*33*32*31*30*29


    /**
     * 乘法用的素数
     */
    public static final long P = 982451653L;

    /**
     * 加法用的素数
     */
    public static final long Q = 9007;

    /**
     * 编码长度
     */
    public static final int LEN = 8;

    /**
     * 采用33进制
     */
    public static final int RADIX = 33;

    public static List<Character> originalCharList = new LinkedList<Character>();

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

    static {
        if (CollectionUtils.isEmpty(originalCharList)) {
            for (char c : cb) {
                originalCharList.add(c);
            }
        }
    }

    /**
     * 编码方法。
     *
     * @param number 序号
     * @return 8位编码
     * @throws IllegalArgumentException 如果序号超过范围
     */
    public static String encode(long number) {
        if (number <= 0 || number > MAX) {
            throw new IllegalArgumentException();
        }
        long x = (number * P + Q) % MAX;

        return encode0(x, LEN);
    }

    private static String encode0(long x, int length) {
        List<Character> list = new LinkedList<Character>();
//        for (int i = 0; i < RADIX; i++) {
//            list.add(Character.toUpperCase(Character.forDigit(i, RADIX)));
//        }
        list.addAll(originalCharList);
        char[] codes = new char[length];
        int radix = RADIX;
        for (int i = length; i-- > 0; ) {
            int n = (int) (x % radix);
            codes[i] = list.remove(n);
            x /= radix;
            radix--;
        }

        return new String(codes);
    }


    /**
     * @param startNum 起始序列号
     * @param length   获取多少个唯一8位的字符串
     * @return java.util.HashSet<java.lang.String>
     * @author zy
     * @date 2021/7/15
     */
    public static HashSet<String> getUkNumByLength(Long startNum, Integer length) {
        AssertUtil.isTrue(!ObjectUtils.isEmpty(startNum), "startNum不能为空");
        AssertUtil.isTrue((!ObjectUtils.isEmpty(length) || length != 0), "length不能为空或者length=0");
        HashSet<String> hashSet = new HashSet<>(length);
        long startIndex = startNum + 1;
        long endIndex = startIndex + length;
        for (long i = startIndex; i < endIndex; i++) {
            hashSet.add(encode(i));
        }
        return hashSet;
    }

    /**
     * 编码方法。
     *
     * @param number 序号
     * @param length 生成的字符串长度
     * @return 8位编码
     * @throws IllegalArgumentException 如果序号超过范围
     */
    public static String encode(long number, int length) {
        if (number <= 0 || number > MAX) {
            throw new IllegalArgumentException();
        }
        long x = (number * P + Q) % MAX;

        return encode0(x, length);
    }

}

分布式自增ID雪花算法

package com.wlc.doc.util;

import org.springframework.stereotype.Component;

import java.text.ParseException;

/**
 * 描述: Twitter的分布式自增ID雪花算法 </br>
 * 时间: 2021-07-15 18:55  </br>
 * 作者:王林冲
 */
@Component
public class SnowFlake {

    /**
     * 起始的时间戳
     */
    private final static long START_STMP = 1609459200000L; // 2021-01-01 00:00:00

    /**
     * 每一部分占用的位数
     */
    private final static long SEQUENCE_BIT = 12; //序列号占用的位数
    private final static long MACHINE_BIT = 5;   //机器标识占用的位数
    private final static long DATACENTER_BIT = 5;//数据中心占用的位数

    /**
     * 每一部分的最大值
     */
    private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
    private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);

    /**
     * 每一部分向左的位移
     */
    private final static long MACHINE_LEFT = SEQUENCE_BIT;
    private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
    private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;

    private long datacenterId = 1;  //数据中心
    private long machineId = 1;     //机器标识
    private long sequence = 0L; //序列号
    private long lastStmp = -1L;//上一次时间戳

    public SnowFlake() {
    }

    public SnowFlake(long datacenterId, long machineId) {
        if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
            throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
        }
        if (machineId > MAX_MACHINE_NUM || machineId < 0) {
            throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
        }
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }

    /**
     * 产生下一个ID
     *
     * @return
     */
    public synchronized long nextId() {
        long currStmp = getNewstmp();
        if (currStmp < lastStmp) {
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        }

        if (currStmp == lastStmp) {
            //相同毫秒内,序列号自增
            sequence = (sequence + 1) & MAX_SEQUENCE;
            //同一毫秒的序列数已经达到最大
            if (sequence == 0L) {
                currStmp = getNextMill();
            }
        } else {
            //不同毫秒内,序列号置为0
            sequence = 0L;
        }

        lastStmp = currStmp;

        return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
                | datacenterId << DATACENTER_LEFT       //数据中心部分
                | machineId << MACHINE_LEFT             //机器标识部分
                | sequence;                             //序列号部分
    }

    private long getNextMill() {
        long mill = getNewstmp();
        while (mill <= lastStmp) {
            mill = getNewstmp();
        }
        return mill;
    }

    private long getNewstmp() {
        return System.currentTimeMillis();
    }

    public static void main(String[] args) throws ParseException {
        // 时间戳
        // System.out.println(System.currentTimeMillis());
        // System.out.println(new Date().getTime());
        //
        // String dateTime = "2021-01-01 08:00:00";
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        // System.out.println(sdf.parse(dateTime).getTime());

        SnowFlake snowFlake = new SnowFlake(1, 1);

        long start = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            System.out.println(snowFlake.nextId());
            System.out.println(System.currentTimeMillis() - start);
        }
    }
}

 IP的util

package com.utils;

import jodd.util.StringUtil;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.*;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** 
 * 描述: 获取ip帮助类 				<br>
 * 作者: wlc 						<br>
 * 实践: 2019年12月5日 下午4:41:58 	<br>
 */
public class IPUtil {
	private static final String UNKNOWN = "unknown";

	private static final Pattern PATTERN = Pattern.compile("^((2([0-4]\\d|5[0-5])|[01]?\\d{1,2})\\.){3}(2([0-4]\\d|5[0-5])|[01]?\\d{1,2})$");

	protected IPUtil(){

	}

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



	/**
	 * ip转换成long
	 *
	 * @param ip ip
	 * @return long
	 */
	public static Long ipToLong(String ip) {
		//校验ip是否正确
		Matcher matcher = PATTERN.matcher(ip);
		if (!matcher.find()) {
			throw new RuntimeException("ip 格式不正确");
		}
		String[] split = ip.split("\\.");
		return (Long.parseLong(split[0]) << 24) + (Long.parseLong(split[1]) << 16)
				+ (Long.parseLong(split[2]) << 8) + Long.parseLong(split[3]);
	}

	/**
	 * 将long类型转换成ip
	 *
	 * @param ipLong ip的long类型
	 * @return ip
	 */
	public static String longToIp(Long ipLong) {
		StringBuilder ip = new StringBuilder();
		ip.append(ipLong >>> 24).append(".");
		ip.append((ipLong >>> 16) & 0xFF).append(".");
		ip.append((ipLong >>> 8) & 0xFF).append(".");
		ip.append(ipLong & 0xFF);
		return ip.toString();
	}

	/**
	 * 检查是否为内部IP地址
	 *
	 * @param ip IP地址
	 * @return 结果
	 */
	public static boolean internalIp(String ip){
		byte[] addr = textToNumericFormatV4(ip);
		return internalIp(addr) || "127.0.0.1".equals(ip);
	}

	/**
	 * 检查是否为内部IP地址
	 *
	 * @param addr byte地址
	 * @return 结果
	 */
	private static boolean internalIp(byte[] addr){
		if (ObjectUtils.isEmpty(addr) || addr.length < 2){
			return true;
		}
		final byte b0 = addr[0];
		final byte b1 = addr[1];
		// 10.x.x.x/8
		final byte SECTION_1 = 0x0A;
		// 172.16.x.x/12
		final byte SECTION_2 = (byte) 0xAC;
		final byte SECTION_3 = (byte) 0x10;
		final byte SECTION_4 = (byte) 0x1F;
		// 192.168.x.x/16
		final byte SECTION_5 = (byte) 0xC0;
		final byte SECTION_6 = (byte) 0xA8;
		switch (b0) {
			case SECTION_1:
				return true;
			case SECTION_2:
				if (b1 >= SECTION_3 && b1 <= SECTION_4) {
					return true;
				}
			case SECTION_5:
				switch (b1) {
					case SECTION_6:
						return true;
				}
			default:
				return false;
		}
	}

	/**
	 * 将IPv4地址转换成字节
	 *
	 * @param text IPv4地址
	 * @return byte 字节
	 */
	public static byte[] textToNumericFormatV4(String text){
		if (text.length() == 0) {
			return null;
		}

		byte[] bytes = new byte[4];
		String[] elements = text.split("\\.", -1);
		try {
			long l;
			int i;
			switch (elements.length) {
				case 1:
					l = Long.parseLong(elements[0]);
					if ((l < 0L) || (l > 4294967295L)) {
						return null;
					}
					bytes[0] = (byte) (int) (l >> 24 & 0xFF);
					bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
					bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
					bytes[3] = (byte) (int) (l & 0xFF);
					break;
				case 2:
					l = Integer.parseInt(elements[0]);
					if ((l < 0L) || (l > 255L)) {
						return null;
					}
					bytes[0] = (byte) (int) (l & 0xFF);
					l = Integer.parseInt(elements[1]);
					if ((l < 0L) || (l > 16777215L)) {
						return null;
					}
					bytes[1] = (byte) (int) (l >> 16 & 0xFF);
					bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
					bytes[3] = (byte) (int) (l & 0xFF);
					break;
				case 3:
					for (i = 0; i < 2; ++i) {
						l = Integer.parseInt(elements[i]);
						if ((l < 0L) || (l > 255L)) {
							return null;
						}
						bytes[i] = (byte) (int) (l & 0xFF);
					}
					l = Integer.parseInt(elements[2]);
					if ((l < 0L) || (l > 65535L)) {
						return null;
					}
					bytes[2] = (byte) (int) (l >> 8 & 0xFF);
					bytes[3] = (byte) (int) (l & 0xFF);
					break;
				case 4:
					for (i = 0; i < 4; ++i) {
						l = Integer.parseInt(elements[i]);
						if ((l < 0L) || (l > 255L)) {
							return null;
						}
						bytes[i] = (byte) (int) (l & 0xFF);
					}
					break;
				default:
					return null;
			}
		}
		catch (NumberFormatException e) {
			return null;
		}
		return bytes;
	}

	/**
	 * 获取本地IP地址 <br>
	 * 注意:linux中会拿host文件中的ip,大部分没有配置的话会拿出127.0.0.1 <br>
	 * 非docker容器中的程序可以采用下方 getLocalIp()方法
	 * @return 本地IP地址
	 */
	public static String getHostIp() {
		try {
			return InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return "127.0.0.1";
	}


	/**
	 * 根据网卡获取本机ip <br>
	 * 注意:若是在docker容器中跑的程序,会拿到 docker的ip <br>
	 *      若是想拿宿主机的ip,加以调用下方 getLocalNetCardAdd() 方法
	 * @return 本地IP地址
	 */
	public static String getLocalNetCardIp() {
		InetAddress inetAddress = null;
		boolean isFind = false; // 返回标识
		Enumeration<NetworkInterface> networkInterfaceLists = null;
		try {
			// 获取网络接口
			networkInterfaceLists = (Enumeration<NetworkInterface>) NetworkInterface.getNetworkInterfaces();
		} catch (SocketException e) {
			e.printStackTrace();
		}
		while (networkInterfaceLists.hasMoreElements()) {
			NetworkInterface networkInterface = (NetworkInterface) networkInterfaceLists.nextElement();
			Enumeration<InetAddress> ips = networkInterface.getInetAddresses();
			// 遍历所有ip,获取本地地址中不是回环地址的ipv4地址
			while (ips.hasMoreElements()) {
				inetAddress = (InetAddress) ips.nextElement();
				if (inetAddress instanceof Inet4Address && inetAddress.isSiteLocalAddress()
						&& !inetAddress.isLoopbackAddress()) {
					isFind = true;
					break;
				}
			}
			if (isFind) {
				break;
			}
		}
		return inetAddress == null ? "" : inetAddress.getHostAddress();
	}

	/**
	 * 根据网卡获得IP地址<br>
	 * 获取到本机网卡ip,就是在docker里跑的程序,也获取的是宿主机的ip地址
	 * @return 本地IP地址
	 */
	public static String getLocalNetCardAdd() {
		String ip="";
		try {
			for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
				NetworkInterface intf = en.nextElement();
				String name = intf.getName();
				if (!name.contains("docker") && !name.contains("lo")) {
					for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
						//获得IP
						InetAddress inetAddress = enumIpAddr.nextElement();
						if (!inetAddress.isLoopbackAddress()) {
							String ipaddress = inetAddress.getHostAddress().toString();
							if (!ipaddress.contains("::") && !ipaddress.contains("0:0:") && !ipaddress.contains("fe80")) {
								if(!"127.0.0.1".equals(ip)){
									ip = ipaddress;
								}
							}
						}
					}
				}
			}
		} catch (SocketException e) {
			e.printStackTrace();
		}
		return ip;
	}


	/**
	 * 获取主机名
	 * @return 本地主机名
	 */
	public static String getHostName() {
		try {
			return InetAddress.getLocalHost().getHostName();
		}
		catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return "未知";
	}


	/**
	 * 从多级反向代理中获得第一个非unknown IP地址
	 * @param ip 获得的IP地址
	 * @return 第一个非unknown IP地址
	 */
	public static String getMultistageReverseProxyIp(String ip) {
		// 多级反向代理检测
		if (ip != null && ip.indexOf(",") > 0) {
			final String[] ips = ip.trim().split(",");
			for (String subIp : ips) {
				if (false == isUnknown(subIp)) {
					ip = subIp;
					break;
				}
			}
		}
		return ip;
	}

	/**
	 * 检测给定字符串是否为未知,多用于检测HTTP请求相关
	 * @param checkString 被检测的字符串
	 * @return 是否未知
	 */
	public static boolean isUnknown(String checkString) {
		return ObjectUtils.isEmpty(checkString) || "unknown".equalsIgnoreCase(checkString);
	}
	/**
	 * 获取客户端Mac地址
	 * @param ip
	 * @return
	 */
	public static String getMACAddress(String ip) {
		String str = "";
		String macAddress = "";
		if(StringUtil.isEmpty(ip)){
			return macAddress;
		}
		try {
			Process p = Runtime.getRuntime().exec("nbtstat -A " + ip);
			InputStreamReader ir = new InputStreamReader(p.getInputStream());
			LineNumberReader input = new LineNumberReader(ir);
			for (int i = 1; i < 100; i++) {
				str = input.readLine();
				if (str != null) {
					if (str.indexOf("MAC Address") > 1) {
						macAddress = str.substring(str.indexOf("MAC Address") + 14, str.length());
						break;
					}
				}
			}
		} catch (IOException e) {
			return "";
		}
		return macAddress;
	}



	public static void main(String[] args) {
		Long ipToLong = ipToLong("147.111.90.201");
		System.out.println(ipToLong);
		System.out.println(longToIp(ipToLong));
	}
}

OkhttpUtils,http请求工具类

package com.utils;

import com.alibaba.fastjson.JSON;
import okhttp3.*;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * 描述: 自定义链式变成实现OkHttpUtils </br>
 * 时间: 2020-09-28 11:10  </br>
 * 作者:王林冲
 */
public class OkHttpUtils {
    //OkHttp客户端
    private static volatile OkHttpClient okHttpClient = null;
    //OkHttp请求信号量*/
    private static volatile Semaphore semaphore = null;
    //OkHttp的requestHeader参数map
    private Map<String, Object> headerMap;
    //OkHttp的request参数map
    private Map<String, Object> paramMap;
    //OkHttp的请求url
    private String url;
    //OkHttp的Request
    private Request.Builder request;

    /**
     * 初始化okHttpClient,并且允许https访问
     */
    private OkHttpUtils() {
        if (okHttpClient == null) {
            synchronized (OkHttpUtils.class) {
                if (okHttpClient == null) {
                    TrustManager[] trustManagers = buildTrustManagers();
                    okHttpClient = new OkHttpClient.Builder()
                            .connectTimeout(15, TimeUnit.SECONDS)
                            .writeTimeout(20, TimeUnit.SECONDS)
                            .readTimeout(20, TimeUnit.SECONDS)
                            .sslSocketFactory(createSSLSocketFactory(trustManagers), (X509TrustManager) trustManagers[0])
                            .hostnameVerifier((hostName, session) -> true)
                            .retryOnConnectionFailure(true)
                            .build();
                    addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
                }
            }
        }
    }

    /**
     * 用于异步请求时,控制访问线程数,返回结果
     *
     * @return
     */
    private static Semaphore getSemaphoreInstance() {
        //只能1个线程同时访问
        synchronized (OkHttpUtils.class) {
            if (semaphore == null) {
                semaphore = new Semaphore(0);
            }
        }
        return semaphore;
    }

    /**
     * 创建OkHttpUtils
     *
     * @return
     */
    public static OkHttpUtils builder() {
        return new OkHttpUtils();
    }

    /**
     * 添加url
     *
     * @param url
     * @return
     */
    public OkHttpUtils url(String url) {
        this.url = url;
        return this;
    }

    /**
     * 添加参数
     * 
     * @param key   参数名
     * @param value 参数值
     * @return
     */
    public OkHttpUtils addParam(String key, String value) {
        if (paramMap == null) {
            paramMap = new LinkedHashMap<>(16);
        }
        paramMap.put(key, value);
        return this;
    }

    /**
     * 添加请求头
     *
     * @param key   参数名
     * @param value 参数值
     * @return
     */
    public OkHttpUtils addHeader(String key, String value) {
        if (headerMap == null) {
            headerMap = new LinkedHashMap<>(16);
        }
        headerMap.put(key, value);
        return this;
    }

    /**
     * 初始化get方法
     *
     * @return
     */
    public OkHttpUtils get() {
        request = new Request.Builder().get();
        StringBuilder urlBuilder = new StringBuilder(url);
        if (paramMap != null) {
            urlBuilder.append("?");
            try {
                for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                    urlBuilder.append(URLEncoder.encode(entry.getKey(), "utf-8")).
                            append("=").
                            append(URLEncoder.encode(entry.getValue().toString(), "utf-8")).
                            append("&");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            urlBuilder.deleteCharAt(urlBuilder.length() - 1);
        }
        request.url(urlBuilder.toString());
        return this;
    }

    /**
     * 初始化post方法
     *
     * @param isJsonPost true等于json的方式提交数据,类似postman里post方法的raw
     *                   false等于普通的表单提交
     * @return
     */
    public OkHttpUtils post(boolean isJsonPost) {
        RequestBody requestBody;
        if (isJsonPost) {
            String json = "";
            if (paramMap != null) {
                json = JSON.toJSONString(paramMap);
            } 
            requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
        } else {
            FormBody.Builder formBody = new FormBody.Builder();
            if (paramMap != null) {
                //paramMap.forEach(formBody::add());
                for (String key : paramMap.keySet()) {
                    formBody.add(key, paramMap.get(key).toString());
                }
            }
            requestBody = formBody.build();
        }
        request = new Request.Builder().post(requestBody).url(url);
        return this;
    }

    /**
     * 上传文件
     * @param file 文件对象
     * @param fileName 文件名
     * @return
     * @throws Exception
     */
    public OkHttpUtils uploadFile(File file, String fileName) throws Exception {
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", fileName, RequestBody.create(MediaType.parse("multipart/form-data"), file))
                .build();
        request = new Request.Builder().post(requestBody).url(url);
        return this;

    }



    /**
     * 上传文件
     * @param filePath 文件路径
     * @param fileName 文件名
     * @return
     * @throws Exception
     */
    public OkHttpUtils uploadFile(String filePath, String fileName) throws Exception {
        return uploadFile(new File(filePath), fileName);

    }


    /**
     * 多文件上传
     * @param filesMap 文件对象map
     * @return
     * @throws Exception
     */
    public OkHttpUtils uploadFiles(HashMap<String, File> filesMap) throws Exception {
        MultipartBody.Builder builder = new MultipartBody.Builder();
        for (String fileName : filesMap.keySet()) {
            builder.addFormDataPart("file", fileName, RequestBody.create(MediaType.parse("multipart/form-data"), filesMap.get(fileName)));
        }
        RequestBody requestBody = builder.setType(MultipartBody.FORM)
                .build();
        request = new Request.Builder().post(requestBody).url(url);
        return this;

    }



    /**
     * 同步请求
     *
     * @return
     */
    public String sync() {
        setHeader(request);
        try {
            Response response = okHttpClient.newCall(request.build()).execute();
            assert response.body() != null;
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
            return "请求失败:" + e.getMessage();
        }
    }

    /**
     * 异步请求,有返回值
     */
    public String async() {
        StringBuilder buffer = new StringBuilder("");
        setHeader(request);
        okHttpClient.newCall(request.build()).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                buffer.append("请求出错:").append(e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                assert response.body() != null;
                buffer.append(response.body().string());
                getSemaphoreInstance().release();
            }
        });
        try {
            getSemaphoreInstance().acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }

    /**
     * 异步请求,带有接口回调
     *
     * @param callBack
     */
    public void async(ICallBack callBack) {
        setHeader(request);
        okHttpClient.newCall(request.build()).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                callBack.onFailure(call, e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                assert response.body() != null;
                callBack.onSuccessful(call, response.body().string());
            }
        });
    }

    /**
     * 为request添加请求头
     *
     * @param request
     */
    private void setHeader(Request.Builder request) {
        if (headerMap != null) {
            try {
                for (Map.Entry<String, Object> entry : headerMap.entrySet()) {
                    request.addHeader(entry.getKey(), entry.getValue().toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 生成安全套接字工厂,用于https请求的证书跳过
     *
     * @return
     */
    private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustAllCerts) {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ssfFactory;
    }

    private static TrustManager[] buildTrustManagers() {
        return new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                }
        };
    }

    /**
     * 自定义一个接口回调
     */
    public interface ICallBack {

        void onSuccessful(Call call, String data);

        void onFailure(Call call, String errorMsg);

    }
}




使用示例:

package com.demo;

import com.utils.OkHttpUtils;
import okhttp3.Call;

/**
 * 描述: OkHttpUtilDemo </br>
 * 时间: 2021-05-26 11:52  </br>
 * 作者:王林冲
 */
public class OkHttpUtilDemo {

    public static void main(String[] args) {
        // get请求,方法顺序按照这种方式,切记选择post/get一定要放在倒数第二,同步或者异步倒数第一,才会正确执行
        String getData = OkHttpUtils.builder().url("请求地址,http/https都可以")
                // 有参数的话添加参数,可多个
                .addParam("参数名", "参数值")
                .addParam("参数名", "参数值")
                // 也可以添加多个
                .addHeader("Content-Type", "application/json; charset=utf-8")
                .get()
                // 可选择是同步请求还是异步请求
                //.async();
                .sync();

        // post请求,分为两种,一种是普通表单提交,一种是json提交
        String postData = OkHttpUtils.builder().url("请求地址,http/https都可以")
                // 有参数的话添加参数,可多个
                .addParam("参数名", "参数值")
                .addParam("参数名", "参数值")
                // 也可以添加多个
                .addHeader("Content-Type", "application/json; charset=utf-8")
                // 如果是true的话,会类似于postman中post提交方式的raw,用json的方式提交,不是表单
                // 如果是false的话传统的表单提交
                .post(true)
                .sync();

        // 选择异步有两个方法,一个是带回调接口,一个是直接返回结果
        OkHttpUtils.builder().url("")
                .post(false)
                .async(new OkHttpUtils.ICallBack() {
                    @Override
                    public void onSuccessful(Call call, String data) {
                        // 请求成功后的处理
                    }

                    @Override
                    public void onFailure(Call call, String errorMsg) {
                        // 请求失败后的处理
                    }
                });

        OkHttpUtils.builder().url("").post(false).async(new OkHttpUtils.ICallBack() {
            @Override
            public void onSuccessful(Call call, String data) {
                // 请求成功后的处理
            }

            @Override
            public void onFailure(Call call, String errorMsg) {
                // 请求失败后的处理
            }
        });
    }

}
文件上传demo

package com.zxl.util;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 描述: NFT通用接口封装util </br>
 * 时间: 2022-05-09 14:15  </br>
 * 作者:王林冲
 */
@Component
public class FileUtil {

    private static void upLoadFile() throws Exception {
        File file = new File("D:\\test.json");
        File file1 = new File("D:\\test1.json");
        HashMap<String, File> fileMap = new HashMap<>();
        fileMap.put("test", file);
        fileMap.put("test1", file1);
    //对文件上传
        String result = OkHttpUtils.builder().addParam("Authorization", "Client-ID " + UUID.randomUUID())
                .url("http://127.0.0.1:18000/file/uploadsMinio")
                .uploadFiles(fileMap)
                .sync();
        System.out.println(result);

    }

    public static void main(String[] args) throws Exception {
        upLoadFile();
    }

}

 redis操作类util

package com.utils;

import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import com.redisKeydelay.LiveRedisKeyConstant;
import com.redisKeydelay.RedisLockDefinitionHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

/** 
 * @description: redis的util操作类
 * @author: wlc
 * @Date: 2019年6月19日 上午10:10:19
 */
@Slf4j
@Component
public final class RedisUtil {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // =============================common============================
    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据key 获取过期时间
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判断key是否存在
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除缓存
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }
    // ============================String=============================
    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    /**
     * 普通缓存放入
     * @param key 键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据正则表达式获取模糊匹配的key value的hashmap
     * @param pattern 通配符表达式,ex:"wlc*"或者"*wlc*"等
     * @return HashMap 符合通配符的key和value的map集合
     */
    public HashMap<String, Object> keys( String pattern){
        //根据通配符获取key的set集合
        Set<String> set=redisTemplate.keys(pattern);
        if (CollectionUtils.isEmpty(set)){
            return null;
        }
        HashMap<String, Object> map = new HashMap<>();
        //遍历key的set集合,获取对应的value
        for (String key : set){
            //通过查到的key值获取value,并放入result
            map.put(key, redisTemplate.opsForValue().get(key));
        }
        return map;
    }


    /**
     *  获取指定前缀的一系列key
     *  使用scan命令代替keys, Redis是单线程处理,keys命令在KEY数量较多时,
     *  操作效率极低【时间复杂度为O(N)】,该命令一旦执行会严重阻塞线上其它命令的正常请求
     * @param pattern
     * @return
     */
    public Set<String> scanKeys(String pattern) {
        Set<String> set = redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
            Set<String> binaryKeys = new HashSet<>();
            Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(pattern).count(Integer.MAX_VALUE).build());
            while (cursor.hasNext()) {
                binaryKeys.add(new String(cursor.next()));
            }
            return binaryKeys;
        });
        if (CollectionUtils.isEmpty(set)){
            return null;
        }
        HashMap<String, Object> k_v_map = new HashMap<>();
        for (String key : set) {
            //通过查到的key值获取value,并放入result
            k_v_map.put(key, redisTemplate.opsForValue().get(key));
        }
        for (String key : k_v_map.keySet()) {
            System.out.println("key = " + key + "   val = " + k_v_map.get(key));
        }
        return set;
    }

    /**
     * 普通缓存放入并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
                //设置当前线程的redis的key到续命队列
                LiveRedisKeyConstant.addLiveRedisKeyHolderList(new RedisLockDefinitionHolder(key, time, System.currentTimeMillis(),
                        Thread.currentThread(), LiveRedisKeyConstant.getDefaultTryCount()));
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 递增
     * @param key 键
     * @param delta 要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 递减
     * @param key 键
     * @param delta 要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    /**
     * HashGet
     * @param key 键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 获取hashKey对应的所有键值
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * HashSet 并设置时间
     * @param key 键
     * @param map 对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张hash表中放入数据,如果不存在将创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张hash表中放入数据,如果不存在将创建
     * @param key 键
     * @param item 项
     * @param value 值
     * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除hash表中的值
     * @param key 键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判断hash表中是否有该项的值
     * @param key 键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }
    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     * @param key 键
     * @param item 项
     * @param by 要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }
    /**
     * hash递减
     * @param key 键
     * @param item 项
     * @param by 要减少记(小于0)
     * @return
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
    /**
     * 根据key获取Set中的所有值
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 根据value从一个set中查询,是否存在
     * @param key 键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将数据放入set缓存
     * @param key 键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 将set数据放入缓存
     * @param key 键
     * @param time 时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0)
            expire(key, time);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 获取set缓存的长度
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 移除值为value的
     * @param key 键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ===============================list=================================
    /**
     * 获取list缓存的内容
     * @param key 键
     * @param start 开始
     * @param end 结束 0 到 -1代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取list缓存的长度
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 通过索引 获取list中的值
     * @param key 键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @param time 时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0)
            expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key 键
     * @param value 值
     * @param time 时间(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0)
            expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据索引修改list中的某条数据
     * @param key 键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 移除N个值为value
     * @param key 键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    public boolean setIfAbsent(String key, Object value, long exptime) {
        Boolean result = (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer valueSerializer = redisTemplate.getValueSerializer();
                RedisSerializer keySerializer = redisTemplate.getKeySerializer();
                Object obj = connection.execute("set", keySerializer.serialize(key),
                        valueSerializer.serialize(value),
                        "NX".getBytes(StandardCharsets.UTF_8),
                        "EX".getBytes(StandardCharsets.UTF_8),
                        String.valueOf(exptime).getBytes(StandardCharsets.UTF_8));
                return obj != null;
            }
        });
        return result;
    }

    /**
     * hyperLogLog数据结构的新增
     * key一样,value不一样,key对应的count就会+1,value一样就不会变,适合大数据量的pv uv统计
     * key一般是业务或者页面或者接口标识,即统计标识
     * value一般是ip
     * @param key 键值
     * @param value
     * @return
     */
    public boolean pfadd (String key, Object value){
        try {
            HyperLogLogOperations<String, Object> hyperLogLog = redisTemplate.opsForHyperLogLog();
            hyperLogLog.add(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * hyperLogLog数据结构获取key的count
     * @param key
     * @return
     */
    public long pfcount(String key){
        try {
            HyperLogLogOperations<String, Object> hyperLogLog = redisTemplate.opsForHyperLogLog();
            Long size = hyperLogLog.size(key);
            return size;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * hyperLogLog数据结构删除key
     * @param key
     * @return
     */
    public boolean pfdelete(String key){
        try {
            HyperLogLogOperations<String, Object> hyperLogLog = redisTemplate.opsForHyperLogLog();
            hyperLogLog.delete(key);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    //设置6自增6位,用于补全操作
    private static final String STR_FORMAT = "000000";

    /**
     * redis流水号自增
     * @param key        自己设置,保存当前自增值
     * @param liveTime   在redis中的缓存时间,方法中设置单位(秒/分/天……)
     * @return
     */
    public String incrSerialNum(String key, long liveTime) {
        RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        Long increment = entityIdCounter.getAndIncrement();

        if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间
            entityIdCounter.expire(liveTime, TimeUnit.SECONDS);    //设置自增值过期时间,liveTime 过期时间;TimeUnit.DAYS 过期时间单位,我这边设置为天
            //entityIdCounter.expire(liveTime, TimeUnit.DAYS);    //设置自增值过期时间,liveTime 过期时间;TimeUnit.DAYS 过期时间单位,我这边设置为天
        }
        if (increment == 0) {
            increment = increment + 1;
        } else if (increment > 999999){
            increment = 1L;
        }
        //位数不够,前面补0
        DecimalFormat df = new DecimalFormat(STR_FORMAT);
        return df.format(increment);
    }


    public String getOrderNo(String prefixFlag){
        StringBuffer sb = new StringBuffer();
        sb.append(prefixFlag);        //标志位
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        sb.append(sdf.format(new Date()));     //年月日时分秒
        String prefixStr = sb.toString();
        String no = incrSerialNum(prefixStr, 1);
        sb.append(no);
        return sb.toString();
    }




}

更多精彩分享请移步:IT学习道场

更多分享关注公众号【IT学习道场】

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT学习道场

为你的进步加点油!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值