概述
自定义断言工具类
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学习道场】
最后
以上就是大气牛排为你收集整理的高质量java常用util类的全部内容,希望文章能够帮你解决高质量java常用util类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复