常用用具类总结

SnowFlakeUtil 

@Slf4j
public class SnowFlakeUtil {
    
    public static final SnowFlakeUtil instance = new SnowFlakeUtil();

    /**
     * 起始的时间戳
     */
    private final long START_TIMESTAMP = 1557489395327L;
    /**
     * 序列号占用位数
     */
    private final long SEQUENCE_BIT = 12;
    /**
     * 机器标识占用位数
     */
    private final long MACHINE_BIT = 10;

    /**
     * 时间戳位移位数
     */
    private final long TIMESTAMP_LEFT = SEQUENCE_BIT + MACHINE_BIT;

    /**
     * 最大序列号  (4095)
     */
    private final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);
    /**
     * 最大机器编号 (1023)
     */
    private final long MAX_MACHINE_ID = ~(-1L << MACHINE_BIT);
    /**
     * 生成id机器标识部分
     */
    private long machineIdPart;
    /**
     * 序列号
     */
    private long sequence = 0L;

    /**
     * 上一次时间戳
     */
    private long lastStamp = -1L;

    /**
     * 构造函数初始化机器编码
     */
    private SnowFlakeUtil() {
        //模拟这里获得本机机器编码
        // long localIp = 0;
        // localIp = hostNameUtil.getMachineNo();
        
        // 机器码随机生成
        long randomNum = new Random().nextInt(1023);
        log.info("当前机器编码:{}", randomNum);

        //localIp & MAX_MACHINE_ID最大不会超过1023,在左位移12位
        machineIdPart = (randomNum & MAX_MACHINE_ID) << SEQUENCE_BIT;
    }

    /**
     * 获取雪花ID
     */
    public synchronized long nextId() {
        long currentStamp = timeGen();
        //避免机器时钟回拨
        while (currentStamp < lastStamp) {
            // //服务器时钟被调整了,ID生成器停止服务.
            throw new RuntimeException(String.format("时钟已经回拨.  Refusing to generate id for %d milliseconds", lastStamp - currentStamp));
        }
        if (currentStamp == lastStamp) {
            // 每次+1
            sequence = (sequence + 1) & MAX_SEQUENCE;
            // 毫秒内序列溢出
            if (sequence == 0) {
                // 阻塞到下一个毫秒,获得新的时间戳
                currentStamp = getNextMill();
            }
        } else {
            //不同毫秒内,序列号置0
            sequence = 0L;
        }
        lastStamp = currentStamp;
        //时间戳部分+机器标识部分+序列号部分
        return (currentStamp - START_TIMESTAMP) << TIMESTAMP_LEFT | machineIdPart | sequence;
    }

    /**
     * 阻塞到下一个毫秒,直到获得新的时间戳
     */
    private long getNextMill() {
        long mill = timeGen();
        //
        while (mill <= lastStamp) {
            mill = timeGen();
        }
        return mill;
    }

    /**
     * 返回以毫秒为单位的当前时间
     */
    protected long timeGen() {
        return System.currentTimeMillis();
    }

    /**
     * 获取long类型雪花ID
     */
    public long uniqueLong() {
        return nextId();
    }

    /**
     * 获取String类型雪花ID
     */
    public String uniqueLongHex() {
        return String.format("%016x", uniqueLong());
    }
}

RedisUtils 

@Component
public class RedisUtils {
	protected static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);

    private static RedisTemplate redisTemplate;

    @Autowired
    public RedisUtils(RedisTemplate stringObjectRedisTemplate){
        RedisUtils.redisTemplate = stringObjectRedisTemplate;
    }

	@SuppressWarnings("unchecked")
	public static <T> T get(String key, Class<T> clazz) {
		try {
			ValueOperations<String, T> ops = getRedisTemplate().opsForValue();
			T value = ops.get(key);
			return value;
		} catch (Exception e) {
			logger.info("get from Cache error! key = {" + key + "}", e);
			logger.warn("catch error!", e);
			return null;
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static Set getSet(String key) {
		try {
			SetOperations ops = getRedisTemplate().opsForSet();
			return ops.members(key);
		} catch (Exception e) {
			logger.info("get from Cache error! key = {" + key + "}", e);
			logger.warn("catch error!", e);
			return null;
		}
	}

	public static String getString(String key) {
		return get(key, String.class);
	}

	public static Integer getInteger(String key) {
		return get(key, Integer.class);
	}

	public static BigDecimal getDecimal(String key) {
		return get(key, BigDecimal.class);
	}

	@SuppressWarnings("unchecked")
	public static <T> boolean set(String key, T value, int expire) {
		try {
			if (value == null) {
				return Boolean.FALSE;
			}
			ValueOperations<String, T> ops = getRedisTemplate().opsForValue();
			ops.set(key, value);
			return getRedisTemplate().expire(key, expire, TimeUnit.SECONDS);
		} catch (Exception e) {
			logger.info("set to Cache error! key = {" + key + "}", e);
			logger.warn("set to Cache error!", e);
		}
		return Boolean.FALSE;
	}
	public static <T> void setAndexpire(String key, T value, int expire) {
		try {
			ValueOperations<String, T> ops = getRedisTemplate().opsForValue();
		    ops.set(key, value,expire,TimeUnit.SECONDS);
		} catch (Exception e) {
			logger.info("set to Cache error! key = {" + key + "}", e);
			logger.warn("set to Cache error!", e);
		}
	}


	/**
	 * 获取分页数据
	 *
	 * @param key       Redis中的列表key
	 * @param pageNum   当前页码(从1开始)
	 * @param pageSize  每页大小
	 * @return          分页数据列表
	 */
	public static CommonPageResp getPagedData(String key, int pageNum, int pageSize) {
		if (pageNum <= 0) {
			throw new IllegalArgumentException("Page number must be greater than 0");
		}
		if (pageSize <= 0) {
			throw new IllegalArgumentException("Page size must be greater than 0");
		}

		// 计算起始和结束索引
		int start = (pageNum - 1) * pageSize;
		int end = start + pageSize - 1;
		CommonPageResp objectCommonPageResp = new CommonPageResp<>();
		// 使用LRANGE命令获取指定范围的数据
		List range = getRedisTemplate().opsForList().range(key, start, end);
		objectCommonPageResp.setRows(range);
		objectCommonPageResp.setPageNo(pageNum);
		objectCommonPageResp.setPageSize(pageSize);
		long listLength = getRedisTemplate().opsForList().size(key);
		objectCommonPageResp.setTotal(listLength);
		return objectCommonPageResp;
	}
	public static void hincrBy_StringSerialize(String key, String hashKey, Long value) {
		try {
			getRedisTemplate().opsForHash().increment(key, hashKey, value);
		} catch (Exception e) {
			logger.error("RedisUtils put error key[{}], hashKey[{}], value[{}], exception:{}", key, hashKey, value, e.getMessage());
		}
	}

	public static Long putHashMap_StringSerialize(String cacheKey, Map map, long time) {
		try {
			getRedisTemplate().opsForHash().putAll(cacheKey, map);
			if (time > 0) {
				getRedisTemplate().expire(cacheKey, time, TimeUnit.SECONDS);
			}
			return getRedisTemplate().opsForHash().size(cacheKey);
		} catch (Exception e) {
			logger.error("putHashMap,cacheKey[" + cacheKey + "]", e);
		}
		return 0l;
	}
	public static void put_StringSerialize(String key, String hashKey, String value) {
		try {
			getRedisTemplate().opsForHash().put(key, hashKey, value);
		} catch (Exception e) {
			logger.error("RedisUtils put error key[{}], hashKey[{}], value[{}], exception:{}", key, hashKey, value, e.getMessage());
		}
	}
	/**
	 * 获取总页数
	 *
	 * @param key Redis中的列表key
	 * @param pageSize 每页大小
	 * @return 总页数
	 */
//	public long getTotalPages(String key, int pageSize) {
//		if (pageSize <= 0) {
//			throw new IllegalArgumentException("Page size must be greater than 0");
//		}
//
//		// 获取列表长度
//		long listLength = getRedisTemplate().opsForList().size(key);
//
//		// 计算总页数(向上取整)
//		return (listLength + pageSize - 1) / pageSize;
//	}


/**
 * @title: 根据前缀删除
 * @author: luo heng
 * @date: 2021/12/20 11:14
 * @description: TODO
 * @version:
 * @param pattern
 * @return:
 */
//	public static Set<Object> scanDel(String pattern) {
//		RedisTemplate redisTemplate = getRedisTemplate();
//		redisTemplate.execute((RedisCallback<Set<Object>>) connection -> {
//			JedisCommands commands = (JedisCommands) connection.getNativeConnection();
//			MultiKeyCommands multiKeyCommands = (MultiKeyCommands) commands;
//			int scanInvokeCount = 0;
//			int totalCount = 0;
//			logger.info("RedisHelper_clearScan_invoke_start scanInvokeCount:{}",scanInvokeCount);
//			ScanParams scanParams = new ScanParams();
//			scanParams.match(pattern + "*");
//			scanParams.count(500);
//			ScanResult<String> scan = multiKeyCommands.scan("0", scanParams);
//			scanInvokeCount++;
//			while (null != scan.getStringCursor()) {
//				List<String> keys = scan.getResult();
//				if (!CollectionUtils.isEmpty(keys)){
//					int count = 0;
//					for (String key : keys) {
//						try {
//							connection.del(key.getBytes());
//							logger.info("RedisHelper_clearScan key:{}",key);
//							count++;
//							totalCount++;
//						} catch (Exception e) {
//							logger.info("RedisHelper_clearScan_fail key:{}",key);
//							e.printStackTrace();
//						}
//					}
//					logger.info("RedisHelper_clearScan_delete count:{}",count);
//				}
//				if (!StringUtils.equals("0", scan.getStringCursor())) {
//					scan = multiKeyCommands.scan(scan.getStringCursor(), scanParams);
//					scanInvokeCount++;
//					logger.info("RedisHelper_clearScan_invoke scanInvokeCount:{}",scanInvokeCount);
//					continue;
//				} else {
//					break;
//				}
//			}
//			logger.info("RedisHelper_clearScan_invoke_end totalCount:{}",totalCount);
//			logger.info("RedisHelper_clearScan_invoke_end scanInvokeCount:{}",scanInvokeCount);
//			return null;
//		});
//		return null;
//	}
	public static <T> void set(String key, T value) {
		try {
			if (value == null) {
				return;
			}
			ValueOperations<String, T> ops = getRedisTemplate().opsForValue();
			ops.set(key, value);
		} catch (Exception e) {
			logger.info("set to Cache error! key = {" + key + "}", e);
			logger.warn("set to Cache error!", e);
		}
	}
	/**
	 * 查找匹配key
	 *
	 * @param pattern key
	 * @return /
	 */
	public static List<String> scan(String pattern) {
		ScanOptions options = ScanOptions.scanOptions().match(pattern).build();
		RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
		RedisConnection rc = Objects.requireNonNull(factory).getConnection();
		Cursor<byte[]> cursor = rc.scan(options);
		List<String> result = new ArrayList<>();
		while (cursor.hasNext()) {
			result.add(new String(cursor.next()));
		}
		try {
			RedisConnectionUtils.releaseConnection(rc, factory,false);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		CollectionUtil.removeEmpty(result);
		return result;
	}


	public static List<String> scanHashKey(String hashKey,String pattern) {
		Map<String,Object> allHashMap = getAllHashMap(hashKey);
		if(CollectionUtil.isNotEmpty(allHashMap)){
			Set<String> keys = allHashMap.keySet();
			List<String> collect = keys.stream().filter(s -> s.startsWith(pattern)||s.endsWith(pattern)).collect(Collectors.toList());
			CollectionUtil.removeEmpty(collect);
			return collect;
		}
		return new ArrayList<>();
	}

	public static boolean setString(String key, String value, int expire) {
		return set(key, value, expire);
	}

	public static boolean setDefExpire(String key, String value) {
		return set(key, value, 5 * 60 * 1000);
	}

	public static <T> boolean setDefExpire(String key, T value) {
		return set(key, value, 5 * 60 * 1000);
	}

	@SuppressWarnings("unchecked")
	public static void del(String key) {
		try {
			getRedisTemplate().delete(key);
		} catch (Exception e) {
			logger.info("delete from Cache error! key = {" + key + "}", e);
			logger.warn("delete from Cache error!", e);
		}
	}

	/**
	 * key是否存在
	 *
	 * @param key
	 */
	@SuppressWarnings("unchecked")
	public static boolean exists(final String key) {
		return getRedisTemplate().hasKey(key);
	}

	/**
	 * 把lis放入redis缓存起来,当天
	 *
	 * @param cacheKey
	 * @param list
	 */
//	public static void putListByRedisCache2ToDay(String cacheKey, List<?> list) {
//		putListByRedisCache(cacheKey, list, DateUtils.getMilliSecondsLeftToday());
//	}

	/**
	 * 把lis放入redis缓存起来,一个小时
	 *
	 * @param cacheKey
	 * @param list
	 */
	public static void putListByRedisCache2ToOneHours(String cacheKey, List<?> list) {
		putListByRedisCache(cacheKey, list, 2 * 60 * 60 * 1000);
	}

	/**
	 * 把lis放入redis缓存起来,30分钟
	 *
	 * @param cacheKey
	 * @param list
	 */
	public static void putListByRedisCache2To30Min(String cacheKey, List<?> list) {
		putListByRedisCache(cacheKey, list, 5 * 60 * 60 * 1000);
	}

	/**
	 * 把map放入redis缓存起来,当天
	 *
	 * @param cacheKey
	 * @param map
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static Long putHashMap(String cacheKey, Map map, long time) {
		try {
			getRedisTemplate().opsForHash().putAll(cacheKey, map);
			if (time > 0) {
				getRedisTemplate().expire(cacheKey, time, TimeUnit.SECONDS);
			}
			return getRedisTemplate().opsForHash().size(cacheKey);
		} catch (Exception e) {
			logger.error("putHashMap,cacheKey[" + cacheKey + "]", e);
		}
		return 0l;
	}

	/**
	 * 向key对应的map中添加缓存对象
	 *
	 * @param cacheKey
	 *            cache对象key
	 * @param field
	 *            map对应的key
	 * @param value
	 *            值
	 */
	@SuppressWarnings("unchecked")
	public static void addMap(String cacheKey, String field, Object value) {
		getRedisTemplate().opsForHash().put(cacheKey, field, value);
	}

	/**
	 * 把map放入redis缓存起来,当天
	 *
	 * @param cacheKey
	 */
	@SuppressWarnings("rawtypes")
	public static Map getAllHashMap(String cacheKey) {
		@SuppressWarnings("unchecked")
        BoundHashOperations boundHashOperations = getRedisTemplate().boundHashOps(cacheKey);
		return boundHashOperations.entries();
	}

	/**
	 * 把map放入redis缓存起来,当天
	 *
	 * @param cacheKey
	 */
	@SuppressWarnings("unchecked")
	public static Object getMapField(String cacheKey, String field) {
		return getRedisTemplate().boundHashOps(cacheKey).get(field);
	}

	/**
	public static Object getMapField(String cacheKey, String field) {
		return getRedisTemplate().boundHashOps(cacheKey).get(field);
	}
	/**
	 * 删除map中的某个对象
	 *
	 * @param key
	 *            map对应的key
	 * @param field
	 *            map中该对象的key
	 * @author lh
	 * @date 2016年8月10日
	 */
	@SuppressWarnings("unchecked")
	public static void delMapField(String key, Object... field) {
		BoundHashOperations<String, String, ?> boundHashOperations = getRedisTemplate().boundHashOps(key);
		boundHashOperations.delete(field);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void putListByRedisCache(String cacheKey, List list, long time) {
		try {
			Set set = getRedisTemplate().opsForSet().members(cacheKey);
			if (!set.isEmpty()) {// 如果当天数据已经存在redis中则不进行更新
				return;
			}
			SetOperations operations = getRedisTemplate().opsForSet();
			int size = 0;
			for (int i = 0; i < list.size(); i++) {
				size += operations.add(cacheKey, list.get(i));
			}
			// 放入缓存的时间 毫秒
			getRedisTemplate().expire(cacheKey, time, TimeUnit.MILLISECONDS);

			if (size == list.size()) {
				logger.info("[" + cacheKey + "]缓存成功,size:" + size);
			} else {
				logger.info("[" + cacheKey + "]缓存失败,size:" + size);
				logger.error("[" + cacheKey + "]缓存失败,size:" + size + ",listsize:" + list.size());
			}

		} catch (Exception e) {
			logger.error("[" + cacheKey + "]缓存失败,List:" + JSONObject.toJSONString(list));
		}

	}

	@SuppressWarnings("unchecked")
	public static boolean hasKey(String pubparadescmap, String key) {
		try {
			return getRedisTemplate().boundHashOps(pubparadescmap).hasKey(key);
		} catch (Exception e) {
			logger.error("hasKey[" + key + "]hasKey,List:", e);
		}

		return false;
	}

	/**
	 * pub 、sub 模式
	 * 
	 * @param channel
	 * @param message
	 * @return
	 */
	public static boolean pubMessage(String channel, Object message) {

		try {
			getRedisTemplate().convertAndSend(channel, message);
		} catch (Exception e) {
			logger.error("pubMessage,channel=" + channel + ",message=" + JSONObject.toJSONString(message) + " ", e);
			return false;
		}

		return true;
	}

	@SuppressWarnings("rawtypes")
	public static RedisTemplate getRedisTemplate() {
			return redisTemplate;
	}

	public static void putListByRedisWithExpired(String cacheKey, List<?> list) {
		try {
			getRedisTemplate().opsForList().leftPushAll(cacheKey, list);
			getRedisTemplate().expire(cacheKey, 8 * 60 * 60 * 1000, TimeUnit.MILLISECONDS);
		}catch (Exception e){
			logger.error("缓存["+cacheKey+"]失败:", e);
		}

	}
	public static void putSetByRedisWithExpired(String cacheKey, List<?> list) {
		try {
			SetOperations setOperations = getRedisTemplate().opsForSet();
			if(exists(cacheKey)){
				//set集已存在,无需再次存入
				logger.info("缓存"+cacheKey+"已存在,无需重复插入!");
				return;
			}
			for(int i = 0; i < list.size(); i++){
				setOperations.add(cacheKey, list.get(i));
			}
			getRedisTemplate().expire(cacheKey, 8 * 60 * 60 * 1000, TimeUnit.MILLISECONDS);
		}catch (Exception e){
			logger.error("缓存["+cacheKey+"]失败:", e);
		}

	}
	public static List getList(String cacheKey ) {
		try {
			return getRedisTemplate().opsForList().range(cacheKey, 0, -1);
		}catch (Exception e){
			logger.error("获取缓存["+cacheKey+"]失败:", e);
		}
		return new ArrayList();
	}


	public static List getList(String cacheKey ,int page,int pageSize) {
		try {
			return getRedisTemplate().opsForList().range(cacheKey, 0, -1);
		}catch (Exception e){
			logger.error("获取缓存["+cacheKey+"]失败:", e);
		}
		return new ArrayList();
	}

ExcelUtil


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Slf4j
public class WriteExcelUtil {


    /**
     * 创建xlsx导出开始(适用于多个sheet)
     * 使用案例:
     * ExcelWriter writer = WriteExcelUtil.createExport(response, "name");
     * WriteExcelUtil.writeSheet(writer, "s1", list, ContractPageDto.class);
     * WriteExcelUtil.writeSheet(writer, "s2", listBills, BusinessBillsPageDto.class);
     * WriteExcelUtil.finishWrite(writer);
     *
     * @param response
     * @param fileName 导出的文件名,不需要加.xlsx
     */
    public static <T> ExcelWriter createExport(HttpServletResponse response, String fileName) {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("导出XLS时发送错误");
        }
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
        } catch (IOException e) {
            throw new RuntimeException("导出XLS发送错误");
        }
        ExcelWriter excelWriter = EasyExcel.write(outputStream).registerWriteHandler(new ExcelWidthStyleStrategy()).build();
        return excelWriter;
    }


    /**
     * 写入一个sheet
     *
     * @param sheetName   工作表名
     * @param list<T>
     * @param entityClass
     */
    public static <T> void writeSheet(ExcelWriter excelWriter, String sheetName, List<T> list, Class entityClass) {
        WriteSheet sheet = EasyExcel.writerSheet(sheetName).head(entityClass).build();
        excelWriter.write(list, sheet);
    }
    /**
     * 结束写入sheet并导出
     */
    public static <T> void finishWrite(ExcelWriter excelWriter) {
        excelWriter.finish();
    }
    /**
     *返回blob类型
     * @param listData
     * @param response httpRes
     * @param fileName
     * @throws IOException
     */
    static public void writeExcelToBrowser(List<? extends Object> listData, HttpServletResponse response, String fileName) throws IOException {
        if(listData.size()>10000){
            throw new RuntimeException("数据量超过10000条,无法导出");
        }
        if(!CollectionUtils.isEmpty(listData)){
            try {
                String name = fileName + ".xlsx";
                fileName = new String(name.getBytes(), StandardCharsets.UTF_8);
                response.setContentType("application/vnd.ms-excel");
                response.setCharacterEncoding("utf-8");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                EasyExcel.write(response.getOutputStream(), listData.get(0).getClass())
                        .registerWriteHandler(new ExcelWidthStyleStrategy())
                        .sheet(fileName)
                        .doWrite(listData);
            }catch (Exception e){
                log.error("导出excel失败",e);
            }

        }
    }



    static public ResponseEntity exportExcel(List<? extends Object> listData, String fileName) {
        try {
            //数据写入到字节流
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            boolean flag = writeExcel(bos, listData.get(0).getClass(), listData , fileName);
            //下载文件
             fileName = fileName + ".xlsx";
            //excel导出
            if (flag) {
                return downloadExcel(fileName, bos);
            }
        } catch (Exception e) {
            log.error("导出excel异常", e);
        }
        return null;
    }



        /**
         * 表头进行自动扩展的导出
         *
         * @param os        文件输出流
         * @param clazz     Excel实体映射类
         * @param data      导出数据
         * @param sheetName sheet名称
         * @return
         */
        public static Boolean writeExcel(OutputStream os, Class clazz, List<?> data, String sheetName) {
            try (BufferedOutputStream bos = new BufferedOutputStream(os)) {
                EasyExcel.write(bos, clazz)
                        .sheet(sheetName)
                        //使用该方法对表头的宽度进行扩展
                        .doWrite(data);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }
        /**
         * ResponseEntity下载文件
         *
         * @param fileName
         * @param byteOutPutStream
         */
        public static ResponseEntity<byte[]> downloadExcel(String fileName, ByteArrayOutputStream byteOutPutStream) {
            //下载文件
            try {
                HttpHeaders headers = new HttpHeaders();
                if (byteOutPutStream != null && byteOutPutStream.toByteArray().length > 0) {
                    headers.setContentDispositionFormData("attachment", fileName);
                    return new ResponseEntity<byte[]>(byteOutPutStream.toByteArray(), headers, HttpStatus.OK);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }


}

WebContext


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class WebContext {
    private static final ThreadLocal<WebContext> LOCAL_CONTEXT = new ThreadLocal();
    private final HttpServletRequest request;
    private final HttpServletResponse response;

    public WebContext(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
    }

    public static void initWebContext(HttpServletRequest request, HttpServletResponse response) {
        WebContext context = new WebContext(request, response);
        initWebContext(context);
    }

    public static void initWebContext(WebContext webContext) {
        LOCAL_CONTEXT.set(webContext);
    }

    public static WebContext getWebContext() {
        return (WebContext)LOCAL_CONTEXT.get();
    }

    public static void clear() {
        LOCAL_CONTEXT.remove();
    }

    public HttpServletRequest getRequest() {
        return this.request;
    }

    public HttpServletResponse getResponse() {
        return this.response;
    }

    public HttpSession getSession() {
        return this.request.getSession();
    }

    public static String getHsSessionid() {
        return getWebContext().getRequest().getHeader("hssessionid");
    }

    public static String getHeader(String name) {
        return getHeader(name, "");
    }

    public static String getHeader(String name, String defaultValue) {
        return getWebContext() != null && getWebContext().getRequest() != null ? getWebContext().getRequest().getHeader(name) : defaultValue;
    }
}

TraceUtil


import org.apache.commons.lang.StringUtils;
import org.slf4j.MDC;
import org.springframework.util.CollectionUtils;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;

/**
 * Trace 工具
 **/
public class TraceUtil {

    public final static String TRACE_ID = "trace_id";
    public final static String TRACE_URI = "uri";

    /**
     * 初始化 TraceId
     * @param uri 请求uri
     */
    public static void initTrace(String uri) {
        if(StringUtils.isBlank(MDC.get(TRACE_ID))) {
            String traceId = generateTraceId();
            setTraceId(traceId);
            MDC.put(TRACE_URI, uri);
        }
    }


    /**
     * 将 Trace 相关信息,包括 TraceId 和 TraceUri 放入 RPC上下文中
     * 给 Dubbo 消费端调用
     * @param context Dubbo 的 RPC 上下文
     */
    public static String getCurrThreadTraceId() {
        String traceId = MDC.get(TRACE_ID);
        return traceId;
    }


    /**
     * 从 MDC 中清除当前线程的 Trace信息
     */
    public static void clearTrace() {
        MDC.clear();
    }

    /**
     * 将traceId放入MDC
     * @param traceId   链路ID
     */
    public static void setTraceId(String traceId) {
        traceId = StringUtils.left(traceId, 36);
        MDC.put(TRACE_ID, traceId);
    }

    /**
     * 生成traceId
     * @return  链路ID
     */
    private static String generateTraceId() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }


    public static <T> Callable<T> wrap(final Callable<T> callable, final Map<String, String> context) {
        return () -> {
            if (CollectionUtils.isEmpty(context)) {
                MDC.clear();
            } else {
                MDC.setContextMap(context);
            }
            try {
                return callable.call();
            } finally {
                // 清除子线程的,避免内存溢出,就和ThreadLocal.remove()一个原因
                MDC.clear();
            }
        };
    }

    public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
        return () -> {
            if (CollectionUtils.isEmpty(context)) {
                MDC.clear();
            } else {
                MDC.setContextMap(context);
            }
            try {
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}

ThreadLocalUtils

import java.util.*;


public final class ThreadLocalUtil {
    private static final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal() {
        protected Map<String, Object> initialValue() {
            return new HashMap(4);
        }
    };

    public static Map<String, Object> getThreadLocal(){
        return threadLocal.get();
    }
    public static <T> T get(String key) {
        Map map = (Map)threadLocal.get();
        return (T)map.get(key);
    }

    public static <T> T get(String key,T defaultValue) {
        Map map = (Map)threadLocal.get();
        return (T)map.get(key) == null ? defaultValue : (T)map.get(key);
    }

    public static void set(String key, Object value) {
        Map map = (Map)threadLocal.get();
        map.put(key, value);
    }

    public static void set(Map<String, Object> keyValueMap) {
        Map map = (Map)threadLocal.get();
        map.putAll(keyValueMap);
    }

    public static void remove() {
        threadLocal.remove();
    }

    public static <T> Map<String,T> fetchVarsByPrefix(String prefix) {
        Map<String,T> vars = new HashMap<>();
        if( prefix == null ){
            return vars;
        }
        Map map = (Map)threadLocal.get();
        Set<Map.Entry> set = map.entrySet();

        for( Map.Entry entry : set ){
            Object key = entry.getKey();
            if( key instanceof String ){
                if( ((String) key).startsWith(prefix) ){
                    vars.put((String)key,(T)entry.getValue());
                }
            }
        }
        return vars;
    }

    public static <T> T remove(String key) {
        Map map = (Map)threadLocal.get();
        return (T)map.remove(key);
    }

    public static void clear(String prefix) {
        if( prefix == null ){
            return;
        }
        Map map = (Map)threadLocal.get();
        Set<Map.Entry> set = map.entrySet();
        List<String> removeKeys = new ArrayList<>();

        for( Map.Entry entry : set ){
            Object key = entry.getKey();
            if( key instanceof String ){
                if( ((String) key).startsWith(prefix) ){
                    removeKeys.add((String)key);
                }
            }
        }
        for( String key : removeKeys ){
            map.remove(key);
        }
    }
}

BigDecimalUtil

import cn.hutool.core.util.StrUtil;
import com.gw.fund.org.common.enums.ErrorCodeEnum;
import com.gw.fund.org.common.exception.BizException;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Objects;


public class BigDecimalUtil {

    public final static BigDecimal ONE_HUNDRED = new BigDecimal("100.00");

    public static String bigDecimal2String(BigDecimal decimal) {
        return decimal == null ? StringUtils.EMPTY : decimal.toPlainString();
    }

    public static String bigDecimal2StringTrimZero(BigDecimal decimal) {
        return decimal == null ? StringUtils.EMPTY : decimal.stripTrailingZeros().toPlainString();
    }

    /*直接舍去*/
    public static String bigDecimal2String(BigDecimal decimal, int scale) {
        return decimal == null ? StringUtils.EMPTY : decimal.setScale(scale, BigDecimal.ROUND_DOWN).toPlainString();
    }

    /*四舍五入*/
    public static String bigDecimal2StringUp(BigDecimal decimal, int scale) {
        return decimal == null ? StringUtils.EMPTY : decimal.setScale(scale, BigDecimal.ROUND_HALF_UP).toPlainString();
    }

    /**
     * 金额前端展示格式化
     */
    // TODO: 2021/8/4 建议前端金额展示都通过该方法来格式化,保证可以统一处理
    public static String amountFrontShow(BigDecimal amount) {
        BigDecimal decimal = amountFront(amount);
        return decimal != null ? decimal.toPlainString() : null;
    }

    /**
     * 金额前端展示格式化
     */
    public static BigDecimal amountFront(BigDecimal amount) {
        // 前端金额展示格式化(当前保留2位小数,多余精度舍去)
        return amount != null ? amount.setScale(2, BigDecimal.ROUND_HALF_UP) : null;
    }

    public static String bigDecimalNull2String(BigDecimal decimal) {
        return decimal == null ? null : decimal.stripTrailingZeros().toPlainString();
    }

    public static BigDecimal formatBigDecimal(BigDecimal decimal) {
        return decimal == null ? BigDecimal.ZERO : decimal;
    }

    /**
     * 当参数不为null的时候,设置精度,直接舍去
     *
     * @param decimal
     * @param scale
     * @return
     */
    public static BigDecimal formatBigDecimalWhenNotnull(BigDecimal decimal, int scale) {
        return decimal != null ? decimal.setScale(scale, BigDecimal.ROUND_DOWN) : null;
    }

    /**
     * 当参数不为null的时候,设置精度,四舍五入
     *
     * @param decimal
     * @param scale
     * @return
     */
    public static BigDecimal formatBigDecimalWhenNotnullUp(BigDecimal decimal, int scale) {
        return decimal != null ? decimal.setScale(scale, BigDecimal.ROUND_HALF_UP) : null;
    }

    public static BigDecimal checkBigDecimal(BigDecimal decimal) {
        return decimal == null ? BigDecimal.ZERO : decimal;
    }

    /**
     * 返回折扣的描述信息
     * 比如: decimal 为  0.45 ,返回 4.5折
     * 比如: decimal 为  0.15 ,返回 1.5折
     */
    public static String discountDescr(BigDecimal decimal) {
        return decimal == null || BigDecimal.ZERO.compareTo(decimal) == 0 ? null : decimal.multiply(new BigDecimal("10")).stripTrailingZeros().toPlainString() + "折";
    }

    public static boolean isEmpty(BigDecimal decimal) {
        return decimal == null || BigDecimal.ZERO.compareTo(decimal) == 0;
    }

    public static boolean isNullOrZero(BigDecimal decimal) {
        return decimal == null || BigDecimal.ZERO.compareTo(decimal) == 0;
    }

    public static boolean isNotNull(BigDecimal decimal) {
        return decimal != null;
    }

    /**
     * 返回折扣的描述信息
     * 比如: decimal 为  0.45 ,返回 4.5折
     * 比如: decimal 为  0.15 ,返回 1.5折
     */
    public static String discountDescr(String decimalStr) {
        if (StringUtils.isBlank(decimalStr)) {
            return null;
        }
        BigDecimal decimal = new BigDecimal(decimalStr);
        return BigDecimal.ZERO.compareTo(decimal) == 0 ? null : decimal.multiply(new BigDecimal("10")).stripTrailingZeros().toPlainString() + "折";
    }

    /**
     * 扣率值 * 100 后返回 T 类型
     */
    public static <T> T multiply100Generic(String decimal, Class<T> t) {
        if (StringUtils.isBlank(decimal)) {
            return null;
        }
        if (t.getClass().equals(String.class)) {
            return (T) new BigDecimal(decimal).multiply(new BigDecimal("100")).stripTrailingZeros().toPlainString();
        }
        return (T) new BigDecimal(decimal).multiply(new BigDecimal("100"));
    }

    public static BigDecimal multiply(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) {
            return null;
        }
        return a.multiply(b);
    }

    /**
     * 指定精度
     */
    public static String bigDecimalScale(String decimal, int scale) {
        if (StringUtils.isBlank(decimal)) return null;

        return new BigDecimal(decimal).setScale(scale, BigDecimal.ROUND_HALF_UP).toPlainString();
    }

    public static String formatPercentData2String(BigDecimal decimal, int scale) {
        if (decimal == null) {
            return null;
        }
        return BigDecimal.valueOf(100).multiply(decimal).setScale(scale, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
    }

    public static BigDecimal formatPercentData(BigDecimal decimal, int scale) {
        if (decimal == null) {
            return null;
        }
        return BigDecimal.valueOf(100).multiply(decimal).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal formatPercentData(BigDecimal decimal) {
        if (decimal == null) {
            return null;
        }
        return BigDecimal.valueOf(100).multiply(decimal);
    }

    //省略0值
    public static String string2BigDecimalStringTrimZero(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        return new BigDecimal(str).stripTrailingZeros().stripTrailingZeros().toPlainString();
    }

    /**
     * 费率格式化,返回给前端:
     * 返回2位或者4位小数
     * 例如:1 返回 1.00
     * 例如:1.2 返回 1.20
     * 例如:1.21 返回 1.21
     * 例如:1.212 返回 1.2120
     * 例如:1.2121 返回 1.2121
     */
    public static String showRatio(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        //
        String calc = new BigDecimal(str).stripTrailingZeros().toPlainString();
        String res = StringUtils.substringAfter(calc, ".");
        if (StringUtils.isBlank(res)) {
            return calc + ".00";
        }
        if (res.length() == 1) {
            return calc + "0";
        }
        if (res.length() == 2) {
            return calc;
        }
        if (res.length() == 3) {
            return calc + "0";
        }
        if (res.length() == 4) {
            return calc;
        }
        if (res.length() > 4) {
            return StringUtils.substring(calc, 0, calc.length() - (res.length() - 4));
        }
        return calc;

    }

    /**
     * 减法: 如果两个参数都是null返回null,否则返回运算后的值
     */
    public static BigDecimal subtract(BigDecimal minuend, BigDecimal subtrahend) {
        if (minuend == null) {
            return null;
        }
        if (subtrahend == null) {
            return minuend;
        }
        return minuend.subtract(subtrahend);
    }

    /**
     * 加法: 如果两个参数都是null返回null,否则返回运算后的值
     */
    public static BigDecimal add(BigDecimal a, BigDecimal b) {
        if (a == null) {
            return b;
        }
        if (b == null) {
            return a;
        }
        return a.add(b);
    }

    /**
     * 加法: 如果两个参数都是null返回null,否则返回运算后的值
     */
    public static BigDecimal sumAdd(BigDecimal... arg) {
        BigDecimal sum = BigDecimal.ZERO;
        for (BigDecimal decimal : arg) {
            sum = add(sum, decimal);
        }
        return sum;
    }


    /**
     * 先截取两个小数,再累加
     * 加法: 如果两个参数都是null返回null,否则返回运算后的值
     */
    public static BigDecimal addSubFirst(BigDecimal a, BigDecimal b) {
        if (a == null && b == null) {
            return BigDecimal.ZERO;
        }
        if (b == null) {
            return a.setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        if (a == null) {
            return b.setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        return a.setScale(2, BigDecimal.ROUND_HALF_UP).add(b.setScale(2, BigDecimal.ROUND_HALF_UP));
    }

    /**
     * 加法: 如果两个参数都是null返回null,否则返回运算后的值
     */
    public static String addStr(String a, String b) {
        if (StringUtils.trimToNull(a) == null) {
            return StringUtils.trimToNull(b);
        }
        if (StringUtils.trimToNull(b) == null) {
            return StringUtils.trimToNull(a);
        }
        return new BigDecimal(a).add(new BigDecimal(b)).toPlainString();
    }

    public static BigDecimal string2BigDecimal(String str, int scale) {
        if (str == null || "".equals(str.trim())) {
            return null;
        }
        return new BigDecimal(str).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal string2BigDecimal(String str) {
        if (str == null || "".equals(str.trim())) {
            return BigDecimal.ZERO;
        }
        return new BigDecimal(str).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal string2PercentBigDecimal(String str, int scale) {
        if (str == null || "".equals(str.trim())) {
            return null;
        }
        return new BigDecimal(str).divide(new BigDecimal("100"), scale, BigDecimal.ROUND_HALF_UP);
    }

    public static String max(String buyLimitMin, String buyMinLimit) {
        if (StringUtils.isBlank(buyLimitMin) && StringUtils.isBlank(buyMinLimit)) {
            return BigDecimal.ZERO.toPlainString();
        }
        if (StringUtils.isBlank(buyLimitMin)) {
            return buyMinLimit;
        }
        if (StringUtils.isBlank(buyMinLimit)) {
            return buyLimitMin;
        }
        BigDecimal minLimit = new BigDecimal(buyLimitMin);
        BigDecimal limitMin = new BigDecimal(buyMinLimit);
        BigDecimal response = minLimit.compareTo(limitMin) >= 0 ? minLimit : limitMin;
        return response.toPlainString();
    }

    public static BigDecimal max(BigDecimal b1, BigDecimal b2) {
        if (b1 == null && b2 == null) {
            return BigDecimal.ZERO;
        }
        if (b1 == null) {
            return b2;
        }
        if (b2 == null) {
            return b1;
        }
        BigDecimal response = b1.compareTo(b2) >= 0 ? b1 : b2;
        return response;
    }

    public static String min(String buyLimitMin, String buyMinLimit) {
        if (StringUtils.isBlank(buyLimitMin) && StringUtils.isBlank(buyMinLimit)) {
            return BigDecimal.ZERO.toPlainString();
        }
        if (StringUtils.isBlank(buyLimitMin)) {
            return buyMinLimit;
        }
        if (StringUtils.isBlank(buyMinLimit)) {
            return buyLimitMin;
        }
        BigDecimal minLimit = new BigDecimal(buyLimitMin);
        BigDecimal limitMin = new BigDecimal(buyMinLimit);
        BigDecimal response = minLimit.compareTo(limitMin) >= 0 ? limitMin : minLimit;
        return response.toPlainString();
    }


    public static BigDecimal formatBigDecimal(BigDecimal decimal, int scale) {
        if (decimal == null) {
            return BigDecimal.ZERO;
        }
        return decimal.setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    public static String min(BigDecimal source, BigDecimal target) {
        if (source == null && target == null) {
            return null;
        }
        if (source == null) {
            return target.toPlainString();
        }
        if (target == null) {
            return source.toPlainString();
        }
        BigDecimal response = source.compareTo(target) >= 0 ? target : source;
        return response.toPlainString();
    }

    /**
     * @return a / b ,结果保留4位小数
     */
    public static BigDecimal divide(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) return null;
        if (BigDecimal.ZERO.compareTo(b) == 0) return BigDecimal.ZERO;
        return a.divide(b, 4, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * @param a
     * @param b
     * @param resultScale 指定结果的小数位数,必须大于0
     * @return
     */
    public static BigDecimal divide(BigDecimal a, BigDecimal b, int resultScale) {
        if (a == null || b == null) return null;
        if (BigDecimal.ZERO.compareTo(b) == 0) return BigDecimal.ZERO;
        return a.divide(b, resultScale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * @return 除后乘以100,结果保留2位小数
     */
    public static BigDecimal divideThenMulti100(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) return null;
        if (BigDecimal.ZERO.compareTo(b) == 0) return BigDecimal.ZERO;
        return a.divide(b, 6, BigDecimal.ROUND_HALF_UP).multiply(ONE_HUNDRED).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * @return 乘以100,结果保留2位小数
     */
    public static BigDecimal multi100(BigDecimal a) {
        if (Objects.isNull(a)) return null;
        return a.multiply(ONE_HUNDRED).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    public static String multi100(String a) {
        if (StrUtil.isEmpty(a)) return null;
        BigDecimal decimal = multi100(str2BigDecimal(a));
        return  bigDecimal2String(decimal, 2);
    }

    /**
     * 值为null返回数值0
     */
    public static BigDecimal null2zero(BigDecimal a) {
        if (a == null) return BigDecimal.ZERO;
        return a;
    }

    /**
     * 值为null返回数值0
     */
    public static BigDecimal null2NumberOne(BigDecimal a) {
        if (a == null) return BigDecimal.ONE;
        return a;
    }

    public static BigDecimal addThrowExceptionIfnull(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) {
            throw new BizException(ErrorCodeEnum.PARAMETER_EMPTY);
        }
        return a.add(b);
    }

    public static BigDecimal addTreatAsZeroIfnull(BigDecimal a, BigDecimal b) {
        if (a == null) {
            return b;
        }
        if (b == null) {
            return a;
        }
        return a.add(b);
    }

    /**
     * 参数为null 或者 小于0
     *
     * @param a
     * @return
     */
    public static boolean lessThanZeroOrIsnull(BigDecimal a) {
        if (a == null || BigDecimal.ZERO.compareTo(a) > 0) {
            return true;
        }
        return false;
    }

    public static BigDecimal str2BigDecimal(String decimal) {
        if (StringUtils.isEmpty(decimal)) {
            return null;
        }
        if (decimal.contains(",")) {
            decimal = decimal.replaceAll(",", "");
        }
        return new BigDecimal(decimal);
    }

    public static String docFormat(BigDecimal bigDecimal) {
        if (Objects.isNull(bigDecimal)) {
            return "0.00";
        }
        DecimalFormat decimal2 = new DecimalFormat("#,###,##0.00");
        if (isNotNull(bigDecimal)) {
            return decimal2.format(bigDecimal);
        }
        return "";
    }
    public static String docFormat2(BigDecimal bigDecimal) {
        if (Objects.isNull(bigDecimal)) {
            return "0.0000";
        }
        DecimalFormat decimal2 = new DecimalFormat("#,###,##0.0000");
        if (isNotNull(bigDecimal)) {
            return decimal2.format(bigDecimal);
        }
        return "";
    }

    /**
     * 返回乘以100后的值,返回小数点后两位
     * @param bigDecimal
     * @return
     */
    public static String multiply100(BigDecimal bigDecimal) {
        return bigDecimal2String(BigDecimalUtil.multiply(bigDecimal, new BigDecimal("100")), 2);
    }

    /**
     * 返回乘以1000后的值,返回小数点后两位
     * @param bigDecimal
     * @return
     */
    public static String multiply1000(BigDecimal bigDecimal) {
        return bigDecimal2String(BigDecimalUtil.multiply(bigDecimal, new BigDecimal("1000")), 2);
    }

    /**
     * 返回乘以10000后的值,返回小数点后两位
     * @param bigDecimal
     * @return
     */
    public static String multiply10000(BigDecimal bigDecimal) {
        return bigDecimal2String(BigDecimalUtil.multiply(bigDecimal, new BigDecimal("10000")), 2);
    }

    /**
     * 返回乘以10000后的值,返回小数点后两位
     * @param bigDecimal
     * @return
     */
    public static String div10000(BigDecimal bigDecimal) {
        return bigDecimal2String(BigDecimalUtil.divide(bigDecimal, new BigDecimal("10000")),0);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值