配置文件读取
PropertiesUtil
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Properties;
public class PropertiesUtil {
private static final Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
private static Properties p = new Properties();
static{
init();
}
private static void init(){
try {
p.load(new InputStreamReader(Objects.requireNonNull(PropertiesUtil.class.getClassLoader().getResourceAsStream("env_config.properties")), StandardCharsets.UTF_8));
} catch (IOException e) {
logger.error("Loading properties file error:", e);
}
}
/**
* Fetch value by key
* @param key key
* @return String
*/
public static String getValue(String key) {
return p.getProperty(key);
}
/**
* Put new value into file
* @param key key
* @param value value
*/
public static void writeProperty(String key, String value) {
p.setProperty(key.trim(), value.trim());
}
public static void main(String[] args) {
}
}
自定义异常
BusinessException
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 2874510430549463213L;
public BusinessException() {
super();
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
public BusinessException(String message) {
super(message);
}
public BusinessException(Throwable cause) {
super(cause);
}
private int returnCode;
public BusinessException(int returnCode) {
super();
this.returnCode = returnCode;
}
public BusinessException(Exception e, int returnCode) {
super(e);
this.returnCode = returnCode;
}
public BusinessException(String message, int returnCode) {
super(message);
this.returnCode = returnCode;
}
public BusinessException(String message, Exception e, int returnCode) {
super(message, e);
this.returnCode = returnCode;
}
public int getReturnCode() {
return returnCode;
}
public void setReturnCode(int returnCode) {
this.returnCode = returnCode;
}
}
redis相关
分布式锁
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.UUID;
@Component
public class RedisDistributedLock {
private static final String LUA_SCRIPT_LOCK = "return redis.call('set',KEYS[1],ARGV[1],'NX','PX',ARGV[2])";
private static final RedisScript<String> SCRIPT_LOCK = new DefaultRedisScript<String>(LUA_SCRIPT_LOCK, String.class);
private static final String LUA_SCRIPT_UNLOCK = "if redis.call('get',KEYS[1]) == ARGV[1] then return tostring(redis.call('del', KEYS[1])) else return '0' end";
private static final RedisScript<String> SCRIPT_UNLOCK = new DefaultRedisScript<String>(LUA_SCRIPT_UNLOCK, String.class);
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* 加锁
*
* @param redisKey 缓存KEY
* @param expire 到期时间 毫秒
* @param tryTimeout 尝试获取锁超时时间 毫秒
* @return redis锁信息
*/
public RedisLockInfo tryLock(String redisKey, long expire, long tryTimeout) {
Assert.isTrue(tryTimeout > 0, "tryTimeout必须大于0");
long timestamp = System.currentTimeMillis();
int tryCount = 0;
String lockId = UUID.randomUUID().toString();
while ((System.currentTimeMillis() - timestamp) < tryTimeout) {
try {
Object lockResult = redisTemplate.execute(SCRIPT_LOCK,
redisTemplate.getStringSerializer(),
redisTemplate.getStringSerializer(),
Collections.singletonList(redisKey),
lockId, String.valueOf(expire));
tryCount++;
if ("OK".equals(lockResult)) {
return new RedisLockInfo(lockId, redisKey, expire, tryTimeout, tryCount);
} else {
Thread.sleep(50);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 解锁
*
* @param redisLockInfo 获取锁返回的对象
* @return 是释放成功
*/
public boolean releaseLock(RedisLockInfo redisLockInfo) {
Object releaseResult = null;
try {
releaseResult = redisTemplate.execute(SCRIPT_UNLOCK,
redisTemplate.getStringSerializer(),
redisTemplate.getStringSerializer(),
Collections.singletonList(redisLockInfo.getRedisKey()),
redisLockInfo.getLockId());
} catch (Exception e) {
e.printStackTrace();
}
return null != releaseResult && releaseResult.equals(1);
}
}
- 锁信息
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class RedisLockInfo {
/**
* 锁ID UUID
*/
private String lockId;
/**
* REDIS KEY
*/
private String redisKey;
/**
* 过期时间
*/
private Long expire;
/**
* 尝试获取锁超时时间
*/
private Long tryTimeout;
/**
* 尝试获取锁次数
*/
private int tryCount;
}
RedisCacheManager
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @description: redis 工具类
*/
public class RedisCacheManager {
/**
* LOCK Result-成功标记
*/
private static final String LOCK_SUCCESS = "OK";
/**
* 当key不存在,进行set操作;若key已存在,则不做任何操作
*/
private static final String SET_IF_NOT_EXIST = "NX";
/**
* key加一个过期的设置
*/
private static final String SET_WITH_EXPIRE_TIME = "PX";
/**
* 锁的超时时间(毫秒)
*/
private static final Long TIMEOUT = 5000L;
/**
* RELEASE Result-成功标记
*/
private static final Long RELEASE_SUCCESS = 1L;
/**
* 单个节点相关requestId
* 可以用UUID.randomUUID().toString()
*/
public static final String REQUESTID_DEFAULT="fittime_requestId";
/**
* redisTemplate 对象
*/
private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 尝试获取分布式锁
* @param lockKey 锁(即key)
* @param requestId 请求标识,解锁时使用(即value或者UUID.randomUUID().toString()生成)
* @param expireTime 超期时间(单位毫秒)
* @return 是否获取成功
*/
public boolean tryGetDistributedLock(String lockKey, String requestId,Long expireTime) {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
String timeoutStr;
if(expireTime!=null){
timeoutStr=expireTime.toString();
}else {
timeoutStr=TIMEOUT.toString();
}
//加锁命令
Object obj = connection.execute("SET", lockKey.getBytes(), requestId.getBytes(),
SET_WITH_EXPIRE_TIME.getBytes(), timeoutStr.getBytes(), SET_IF_NOT_EXIST.getBytes());
return Arrays.equals(LOCK_SUCCESS.getBytes(), (byte[]) obj);
});
}
/**
* 释放分布式锁
* @param lockKey 锁(即key)
* @param requestId 请求标识,解锁时使用(即value)
* @return 是否释放成功
*/
public boolean releaseDistributedLock(String lockKey, String requestId) {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
//Lua脚本代码(原子性):先获取锁对应的value值,检查是否与requestId相等,如果相等则删除锁(解锁)
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
List<String> keys=Collections.singletonList(lockKey);
List<String> args=Collections.singletonList(requestId);
Object nativeConnection = connection.getNativeConnection();
Long result=0L;
if (nativeConnection instanceof JedisCluster) {
// 集群模式
result= (Long) ((JedisCluster) nativeConnection).eval(script, keys, args);
} else if (nativeConnection instanceof Jedis) {
// 单机模式
result= (Long) ((Jedis) nativeConnection).eval(script, keys, args);
}
if(RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;
});
}
//=============================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;
}
}
/**
* 普通缓存放入并设置时间
* @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);
}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);
}
//================================Map=================================
/**
* 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);
}
//============================set=============================
/**
* 根据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;
}
}
/**
* 获取redis中以某些字符串为前缀的KEY列表
* @param prefix key 前缀
* @return 移除的个数
*/
public Set<String> keySet(String prefix){
Set<String> keys = redisTemplate.keys(prefix);
return keys;
}
}
RedisLock
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class RedisLock {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* Redis 加锁
* @param key KEY
* @param value 超时时间
* @return boolean 加锁是否成功 true是 false否
*/
public boolean lock(String key, String value) {
// 先获取当前值
Object currentValue = redisTemplate.opsForValue().get(key);
if (null != currentValue) {
// 锁过期/重新设置值
if (Long.parseLong(String.valueOf(currentValue)) < System.currentTimeMillis()) {
redisTemplate.opsForValue().set(key, value);
return false;
} else {
return true;
}
}
redisTemplate.opsForValue().set(key, value);
return false;
// // 避免死锁,且只让一个线程拿到锁
// String currentValue = String.valueOf(redisTemplate.opsForValue().get(key));
//
// // 如果锁过期了
// if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) {
//
// // 获取上一个锁的时间
// String oldValues = String.valueOf(redisTemplate.opsForValue().getAndSet(key, value));
//
// // 如果旧的value和currentValue相等,只会有一个线程达成条件,因为第二个线程拿到的oldValue已经和currentValue不一样了
// return !StringUtils.isEmpty(oldValues) && oldValues.equals(currentValue);
// }
// return false;
}
/**
* Redis 解锁
* @param key KEY
* @param value VALUE
*/
public void unlock(String key, String value) {
try {
String currentValue = String.valueOf(redisTemplate.opsForValue().get(key));
if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
redisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Exception e) {
logger.error("[Redis分布式锁] 解锁异常: ", e);
}
}
}
RedisCacheUtil
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
@Service("redisCacheUtil")
public class RedisCacheUtil {
// @Qualifier("jedisTemplate")
@Resource
public RedisTemplate redisTemplate;
/**
* 缓存基本的对象,Integer、String、实体类等
* @param key 缓存的键值
* @param value 缓存的值
* @return 缓存的对象
*/
public <T> ValueOperations<String,T> setCacheObject(String key, T value) {
ValueOperations<String,T> operation = redisTemplate.opsForValue();
operation.set(key,value);
return operation;
}
// public <T> ValueOperations<String,T> setCacheObject(String key, T value, Double timeout) {
// ValueOperations<String,T> operation = redisTemplate.opsForValue();
// operation.set.set().set(key,value, timeout);
// return operation;
// }
/**
* 获得缓存的基本对象。
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(String key) {
ValueOperations<String,T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
/**
* 缓存List数据
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) {
ListOperations listOperation = redisTemplate.opsForList();
if(null != dataList) {
int size = dataList.size();
for(int i = 0; i < size ; i ++) {
listOperation.rightPush(key,dataList.get(i));
}
}
return listOperation;
}
/**
* 获得缓存的list对象
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getCacheList(String key) {
List<T> dataList = new ArrayList<T>();
try {
ListOperations<String, T> listOperation = redisTemplate.opsForList();
Long size = listOperation.size(key);
for (int i = 0; i < size; i++) {
dataList.add((T) listOperation.leftPop(key));
}
} catch (Exception ex) {
ex.printStackTrace();
}
return dataList;
}
/**
* 缓存Set
* @param key 缓存键值
* @param dataSet 缓存的数据
* @return 缓存数据的对象
*/
public <T> BoundSetOperations<String,T> setCacheSet(String key, Set<T> dataSet) {
BoundSetOperations<String,T> setOperation = redisTemplate.boundSetOps(key);
/*T[] t = (T[]) dataSet.toArray();
setOperation.add(t);*/
Iterator<T> it = dataSet.iterator();
while(it.hasNext()) {
setOperation.add(it.next());
}
return setOperation;
}
// /**
// * 获得缓存的set
// * @param key
// * @return
// */
// public Set<T> getCacheSet(String key) {
// Set<T> dataSet = new HashSet<T>();
// BoundSetOperations<String,T> operation = redisTemplate.boundSetOps(key);
//
// Long size = operation.size();
//
// for(int i = 0 ; i < size ; i++) {
// dataSet.add(operation.pop());
// }
// return dataSet;
// }
//
// /**
// * 缓存Map
// * @param key
// * @param dataMap
// * @return
// */
// public <T> HashOperations<String,String,T> setCacheMap(String key, Map<String,T> dataMap) {
//
// HashOperations hashOperations = redisTemplate.opsForHash();
// if(null != dataMap) {
//
// for (Map.Entry<String, T> entry : dataMap.entrySet()) {
// /*System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); */
// hashOperations.put(key,entry.getKey(),entry.getValue());
// }
// }
//
// return hashOperations;
// }
/**
* 获得缓存的Map
* @param key
* @return
* ,HashOperations<String,String,T> hashOperation
*/
public <T> Map<String,T> getCacheMap(String key) {
Map<String, T> map = redisTemplate.opsForHash().entries(key);
/*Map<String, T> map = hashOperation.entries(key);*/
return map;
}
/**
* 缓存Map
* @param key
* @param dataMap
* @return
*/
public <T> HashOperations<String,Integer,T> setCacheIntegerMap(String key,Map<Integer,T> dataMap) {
HashOperations hashOperations = redisTemplate.opsForHash();
if(null != dataMap) {
for (Map.Entry<Integer, T> entry : dataMap.entrySet()) {
/*System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); */
hashOperations.put(key,entry.getKey(),entry.getValue());
}
}
return hashOperations;
}
/**
* 获得缓存的Map
* @param key
* @return
* ,HashOperations<String,String,T> hashOperation
*/
public <T> Map<Integer,T> getCacheIntegerMap(String key) {
Map<Integer, T> map = redisTemplate.opsForHash().entries(key);
/*Map<String, T> map = hashOperation.entries(key);*/
return map;
}
/**
* 获取redis中以某些字符串为前缀的KEY列表
* @param prefix key 前缀
* @return 移除的个数
*/
public Set<String> keySet(String prefix){
Set<String> keys = redisTemplate.keys(prefix);
return keys;
}
}
返回信息
ResponseBean
public class ResponseBean<T> {
private Integer code = 0;
private String msg = null;
private T data = null;
public ResponseBean() {
}
public ResponseBean(T data) {
this.data = data;
}
public ResponseBean(String info, T data) {
this.msg = info;
this.data = data;
}
public ResponseBean(Integer code, String info, T data) {
super();
this.code = code;
this.msg = info;
this.data = data;
}
public ResponseBean(Integer code, String info) {
super();
this.code = code;
this.msg = info;
}
public static <T> ResponseBean onSuccess() {
ResponseBean<T> responseBean = new ResponseBean<>();
responseBean.fillResponse(ResponseCode.Common.SUCCESS, null);
return responseBean;
}
public static <T> ResponseBean onSuccess(ResponseCode.IResponseCode responseCode) {
ResponseBean<T> responseBean = new ResponseBean<>();
responseBean.fillResponse(responseCode, null);
return responseBean;
}
public static <T> ResponseBean onSuccess(T data) {
ResponseBean<T> result = new ResponseBean<>();
result.fillResponse(ResponseCode.Common.SUCCESS, data);
return result;
}
public static <T> ResponseBean onSuccess(ResponseCode.IResponseCode responseCode, T data) {
ResponseBean<T> result = new ResponseBean<>();
result.fillResponse(responseCode, data);
return result;
}
public static ResponseBean onFailure(ResponseCode.IResponseCode responseCode) {
return onFailure(responseCode, null);
}
public static <T> ResponseBean<T> onFailure(ResponseCode.IResponseCode responseCode, T data) {
ResponseBean<T> responseBean = new ResponseBean<>();
responseBean.fillResponse(responseCode, data);
return responseBean;
}
public static <T> ResponseBean<T> onFailureMessage( String message) {
ResponseBean<T> responseBean = new ResponseBean<>();
responseBean.fillResponse(ResponseCode.Common.FAILURE, null);
responseBean.setMsg(message);
return responseBean;
}
public static <T> ResponseBean<T> onFailureMessage(ResponseCode.IResponseCode responseCode, String message) {
ResponseBean<T> responseBean = new ResponseBean<>();
responseBean.fillResponse(responseCode, null);
responseBean.setMsg(message);
return responseBean;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
private void fillResponse(ResponseCode.IResponseCode responseCode, T data) {
setCode(responseCode.getCode());
setMsg(responseCode.getMsg());
setData(data);
}
}
ResponseCode
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 系统错误码: 16 01 001
* 系统 模块 详细错误
*/
public class ResponseCode {
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Common implements IResponseCode {
/* 返回Code码 */
SUCCESS(0, "成功"),
FAILURE(-1, "失败"),
INVALID_PARAMETER(400, "参数非法"),
UNAUTHORIZED(401, "无权访问"),
INTERFACE_EXCEPTION(402, "调用接口异常"),
PARAM_EXCEED_LIMIT(403, "超过字数限制");
private int code;
private String msg;
Common(int code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public int getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum PreSaleQn implements IResponseCode {
/* 返回Code码 */
RECORD_ALREADY_EXISTS(1601001, "不可重复插入");
private int code;
private String msg;
PreSaleQn(int code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public int getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
}
public interface IResponseCode {
int getCode();
String getMsg();
}
}
ResultJson
import com.alibaba.fastjson.JSONObject;
import com.fittime.common.util.DateUtils;
import com.fittime.common.util.enums.ResponseCodeEnums;
import lombok.Data;
import java.util.Date;
/**
* @description: ResultJson
*/
@Data
public class ResultJson {
private Integer returnCode;
private Object object;
private String returnDesc;
private String currentTime;
public ResultJson() {}
private ResultJson(Integer returnCode, Object object, String returnDesc) {
this.returnCode = returnCode;
this.object = object;
this.returnDesc = returnDesc;
this.currentTime = DateUtils.dateToStr(new Date(), DateUtils.DEFAULTPATTERN);
}
/**
* 成功操作返回数据
* @param data data
* @param <E> E
* @return E
*/
public static ResultJson success(Object data) {
JSONObject jsonSucess = new JSONObject();
jsonSucess.put("data", data);
return new ResultJson(ResponseCodeEnums.SUCCESS.getReturnCode(), jsonSucess, ResponseCodeEnums.SUCCESS.getChMessage());
}
/**
* 错误操作返回数据
* @param returnCode 状态码
* @param message 信息
* @param <E> 泛型
* @return ResultJson
*/
public static ResultJson badRequest(int returnCode, String message) {
JSONObject jsonBad = new JSONObject();
jsonBad.put("data", null);
return new ResultJson(returnCode, jsonBad, message);
}
/**
* 错误操作返回数据
* @return ResultJson
*/
public static ResultJson badRequest() {
JSONObject jsonBad = new JSONObject();
jsonBad.put("data", null);
return new ResultJson(ResponseCodeEnums.ERROR.getReturnCode(), jsonBad, ResponseCodeEnums.ERROR.getChMessage());
}
/**
* 设置结果数据
* @param resultJson ResultJson
* @param data 数据
*/
public static void setResultJson(ResultJson resultJson, Object data) {
if (null != resultJson) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("data", null == data ? "" : data);
resultJson.setObject(jsonObject);
resultJson.setCurrentTime(DateUtils.dateToStr(new Date(), DateUtils.DEFAULTPATTERN));
}
}
}
枚举
ResponseCodeEnums
/**
* 服务返回状态枚举
*/
public enum ResponseCodeEnums {
SUCCESS(200, "成功", "success"),
ERROR(500, "系统异常", "error"),
NAUTHORIZED(401, "未授权", "unauthorized"),
ACCESSFORBIDDEN(403, "禁止访问", "access forbidden"),
NOTFOUND(404, "您访问的资源不存在", "not found"),
// 自定义的错误码建议从10000开始
PLEASE_OPEN_IN_WEIXIN(10000, "请在微信中打开链接", ""),
USERID_IS_NOT_NULL(10001, "userId不能为空", ""),
SOURCE_IS_NULL(10002, "渠道码为空", ""),
CLUETYPE_IS_NULL(10003, "clueType不能为空", ""),
CLUETYPE_IS_ERROR(10004, "clueType只能为1或2", ""),
QUESTIONNAIREAGE_NULL(10005, "questionnaireAge不能为空", ""),
QUESTIONNAIREAGE_ERROR(10006, "questionnaireAge应为1~99整数", ""),
YOU_ARE_BUSYING(10007, "不能操作太频繁哦!", ""),
;
// 状态码
private Integer returnCode;
// 中文信息
private String chMessage;
// 英文信息
private String enMessage;
private ResponseCodeEnums(int returnCode, String chMessage, String enMessage) {
this.returnCode = returnCode;
this.chMessage = chMessage;
this.enMessage = enMessage;
}
public Integer getReturnCode() {
return returnCode;
}
public void setReturnCode(Integer returnCode) {
this.returnCode = returnCode;
}
public String getChMessage() {
return chMessage;
}
public void setChMessage(String chMessage) {
this.chMessage = chMessage;
}
public String getEnMessage() {
return enMessage;
}
public void setEnMessage(String enMessage) {
this.enMessage = enMessage;
}
}
跨域
CrossDomainFilter
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 处理跨域
*/
@Configuration
public class CrossDomainFilter extends OncePerRequestFilter {
private Logger log = LoggerFactory.getLogger(getClass());
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
log.info("跨域处理初始化......");
response.setHeader("Access-Control-Allow-Origin", "*");
//response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, x-rjft-request");
//response.setHeader("Access-Control-Expose-Headers", "Location");
filterChain.doFilter(request, response);
}
}
日期
DateUtils
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;
/**
* 日期工具类
*/
public class DateUtils {
public static final String DEFAULTPATTERN = "yyyy-MM-dd HH:mm:ss";
public static final String PATTERN_YYYY_MM_DD = "yyyy-MM-dd";
public static final SimpleDateFormat NORMAL_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
/**
* Date convert to string
*
* @param date 日期
* @param pattern 时间规则
* @return StringDate
*/
public static String dateToStr(Date date, String pattern) {
if (null != date) {
SimpleDateFormat format = new SimpleDateFormat(pattern);
return format.format(date);
} else {
return null;
}
}
/**
* 功能描述: LocalDateTime实现date2string(推荐)
*
* @param: [date, pattern]
* @return: java.lang.String
*/
public static String dateToStrByLocalDateTime(Date date, String pattern) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
Instant instant = date.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
LocalDateTime localDate = instant.atZone(zoneId).toLocalDateTime();
return df.format(localDate);
}
/**
* 功能描述: LocalDate实现date2string(推荐)
*
* @param: [date, pattern]
* @return: java.lang.String
*/
public static String dateToStrByLocalDate(Date date, String pattern) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
Instant instant = date.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
LocalDate localDate = instant.atZone(zoneId).toLocalDate();
return df.format(localDate);
}
/**
* String to date
*
* @param str String
* @return Date
*/
public static Date stringToDate(String str) {
DateFormat df = new SimpleDateFormat(DateUtils.PATTERN_YYYY_MM_DD);
Date date = null;
try {
date = df.parse(str);
} catch (ParseException e) {
}
return date;
}
/**
* 功能描述: LocalDateTime实现string2date(推荐)
*
* @param: [dateStr]
* @return: java.util.Date
*/
public static Date stringToDateByLocalDateTime(String dateStr) {
ZoneId zoneId = ZoneId.systemDefault();
LocalDateTime localDateTime = LocalDateTime.parse(dateStr);
ZonedDateTime zdt = localDateTime.atZone(zoneId);
return Date.from(zdt.toInstant());
}
/**
* 功能描述: LocalDate实现string2date(推荐)
*
* @param: [dateStr]
* @return: java.util.Date
*/
public static Date stringToDateByLocalDate(String dateStr) {
ZoneId zoneId = ZoneId.systemDefault();
LocalDate localDate = LocalDate.parse(dateStr);
ZonedDateTime zdt = localDate.atStartOfDay(zoneId);
return Date.from(zdt.toInstant());
}
/**
* 将时间字符串转换成时间戳
*
* @param dataStr
* @return
*/
public static long dataStr2Timestamp(String dataStr) {
return Timestamp.valueOf(dataStr).getTime() / 1000;
}
/**
* 给定一个时间计算距离现在的时间差精准到毫秒
*
* @param date 字符串时间
* @return 相差时间毫秒数
*/
public static long differentDateToNowsms(String date) {
try {
Date d = new SimpleDateFormat(DateUtils.DEFAULTPATTERN).parse(date);
long daysms = System.currentTimeMillis() - d.getTime();
return daysms;
} catch (Exception e) {
}
return 0;
}
/**
* 两个日期之间差值(毫秒)
*
* @param strDate1
* @param strDate2
* @param formatStr
* @return -1 异常
*/
public static long different2DateSms(String strDate1, String strDate2, String formatStr) {
SimpleDateFormat format = new SimpleDateFormat(formatStr);
try {
Date dt1 = format.parse(strDate1);
Date dt2 = format.parse(strDate2);
return dt1.getTime() - dt2.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return -1L;
}
/**
* 计算两个日期相差的天数
*
* @param startDate 开始时间
* @param endDate 结束时间
* @return
*/
public static int different2DateDays(Date startDate, Date endDate) {
return (int) ((endDate.getTime() - startDate.getTime()) / (3600 * 1000 * 24));
}
/**
* 日期相差的周数
*
* @param source
* @param date
* @return
*/
public static int different2DateWeek(Date source, Date date) {
if (source.after(date)) {
return 1;
}
int week = 0;
Calendar cal = Calendar.getInstance();
cal.setTime(source);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
while (true) {
if (!calendar.before(cal)) {
cal.add(Calendar.DAY_OF_YEAR, 7);
week++;
} else {
break;
}
}
return week;
}
/**
* 功能描述: 当前日期
*
* @param: [dateStr]
* @return: java.util.Date
*/
public static Date localDate() {
ZoneId zoneId = ZoneId.systemDefault();
LocalDate localDate = LocalDate.now();
ZonedDateTime zdt = localDate.atStartOfDay(zoneId);
return Date.from(zdt.toInstant());
}
/**
* 功能描述: 计算2个日期是否为同一天
*
* @date: 2019/3/21 下午7:42
* @param: [date1, date2]
* @return: boolean
*/
public static boolean isSameDate(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
//年月日都相同就是同一天
boolean isSameYear = cal1.get(Calendar.YEAR) == cal2
.get(Calendar.YEAR);
boolean isSameMonth = isSameYear
&& cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
boolean isSameDate = isSameMonth
&& cal1.get(Calendar.DAY_OF_MONTH) == cal2
.get(Calendar.DAY_OF_MONTH);
return isSameDate;
}
/**
* 获取当前时间的前n天或后n天
*
* @param format 格式化
* @param day -n 表示前 +n 表示后
* @return String
*/
public static String getBeforeOrAfterCurrentTime(String format, int day) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, day);
date = calendar.getTime();
return sdf.format(date);
}
/**
* 功能描述: 获得某个时间前几天的时间
*
* @param time 当前时间
* @param num 前几天
* @param haveTime true显示时间
* @return java.util.String
*/
public static String beforeDayByPoint(Date time, int num, boolean isBefore, boolean haveTime) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(time);
if (isBefore) {
// * 00:00:00
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH) - num, 0, 0, 0);
} else {
// * 23:59:59
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH) - num, 23, 59, 59);
}
if (haveTime) {
// 生成时间带毫秒数如*.233,这里作用是去掉
return dateToStr(calendar.getTime(), DEFAULTPATTERN);
} else {
return dateToStr(calendar.getTime(), PATTERN_YYYY_MM_DD);
}
}
/**
* 得到一个时间延后或前移几天的时间
*
* @param nowdate 日期
* @param delay delay为前移或后延的天数 正数为后推 负数为前推
* @return
*/
public static Date getNextOrPreDayByDate(Date nowdate, int delay) {
try {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
long myTime = (nowdate.getTime() / 1000) + delay * 24 * 60 * 60;
nowdate.setTime(myTime * 1000);
return nowdate;
} catch (Exception e) {
return null;
}
}
/**
* 获得起始日期和终止日期的所有区间内日期
*
* @param startLocalDate 开始日期
* @param endLocalDate 截止日期
* @return 区间内所有日期集合
*/
public static List<LocalDate> getAllDateBetweenStartAndEnd(LocalDate startLocalDate, LocalDate endLocalDate) {
List<LocalDate> resultList = new ArrayList();
long betweenDays = ChronoUnit.DAYS.between(startLocalDate, endLocalDate);
if (betweenDays < 1) {
return resultList;
}
Stream.iterate(startLocalDate, localDate -> localDate.plusDays(1)).limit(betweenDays + 1).forEach(resultList::add);
return resultList;
}
/**
* 两个日期之间的比较
*
* @param dt1
* @param dt2
* @return 1 小于 2大于 0等于
*/
public static int compareDate(Date dt1, Date dt2) {
if (dt1.getTime() < dt2.getTime()) {
return 1;
} else if (dt1.getTime() > dt2.getTime()) {
return 2;
} else {
return 0;
}
}
/**
* 两个日期之间的比较
*
* @param strDate1
* @param strDate2
* @param formatStr
* @return 1 小于; 2 大于; 0 等于 ;-1 异常
*/
public static int compare2Date(String strDate1, String strDate2, String formatStr) {
SimpleDateFormat format = new SimpleDateFormat(formatStr);
try {
Date dt1 = format.parse(strDate1);
Date dt2 = format.parse(strDate2);
return compareDate(dt1, dt2);
} catch (ParseException e) {
e.printStackTrace();
}
return -1;
}
/**
* 由出生日期获得年龄
*
* @param birthDay
* @return
* @throws Exception
*/
public static int getAgeByBirthDay(Date birthDay) throws Exception {
Calendar cal = Calendar.getInstance();
if (cal.before(birthDay)) {
throw new IllegalArgumentException(
"The birthDay is before Now.It's unbelievable!");
}
int yearNow = cal.get(Calendar.YEAR);
int monthNow = cal.get(Calendar.MONTH);
int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
cal.setTime(birthDay);
int yearBirth = cal.get(Calendar.YEAR);
int monthBirth = cal.get(Calendar.MONTH);
int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
int age = yearNow - yearBirth;
if (monthNow <= monthBirth) {
if (monthNow == monthBirth) {
if (dayOfMonthNow < dayOfMonthBirth) {
age--;
}
} else {
age--;
}
}
return age;
}
/**
* 功能描述: 根据年龄算生日
* <p>
* 当然这个时间是不准确的
*
* @auther: zemin.liu
* @date: 2018/11/7 下午4:42
* @param: [age, createtime]
* @return: java.lang.String
*/
public static Date getBirthdayByAge(int age) {
Calendar c3 = Calendar.getInstance();
c3.add(Calendar.YEAR, -age);
return c3.getTime();
}
/**
* 给定时间段和星期几,计算该时间段内共有多少个给定的星期几
*
* @param start 开始时间,格式yyyy-MM-dd
* @param end 结束时间,格式yyyy-MM-dd
* @param a 星期几,从星期一到星期天,分别用数字0-6表示,包含起始终止日期
* @return 星期几统计数
*/
public static long weekend(String start, String end, int a) {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
long sunDay = 0;//计数
try {
Calendar startDate = Calendar.getInstance(); //开始时间
startDate.setTime(format.parse(start));
Calendar endDate = Calendar.getInstance();//结束时间
endDate.setTime(format.parse(end));
int SW = startDate.get(Calendar.DAY_OF_WEEK) - 1;//开始日期是星期几
int EW = endDate.get(Calendar.DAY_OF_WEEK) - 1;//结束日期是星期几
long diff = endDate.getTimeInMillis() - startDate.getTimeInMillis();
long days = diff / (1000 * 60 * 60 * 24);//给定时间段内一共有多少天
long w = Math.round(Math.ceil(((days + SW + (7 - EW)) / 7.0)));//给定时间内,共有多少个星期
sunDay = w;//总的星期几统计数
if (a < SW)//给定的星期几小于起始日期的星期几,需要减少一天
{
sunDay--;
}
if (a > EW)//给定的星期几大于结束日期的星期几,需要减少一天
{
sunDay--;
}
} catch (Exception se) {
se.printStackTrace();
}
return sunDay;
}
/**
* @description 计算两个日期间的日子
* @Date: 2020/5/22 3:33 下午
* @param: [begin, end]
* @return: java.util.List<java.lang.String>
*/
public static List<String> getDayListBetween(String begin, String end) throws ParseException {
List<String> strDate = new ArrayList<>();
strDate.add(begin);
Calendar calendar = Calendar.getInstance();
calendar.setTime(NORMAL_DATE_FORMAT.parse(begin));
while (true) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
if (NORMAL_DATE_FORMAT.parse(end).after(calendar.getTime())) {
strDate.add(NORMAL_DATE_FORMAT.format(calendar.getTime()).toString());
} else {
break;
}
}
if (!begin.equals(end)) {
strDate.add(end);
}
return strDate;
}
/**
* 判断日期是星期几
*
* @description
* @Date: 2020/5/22 3:53 下午
* @param: [dateStr]
* @return: java.lang.String
*/
public static String getWeekStr(String dateStr) throws ParseException {
Date date = NORMAL_DATE_FORMAT.parse(dateStr);
Calendar cal = Calendar.getInstance();
if (date != null) {
cal.setTime(date);
}
int week = cal.get(Calendar.DAY_OF_WEEK);
switch (week) {
case 1:
return "星期日";
case 2:
return "星期一";
case 3:
return "星期二";
case 4:
return "星期三";
case 5:
return "星期四";
case 6:
return "星期五";
case 7:
return "星期六";
default:
return "";
}
}
/**
* 功能描述: 获得指定时间
*
* @param time 当前时间
* @param hourOfDay 时
* @param minute 分
* @param second 秒
* @return java.util.String
*/
public static String dayTimePoint(Date time, int hourOfDay, int minute, int second) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(time);
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH), hourOfDay, minute, second);
return dateToStr(calendar.getTime(), DEFAULTPATTERN);
}
/**
* 判断当前时间是否在某个时间范围
*
* @param date 判断时间点
* @param start 开始始时间,例如:yyyy-MM-dd HH:mm:ss
* @param end 结束时间,例如:yyyy-MM-dd HH:mm:ss
* @param pattern 时间格式化格式,例如:yyyy-MM-dd HH:mm:ss
* @return boolean
*/
public static boolean currentTimeInTime(Date date, String start, String end, String pattern) {
try {
SimpleDateFormat format = new SimpleDateFormat(pattern);
Date startTime = format.parse(start);
Date endTime = format.parse(end);
return startTime.before(date) && endTime.after(date);
} catch (ParseException e) {
e.printStackTrace();
}
return false;
}
}
国际日期
String x = "Mon Mar 02 13:57:49 CST 2015";
SimpleDateFormat sdf1 = new SimpleDateFormat ("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
try
{
Date date=sdf1.parse(x);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
String sDate=sdf.format(date);
System.out.println(sDate);
}
catch (ParseException e)
{
e.printStackTrace();
}
//先把字符串转化成Date,再把Date转换成你想要的格式
IP地址
IpAddressUtil
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
*/
public class IpAddressUtil {
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || CommonConstants.UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || CommonConstants.UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || CommonConstants.UNKNOWN.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (CommonConstants.LOCAL_HOST.equals(ipAddress) || CommonConstants.MAC_ADDR.equals(ipAddress)) {
//根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
assert inet != null;
ipAddress = inet.getHostAddress();
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > CommonConstants.N15) {
if (ipAddress.indexOf(CommonConstants.DOU_HAO) > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(CommonConstants.DOU_HAO));
}
}
return ipAddress;
}
}
IpUtil
import com.alibaba.fastjson.JSON;
import com.fittime.common.constant.CommonConstants;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import java.io.File;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* 查询算法
* DbSearcher.BINARY_ALGORITHM //Binary
* DbSearcher.MEMORY_ALGORITYM //Memory
* @createdate 2020-07-30 15:17
*/
@Slf4j
public class IpUtil {
private static final String DBPATH = Objects.requireNonNull(IpUtil.class.getClassLoader().getResource("ip2region.db")).getPath();
private static String getCityInfo(String ip) {
File file = new File(DBPATH);
if (!file.exists()) {
log.info("[Error: Invalid ip2region.db file] {}", ip);
}
try {
DbConfig config = new DbConfig();
DbSearcher searcher = new DbSearcher(config, DBPATH);
Method method = searcher.getClass().getMethod("btreeSearch", String.class);
DataBlock dataBlock;
if (!Util.isIpAddress(ip)) {
log.info("[Error: Invalid ip address] {}", ip);
}
dataBlock = (DataBlock) method.invoke(searcher, ip);
return dataBlock.getRegion();
} catch (Exception e) {
log.error("[IP获取地域错误]", e);
}
return null;
}
/**
* 获取IP信息数组
* 上海IP:114.80.166.240 ["中国","0","上海","上海市","电信"]
* 北京IP:210.51.167.169 ["中国","0","北京","北京市","联通"]
* 广州IP:192.168.1.157 ["中国","0","广东省","广州市","电信"]
* 深圳IP:116.76.73.232 ["中国","0","广东省","深圳市","天威"]
* 其它省份:["中国","0","山西省","临汾市","电信"]
* 无效IP:["0","0","0","内网IP","内网IP"]
* @param ip IP
* @return String[]
*/
public static String[] getIpInfos(String ip) {
String ipStr = IpUtil.getCityInfo(ip);
log.info("[根据IP获取到到地址信息] {}, {}", ip, ipStr);
return Objects.requireNonNull(ipStr).split(CommonConstants.FEN_GE_FU);
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
String ip = "116.76.73.233";
System.out.println(JSON.toJSONString(IpUtil.getIpInfos(ip)));
System.out.println("耗时:"+ (System.currentTimeMillis() - start));
}
}
json相关
JacksonUtil
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class JacksonUtil {
private static Logger log = LoggerFactory.getLogger(JacksonUtil.class);
private static ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);// 允许字段名不带引号
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
private static XmlMapper xmlMapper = new XmlMapper();
/**
* map convert to xml string
*
* @param obj
* @return
*/
public static String map2xml(Map<String, Object> map) {
try {
return xmlMapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
log.error("map2xml error. map=" + map, e);
return null;
}
}
/**
* javabean,list,array convert to xml string
*
* @param obj
* @return
*/
public static String obj2xml(Object obj) {
try {
return xmlMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
// log.error("obj2xml error. obj=" + ToStringBuilder.reflectionToString(obj), e);
return null;
}
}
/**
* javaBean,list,array convert to json string
*/
public static String obj2json(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
// log.error("obj2json error. obj=" + ToStringBuilder.reflectionToString(obj), e);
return null;
}
}
/**
* xml string convert to java bean
*
* @param xmlStr
* @param clazz
* @return
*/
public static <T> T xml2pojo(String xmlStr, Class<T> clazz) {
try {
return xmlMapper.readValue(xmlStr, clazz);
} catch (IOException e) {
log.error("xml2pojo error. xml=" + xmlStr + "clazz=" + clazz, e);
return null;
}
}
/**
* json string convert to javaBean
*/
public static <T> T json2pojo(String jsonStr, Class<T> clazz) {
try {
return objectMapper.readValue(jsonStr, clazz);
} catch (IOException e) {
log.error("json2pojo error. json=" + jsonStr + ", clazz=" + clazz, e);
return null;
}
}
/**
* xml string convert to map
*
* @param xmlStr
* @return
*/
@SuppressWarnings("unchecked")
public static Map<String, Object> xml2map(String xmlStr) {
try {
return xmlMapper.readValue(xmlStr, Map.class);
} catch (IOException e) {
log.error("xml2map error. xml=" + xmlStr, e);
return null;
}
}
/**
* json string convert to map
*/
@SuppressWarnings("unchecked")
public static <T> Map<String, Object> json2map(String jsonStr) {
try {
return objectMapper.readValue(jsonStr, Map.class);
} catch (IOException e) {
log.error("json2map error, json=" + jsonStr, e);
return null;
}
}
/**
* json string convert to map with javaBean
*/
public static <T> Map<String, T> json2map(String jsonStr, Class<T> clazz) {
try {
Map<String, Map<String, Object>> map = objectMapper.readValue(jsonStr, new TypeReference<Map<String, T>>() {
});
Map<String, T> result = new HashMap<String, T>();
for (Entry<String, Map<String, Object>> entry : map.entrySet()) {
result.put(entry.getKey(), objectMapper.convertValue(entry.getValue(), clazz));
}
return result;
} catch (Exception e) {
log.error("json2map error, json=" + jsonStr + ", clazz=" + clazz, e);
return null;
}
}
/**
* json array string convert to list with javaBean
*/
public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception {
List<Map<String, Object>> list = objectMapper.readValue(jsonArrayStr, new TypeReference<List<T>>() {
});
List<T> result = new ArrayList<T>();
for (Map<String, Object> map : list) {
result.add(map2pojo(map, clazz));
}
return result;
}
/**
* map convert to javaBean
*/
@SuppressWarnings("rawtypes")
public static <T> T map2pojo(Map map, Class<T> clazz) {
return objectMapper.convertValue(map, clazz);
}
/**
* json string convert to xml string
*/
public static String json2xml(String jsonStr) throws Exception {
JsonNode root = objectMapper.readTree(jsonStr);
String xml = xmlMapper.writeValueAsString(root);
return xml;
}
/**
* xml string convert to json string
*/
public static String xml2json(String xml) throws Exception {
StringWriter w = new StringWriter();
JsonParser jp = xmlMapper.getFactory().createParser(xml);
JsonGenerator jg = objectMapper.getFactory().createGenerator(w);
while (jp.nextToken() != null) {
jg.copyCurrentEvent(jp);
}
jp.close();
jg.close();
return w.toString();
}
}
JSONUtils
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class JSONUtils {
private static final ObjectMapper MAPPER = new ObjectMapper();
private JSONUtils() {
}
public static String writeString(Object o) {
if (o != null) {
try {
return MAPPER.writeValueAsString(o);
} catch (JsonProcessingException ignored) {
log.error("JSONUtils writeString exception {}", ignored);
}
}
return "";
}
public static <T> T readValue(String json, JavaType javaType) {
if (StringUtils.isNotEmpty(json)) {
try {
return MAPPER.readValue(json, javaType);
} catch (IOException ignored) {
log.error("JSONUtils readValue exception {}", ignored);
}
}
return null;
}
public static <T> T readValue(String json, Class<T> clazz) {
if (StringUtils.isNotEmpty(json)) {
try {
return MAPPER.readValue(json, clazz);
} catch (IOException ignored) {
log.error("JSONUtils readValue exception {}", ignored);
}
}
return null;
}
public static <T> List<T> readListValue(String json, Class<T> clazz) {
if (StringUtils.isNotEmpty(json)) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(ArrayList.class, clazz);
try {
return MAPPER.readValue(json, javaType);
} catch (IOException ignored) {
log.error("JSONUtils readListValue exception {}", ignored);
}
}
return null;
}
}
JsonSerializationUtil
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
/**
* Jackson json序列化和反序列化工具类
* Created by macro on 2018/4/26.
*/
public class JsonUtil {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成json字符串。
*/
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @param beanType 对象中的object类型
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成pojo对象list
*/
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
ReadJsonFileUtil
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;
import java.util.Map;
/**
* 对json文件的读操作
*/
public class LocalJSONFileUtil {
/**
* 根据key获取json
* @param filepath 文件路径
* @param key json的key
* @return
*/
public static Object getJSONByKey(String filepath, String key){
String text = LocalJSONFileUtil.getFileText(filepath);
JSONObject object = new JSONObject();
if (StringUtils.isNoneBlank(text)){
object = parseObject(text);
}
return object.get(key);
}
/**
* 将json 字符串转换为json对象
*/
public static JSONObject parseObject(String text) {
return JSONObject.parseObject(text);
}
/**
* 获取文件内文本
* @param filepath
* @return
*/
public static String getFileText(String filepath){
StringBuffer sb = new StringBuffer();
try{
ClassPathResource classPathResource = new ClassPathResource(filepath);
Reader reader = new InputStreamReader(classPathResource.getInputStream());
int ch = 0;
while ((ch = reader.read())!=-1){
sb.append((char)ch);
}
}catch (Exception e) {
e.printStackTrace();
}
return sb.toString().replaceAll("\r\n","").replaceAll(" ", "");
}
}
class Text{
public static void main(String[] args) {
System.out.println("获取json文本,也可以获取txt文本");
String textJOSN = LocalJSONFileUtil.getFileText("templates/localJSON.json");
System.out.println(textJOSN); //{ "key1": "value1", "key2": "value2", "key3": [{"key1": "value1"},{"key2": "value2"}]}
String txt = LocalJSONFileUtil.getFileText("templates/localJSON.txt"); // 测试文本
System.out.println(txt);
// LocalJSONFileUtil.getJSONByKey()
System.out.println("=============通过key获取对象=================");
String key2 = (String) LocalJSONFileUtil.getJSONByKey("templates/localJSON.json","key2");
System.out.println("key2:"+key2); // key2:value2
List<Map<String,Object>> key3 = (List<Map<String, Object>>) LocalJSONFileUtil.getJSONByKey("templates/localJSON.json","key3");
System.out.println(key3); // [{"key1":"value1"},{"key2":"value2"}]
Map<String,Object> key4 = (Map<String, Object>) LocalJSONFileUtil.getJSONByKey("templates/localJSON.json","key4");
System.out.println(key4); //{"key1":"value1"}
System.out.println("=========获取整体json对象=============");
Map<String,Object> objectMap = LocalJSONFileUtil.parseObject(LocalJSONFileUtil.getFileText("templates/localJSON.json"));
System.out.println(objectMap.get("key1")); // value1
Map<String,Object> objectMap2 = JSONObject.parseObject(LocalJSONFileUtil.getFileText("templates/localJSON.json"));
System.out.println(objectMap2.get("key1"));
System.out.println("向文本内写入值,一般工作中没有这个需求,思路也很简单,封装个方法,参数为,路径,key,value, 通过路径读取JSON到程序,通过map的put方法向json中put值,最后将数据再次写入到JSON文件内就行了");
}
}
线程池相关
ThreadPoolUtils
import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 线程工具类
*/
public class ThreadPoolUtils {
public static AtomicInteger ai = new AtomicInteger(0);
/** 线程池基本参数*/
private static int corePoolSize = Runtime.getRuntime().availableProcessors(),
maxPoolSize = 200,keepAliveTime = 30,queueCapacity = 100;
private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(queueCapacity),
new ThreadPoolExecutor.CallerRunsPolicy());
public static void addProcess(Runnable runnable){
try {
threadPool.execute(runnable);
} catch (Exception e) {
// log.error("调用线程池的addProcess方法出错", e);
}
}
public static <T> Future<T> addTask(Callable<T> task){
return threadPool.submit(task);
}
public static <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks){
try {
return threadPool.invokeAll(tasks);
} catch (InterruptedException e) {
e.printStackTrace();
// log.error("调用线程池的invokeAll方法出错", e);
}
return null;
}
public static <T> T invokeAny(Collection<? extends Callable<T>> tasks){
try {
return threadPool.invokeAny(tasks);
} catch (Exception e) {
e.printStackTrace();
// log.error("调用线程池的invokeAny方法出错", e);
}
return null;
}
}
拦截器相关
InterfaceLoggerFilter
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fittime.ecom.common.constants.CommonConstant;
import com.fittime.ecom.common.util.IpAddressUtil;
/**
* 项目接口拦截器处理
*/
public class InterfaceLoggerFilter implements Filter {
private Logger logger = LoggerFactory.getLogger(InterfaceLoggerFilter.class);
@Override
public void init(FilterConfig filter) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
long startTime, endTime;
Map<String,String[]> params = new HashMap<String,String[]>(request.getParameterMap());
StringBuffer sbParams = new StringBuffer();
sbParams.append("?");
for (String key : params.keySet()) {
if(null == key || null == params.get(key) || null == params.get(key)[0]){ continue;}
sbParams.append(key).append("=").append(params.get(key)[0]).append("&");
}
if(sbParams.length() > 1) {sbParams = sbParams.delete(sbParams.length() - 1, sbParams.length());}
String fullUrl = ((HttpServletRequest)request).getRequestURL().toString();
String token = getToken((HttpServletRequest)request);
String requestType = ((HttpServletRequest)request).getMethod();
String userId = request.getParameter("userId");
//前置条件:将不符合条件的URL地址予以过滤
if(null == fullUrl) {
chain.doFilter(request, response);
return;
}
int re1=fullUrl.indexOf(".json");
int re2=fullUrl.indexOf(".html");
int re3=fullUrl.indexOf("index.html");
if((re1 == -1 && re2 == -1) || re3 != -1){
chain.doFilter(request, response);
return;
}
//前置条件:token为空情况处理
if(null == token) {
logger.info(formMapKey(userId, "token is null url=" + fullUrl, requestType,
IpAddressUtil.getIpAddr((HttpServletRequest)request), sbParams.toString(), "null")
+ ",\"cost\":\"" + 0 + "ms\"");
chain.doFilter(request, response);
return;
}
//前置条件:所有异常统一捕捉处理
try {
startTime = System.currentTimeMillis();
chain.doFilter(request, response);
endTime = System.currentTimeMillis();
int startIntercept = fullUrl.lastIndexOf("/") + 1;
int endIntercept = fullUrl.lastIndexOf(".json");
String interfaceName = fullUrl.substring(startIntercept, endIntercept) + ".json";
logger.info(formMapKey(userId, interfaceName, requestType,
IpAddressUtil.getIpAddr((HttpServletRequest) request), sbParams.toString(), token)
+ ",\"cost\":\"" + (endTime - startTime) + "ms\"");
} catch (Exception ex) {
chain.doFilter(request, response);
logger.info("项目接口监控异常fullUrl:" + fullUrl + " message:" + ex.getMessage());
}
}
private String formMapKey(Object userId, String mothedName, String requestType,
String ip, String params, String token) {
return "\"time\"" + ":\"" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date())
+ "\",\"name\"" + ":\"" + mothedName + "\",\"uid\":\"" + userId
+ "\",\"type\":\"" + requestType + "\",\"ip\":\"" + ip
+ "\",\"token\":\"" + token + "\",\"params\":\"" + params + "\"";
}
private String getRequestType(HttpServletRequest request) {
String ajaxHeader = request.getHeader(CommonConstant.AJAX_REQUEST_HEADER_KEY);
if (ajaxHeader != null && ajaxHeader.equalsIgnoreCase(CommonConstant.AJAX_REQUEST_HEADER_VALUE)) {
return "ajax";
}
String nativeValue = request.getHeader(CommonConstant.AJAX_NATIVE_HEADER_KEY);
if (nativeValue != null && nativeValue.equalsIgnoreCase(CommonConstant.AJAX_NATIVE_HEADER_VALUE)) {
return "native";
}
return "web";
}
private String getToken(HttpServletRequest request) {
String token = request.getHeader(CommonConstant.AJAX_REQUEST_TOKEN_KEY);
if(StringUtils.isNotBlank(token)){
//Bearer xxxxxx (xxxxxx 是 token)
String[] temp = token.split(" ");
if(temp.length > 1){
return temp[1];
}
}
return null;
}
}
数字运算相关
Arith
import java.math.BigDecimal;
public class Arith {
private static final int DEF_DIV_SCALE = 10;
/**
* * 两个Double数相加 *
*
* @param v1 *
* @param v2 *
* @return Double
*/
public static Double add(Double v1, Double v2) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.add(b2).doubleValue());
}
public static Double add(Double v1, Double v2, Double v3) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
BigDecimal b3 = new BigDecimal(v3.toString());
return new Double(b1.add(b2).add(b3).doubleValue());
}
/**
* * 两个Double数相减 *
*
* @param v1 *
* @param v2 *
* @return Double
*/
public static Double sub(Double v1, Double v2) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.subtract(b2).doubleValue());
}
/**
* * 两个Double数相乘 *
*
* @param v1 *
* @param v2 *
* @return Double
*/
public static Double mul(Double v1, Double v2) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.multiply(b2).doubleValue());
}
/**
* * 两个Double数相除 *
*
* @param v1 *
* @param v2 *
* @return Double
*/
public static Double div(Double v1, Double v2) {
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP)
.doubleValue());
}
/**
* * 两个Double数相除,并保留scale位小数 *
*
* @param v1 *
* @param v2 *
* @param scale *
* @return Double
*/
public static Double div(Double v1, Double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1.toString());
BigDecimal b2 = new BigDecimal(v2.toString());
return new Double(b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue());
}
}
图片相关
CompressorUtil
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;
/**
* @description: 图片压缩工具类
*/
public class CompressorUtil {
/**
* This ratio that indicating the desired quality level, it is between 0 and 1
*/
private static final float IMAGE_QUALITY_LEVEL = 0.6f;
/**
* 方式1:根据文件方式操作
*
* @param src 原文件地址
* @param dest 生成图片地址
* @return void
*/
public static void resize(String src, String dest) throws IOException {
// file转为图片对象
Image img = ImageIO.read(new File(src));
BufferedImage tempPNG = resizeImage(img);
// 裁剪不压缩,存储
// ImageIO.write(tempPNG, "png", new File(dest));
// 压缩后输出
compress(tempPNG, dest);
}
/**
* 方式1:根据文件方式操作
*
* @param byteArrayDoc 原文件字节数组
* @return byte[] 生成图片字节数组
*/
public static byte[] resize(byte[] byteArrayDoc) throws IOException {
// 字节数组转为图片对象
Image img = ImageIO.read(new ByteArrayInputStream(byteArrayDoc));
BufferedImage tempPNG = resizeImage(img);
// 裁剪不压缩,存储
// ImageIO.write(tempPNG, "png", new File(dest));
// 压缩后输出
return compress(tempPNG);
}
/**
* 压缩图片逻辑(操作字节数组)
*
* @param image BufferedImage对象
* @return 返回字节数组
*/
private static byte[] compress(BufferedImage image) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
MemoryCacheImageOutputStream imageOutput = new MemoryCacheImageOutputStream(output);
// 必须写此参数
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = writers.next();
// 建立输出通道
writer.setOutput(imageOutput);
// 设置压缩参数
ImageWriteParam param = writer.getDefaultWriteParam();
// 必须写此参数
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(IMAGE_QUALITY_LEVEL);
// 写入流数据
writer.write(null, new IIOImage(image, null, null), param);
if(output != null){
output.close();
}
if(imageOutput != null){
imageOutput.close();
}
if(writer != null){
writer.dispose();
}
return output.toByteArray();
}
/**
* 压缩图片逻辑(操作文件)
*
* @param image BufferedImage对象
* @param dest 生成图片保存地址
*/
private static void compress(BufferedImage image, String dest) throws IOException {
OutputStream output = new FileOutputStream(new File(dest));
ImageOutputStream imageOutput = ImageIO.createImageOutputStream(output);
// 必须写此参数
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = writers.next();
// 建立输出通道
writer.setOutput(imageOutput);
// 设置压缩参数
ImageWriteParam param = writer.getDefaultWriteParam();
// 必须写此参数
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(IMAGE_QUALITY_LEVEL);
// 写入流数据
writer.write(null, new IIOImage(image, null, null), param);
if(output != null){
output.close();
}
if(imageOutput != null){
imageOutput.close();
}
if(writer != null){
writer.dispose();
}
}
/**
* 设置生成图片大小
* @param image
* @return java.awt.image.BufferedImage
*/
private static BufferedImage resizeImage(Image image) {
// 可设置生成图片大小,这里与原图一样
int width = ((BufferedImage) image).getWidth();
int height = ((BufferedImage) image).getHeight();
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建graph2D,用来将image写入bufferedImage
Graphics2D graphics2D = bufferedImage.createGraphics();
graphics2D.setComposite(AlphaComposite.Src);
// below three lines are for RenderingHints for better image quality at cost of higher processing time
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.drawImage(image, 0, 0, width, height, null);
graphics2D.dispose();
return bufferedImage;
}
}
DownImage
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* @description: 从网络下载图片
*/
public class DownImage {
private static Logger log = LoggerFactory.getLogger(DownImage.class);
private final static String OSS_URL = "fop-hotcamp-resource.rjfittime.com";
private final static String OSS_URL_INTERNAL = "fop-hotcamp-resource.oss-cn-beijing-internal.aliyuncs.com";
/**
* 从网络下载图片到本地
* @param imageUrl : 网络图片URL
*/
public void saveToFile(String imageUrl) {
FileOutputStream fos = null;
BufferedInputStream bis = null;
HttpURLConnection httpUrl = null;
URL url;
int bufferSize = 1024;
byte[] buf = new byte[bufferSize];
int size;
try {
url = new URL(imageUrl);
httpUrl = (HttpURLConnection) url.openConnection();
httpUrl.connect();
bis = new BufferedInputStream(httpUrl.getInputStream());
fos = new FileOutputStream("/Users/guiping.liang/1.png");
while ((size = bis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
fos.flush();
} catch (IOException | ClassCastException ignored) {
} finally {
try {
assert fos != null;
fos.close();
bis.close();
httpUrl.disconnect();
} catch (IOException | NullPointerException ignored) {
}
}
}
/**
* 网络图片url 转 BufferedImage 对象
* @param imageUrl :网络图片URL
* @param applyId :报名记录号
* @return :BufferedImage
*/
public static BufferedImage getBufferedImageByUrl(String imageUrl, long applyId) {
String pic = getOssUrlInternal(imageUrl);
log.info("[从客户端传过来的饼图片RUL] {}, {}, {}", imageUrl, applyId, pic);
BufferedInputStream bis = null;
URL url;
HttpURLConnection httpUrl = null;
try {
url = new URL(pic);
httpUrl = (HttpURLConnection) url.openConnection();
httpUrl.connect();
bis = new BufferedInputStream(httpUrl.getInputStream());
return ImageIO.read(bis);
} catch (Exception e) {
log.error("[网络图片url 转 BufferedImage 对象出错] {}, {}", e, applyId);
return null;
} finally {
try {
if (bis != null) {
bis.close();
}
if (httpUrl != null) {
httpUrl.disconnect();
}
} catch (Exception ex) {
log.error("[关闭对象出错] {}, {}", ex, applyId);
}
}
}
/**
* 网络图片url 转 BufferedImage 对象走内网地址
* @param imageUrl :网络图片URL
* @param applyId :报名记录号
* @return :BufferedImage
*/
private static BufferedImage getBufferedImageByUrlAgain(String imageUrl, long applyId) {
log.info("[走内网地址] {}, {}", imageUrl, applyId);
if (imageUrl.contains(OSS_URL)) {
imageUrl = imageUrl.replace(OSS_URL, OSS_URL_INTERNAL);
}
BufferedInputStream bis = null;
URL url;
HttpURLConnection httpUrl = null;
try {
url = new URL(imageUrl);
httpUrl = (HttpURLConnection) url.openConnection();
httpUrl.connect();
bis = new BufferedInputStream(httpUrl.getInputStream());
return ImageIO.read(bis);
} catch (Exception e) {
log.error("[getBufferedImageByUrlAgain.error] {}, {}", applyId, e);
} finally {
try {
if (bis != null) {
bis.close();
}
if (httpUrl != null) {
httpUrl.disconnect();
}
} catch (Exception ex) {
log.error("[getBufferedImageByUrlAgain.source.error] {}, {}", applyId, ex);
}
}
return null;
}
public static String getOssUrlInternal(String imageUrl) {
if (imageUrl.contains(OSS_URL)) {
imageUrl = imageUrl.replace(OSS_URL, OSS_URL_INTERNAL);
}
return imageUrl;
}
public static void main(String[] args) {
String a = "https://fop-hotcamp-resource.rjfittime.com/158755074291609685229851377883";
// BufferedImage pieChart = getBufferedImageByUrlAgain(a, 66078);
// assert pieChart != null;
// System.out.println(pieChart.getWidth());
// System.out.println(pieChart.getHeight());
System.out.println(getOssUrlInternal(a));
}
}
对象拷贝相关
CopyUtils
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.util.HashSet;
import java.util.Set;
/**
* @description 重写BeanUtils.copyProperties方法
*/
public class CopyUtils {
/**
*
* 功能描述: BeanUtils.copyProperties默认没有提供设置忽略null属性
*
* @param source
* @return java.lang.String[]
*/
private static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) {
emptyNames.add(pd.getName());
}
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
/**
*
* 功能描述: 工具入口
*
* @param src
* @param target
* @return void
*/
public static void copyProperties(Object src, Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}
}
表情相关
EmojiUtil
import org.apache.commons.lang3.StringUtils;
/**
* 表情符号工具类定义
*/
public class EmojiUtil {
private static boolean isEmojiCharacter(char codePoint) {
return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
|| (codePoint == 0xD)
|| ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
|| ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
|| ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
}
/**
* 过滤emoji 或者 其他非文字类型的字符
*
* @param source
* @return
*/
public static String filterEmoji(String source) {
if (StringUtils.isBlank(source)) {
return source;
}
StringBuilder buf = null;
int len = source.length();
for (int i = 0; i < len; i++) {
char codePoint = source.charAt(i);
if (isEmojiCharacter(codePoint)) {
if (buf == null) {
buf = new StringBuilder(source.length());
}
buf.append(codePoint);
}
}
if (buf == null) {
return source;
} else {
if (buf.length() == len) {
buf = null;
return source;
} else {
return buf.toString();
}
}
}
}
Excel相关
ExcelUtil
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
public class ExcelUtil {
private static Logger log = LoggerFactory.getLogger(ExcelUtil.class);
public static final String EXCEL_2003_SUFFIX = ".xls";
public static final String EXCEL_2007_SUFFIX = ".xlsx";
public static Workbook createWorkBookUsingAnnotation(String fileName, String sheetName, List<?> excelBeanList) {
long startTime = System.currentTimeMillis();
log.info("导出订单createWorkBookUsingAnnotation start" + startTime + "ms");
Workbook workbook = null;
if (fileName.toLowerCase().endsWith(EXCEL_2003_SUFFIX)) {
workbook = new HSSFWorkbook();
}
if (fileName.toLowerCase().endsWith(EXCEL_2007_SUFFIX)) {
workbook = new XSSFWorkbook();
}
// 创建sheet对象
Sheet sheet = workbook.createSheet(sheetName);
Row headRow = sheet.createRow(0);
// 设置样式
// 行首各个列的样式
CellStyle topStyle = workbook.createCellStyle();
topStyle.setAlignment(CellStyle.ALIGN_CENTER);
// 设置字体
Font font = workbook.createFont();
// 设置字体大小
font.setFontHeightInPoints((short) 11);
// 字体加粗
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
// 设置字体名字
font.setFontName("黑体");
topStyle.setFont(font);
// 列内容样式
CellStyle style = workbook.createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER);
List<Field> columnNameList = new ArrayList<>();
if (excelBeanList != null && excelBeanList.size() != 0) {
Field[] declaredFields = excelBeanList.get(0).getClass().getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
ExcelColumn column = field.getAnnotation(ExcelColumn.class);
if (column != null) {
columnNameList.add(field);
Cell cell = headRow.createCell(column.odinal());
try {
cell.setCellStyle(topStyle);
// 设置excel表格首行中各个列名
cell.setCellValue(column.columnName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Collections.sort(columnNameList, (a, b) -> {
return a.getAnnotation(ExcelColumn.class).odinal() - b.getAnnotation(ExcelColumn.class).odinal();
});
Map<Field, Method> getMethodMap = new HashMap<>();
CreationHelper createHelper = workbook.getCreationHelper();
CellStyle hlinkStyle = workbook.createCellStyle();
Font hlinkFont = workbook.createFont();
hlinkFont.setUnderline(Font.U_SINGLE);
hlinkFont.setColor(IndexedColors.BLUE.getIndex());
hlinkStyle.setFont(hlinkFont);
Row row = null;
Method getMethod = null;
String getMethodName = null;
Object fieldVal = null;
Cell cell = null;
Hyperlink link = null;
for (int i = 0; i < excelBeanList.size(); i++) {
row = sheet.createRow(i + 1);
for (Field field : columnNameList) {
try {
getMethod = getMethodMap.get(field);
if (getMethod == null) {
getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
getMethod = excelBeanList.get(i).getClass().getMethod(getMethodName);
getMethod.setAccessible(true);
getMethodMap.put(field, getMethod);
}
fieldVal = getMethod.invoke(excelBeanList.get(i));
cell = row.createCell(field.getAnnotation(ExcelColumn.class).odinal());
if (fieldVal != null) {
//如果cell内容是链接,则生成超链接样式
if (fieldVal.toString().startsWith("http")) {
link = createHelper.createHyperlink(Hyperlink.LINK_URL);
link.setAddress(fieldVal.toString());
cell.setHyperlink(link);
cell.setCellStyle(hlinkStyle);
} else {
cell.setCellStyle(style);
}
cell.setCellValue(fieldVal.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 让列宽随着导出的列长自动适应
processColumnWidth(sheet, columnNameList.size());
System.err.println("导出订单createWorkBookUsingAnnotation total cost:" + (System.currentTimeMillis() - startTime) + "ms");
}
return workbook;
}
/**
* 根据输入的值获取合法的值(非空,浮点到string)
*
* @param value 输入的值对象
* @return
*/
public static String getLegalValue(Object value) {
if (null == value) {
return "";
}
return String.valueOf(value);
}
public static void processColumnWidth(Sheet sheet, int columns) {
int columnWidth = 0;
Row currentRow = null;
Cell currentCell = null;
int length = 0;
for (int colNum = 0; colNum < columns; colNum++) {
columnWidth = sheet.getColumnWidth(colNum) / 256;
for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
// 当前行未被使用过
if (sheet.getRow(rowNum) == null) {
currentRow = sheet.createRow(rowNum);
} else {
currentRow = sheet.getRow(rowNum);
}
if (currentRow.getCell(colNum) != null) {
currentCell = currentRow.getCell(colNum);
if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
length = currentCell.getStringCellValue().length();
if (columnWidth < length) {
columnWidth = length;
}
}
}
}
if (colNum == 0) {
sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
} else {
if (columnWidth > 250) {
columnWidth = 250;
}
sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);
}
}
}
/**
* 解决不同浏览器下载文件时,中文文件名乱码问题
*
* @param request
* @param fileNames
* @return
*/
public static String processFileName(HttpServletRequest request, String fileNames) {
String codedfilename = null;
try {
String agent = request.getHeader("User-Agent");
if (agent != null) {
// ie edge
if (agent.indexOf("MSIE") != -1 || agent.indexOf("Trident") != -1 || agent.indexOf("Edge") != -1) {
codedfilename = java.net.URLEncoder.encode(fileNames, "UTF8");
} else if (agent.indexOf("Firefox") != -1 || agent.indexOf("Chrome") != -1 || agent.indexOf("Safari") != -1) {
// 火狐,chrome等
codedfilename = new String(fileNames.getBytes("UTF-8"), "iso-8859-1");
} else {
codedfilename = fileNames;
}
}
} catch (Exception e) {
log.error("processFileName error.", e);
}
return codedfilename;
}
public static void main(String[] args) {
}
}
随机数
RandomUtils
/**
* @ClassName: RandomUtil
* @Description: 随机数工具类
* qinfen
* (分别使用java.util.Random、Apache Common Math3、Apache Common Lang3、TreadLocalRandom)
*/
public class RandomUtil {
/**
* 随机数生成无边界的Int
*/
public static int getRandomForIntegerUnbounded() {
int intUnbounded = new Random().nextInt();
System.out.println(intUnbounded);
return intUnbounded;
}
/**
* 生成有边界的Int
*/
public static int getRandomForIntegerBounded(int min, int max) {
int intBounded = min + ((int) (new Random().nextFloat() * (max - min)));
System.out.println(intBounded);
return intBounded;
}
/**
* 使用Apache Common Math3来生成有边界的Int,包含1而不包含10
* @param min
* @param max
* @return
*/
public static int getRandomForIntegerBounded2(int min, int max) {
int intBounded = new RandomDataGenerator().nextInt(min, max);
System.out.println(intBounded);
return intBounded;
}
/**
* 用Apache Common Lang3的工具类来生成有边界的Int,包含1且包含10
* @param min
* @param max
* @return
*/
public static int getRandomForIntegerBounded3(int min, int max) {
int intBounded = RandomUtils.nextInt(min, max);
System.out.println(intBounded);
return intBounded;
}
/**
* 使用TreadLocalRandom来生成有边界的Int,包含min而不包含max
* @param min
* @param max
* @return
*/
public static int getRandomForIntegerBounded4(int min, int max) {
int threadIntBound = ThreadLocalRandom.current().nextInt(min, max);
System.out.println(threadIntBound);
return threadIntBound;
}
/**
* 随机数生成无边界的Long
*/
public static long getRandomForLongUnbounded() {
long unboundedLong = new Random().nextLong();
System.out.println(unboundedLong);
return unboundedLong;
}
/**
* 使用Random生成有边界的Long
* 因为Random类使用的种子是48bits,所以nextLong不能返回所有可能的long值,long是64bits
* @param min
* @param max
* @return
*/
public static long getRandomForLongBounded(long min, long max) {
long rangeLong = min + (((long) (new Random().nextDouble() * (max - min))));
System.out.println(rangeLong);
return rangeLong;
}
/**
* 使用Apache Commons Math3来生成有边界的Long(RandomDataGenerator类提供的生成随机数的方法)
* @param min
* @param max
* @return
*/
public static long getRandomForLongBounded2(long min, long max) {
long rangeLong = new RandomDataGenerator().nextLong(min, max);
System.out.println(rangeLong);
return rangeLong;
}
/**
* 使用Apache Commons Lang3的工具类来生成有边界的Long(RandomUtils提供了对java.util.Random的补充)
* @param min
* @param max
* @return
*/
public static long getRandomForLongBounded3(long min, long max) {
long longBounded = RandomUtils.nextLong(min, max);
System.out.println(longBounded);
return longBounded;
}
/**
* 使用ThreadLocalRandom生成有边界的Long
* @param min
* @param max
* @return
*/
public static long getRandomForLongBounded4(long min, long max) {
long threadLongBound = ThreadLocalRandom.current().nextLong(min, max);
System.out.println(threadLongBound);
return threadLongBound;
}
/**
* 随机数Float的生成生成0.0-1.0之间的Float随机数
*/
public static float getRandomForFloat0To1() {
float floatUnbounded = new Random().nextFloat();
System.out.println(floatUnbounded);
return floatUnbounded;
}
/**
* 以上只会生成包含0.0而不包括1.0的float类型随机数生成有边界的Float随机数
* @param min
* @param max
* @return
*/
public static float getRandomForFloatBounded(float min, float max) {
float floatBounded = min + new Random().nextFloat() * (max - min);
System.out.println(floatBounded);
return floatBounded;
}
/**
* 使用Apache Common Math来生成有边界的Float随机数
* @param min
* @param max
* @return
*/
public static float getRandomForFloatBounded2(float min, float max) {
float randomFloat = new RandomDataGenerator().getRandomGenerator().nextFloat();
float generatedFloat = min + randomFloat * (max - min);
System.out.println(generatedFloat);
return generatedFloat;
}
/**
* 使用Apache Common Lang来生成有边界的Float随机数
* @param min
* @param max
* @return
*/
public static float getRandomForFloatBounded3(float min, float max) {
float generatedFloat = RandomUtils.nextFloat(min, max);
System.out.println(generatedFloat);
return generatedFloat;
}
// 使用ThreadLocalRandom生成有边界的Float随机数
// ThreadLocalRandom类没有提供
/**
* 生成0.0d-1.0d之间的Double随机数
*/
public static double getRandomForDouble0To1() {
double generatorDouble = new Random().nextDouble();
System.out.println(generatorDouble);
return generatorDouble;
}
/**
* 与Float相同,以上方法只会生成包含0.0d而不包含1.0d的随机数生成带有边界的Double随机数
* @param min
* @param max
* @return
*/
public static double getRandomForDoubleBounded(double min, double max) {
double boundedDouble = min + new Random().nextDouble() * (max - min);
System.out.println(boundedDouble);
return boundedDouble;
}
/**
* 使用Apache Common Math来生成有边界的Double随机数
* @param min
* @param max
* @return
*/
public static double getRandomForDoubleBounded2(double min, double max) {
double boundedDouble = new RandomDataGenerator().getRandomGenerator().nextDouble();
double generatorDouble = min + boundedDouble * (max - min);
System.out.println(generatorDouble);
return generatorDouble;
}
/**
* 使用Apache Common Lang生成有边界的Double随机数
* @param min
* @param max
* @return
*/
public static double getRandomForDoubleBounded3(double min, double max) {
double generatedDouble = RandomUtils.nextDouble(min, max);
System.out.println(generatedDouble);
return generatedDouble;
}
/**
* 使用ThreadLocalRandom生成有边界的Double随机数
* @param min
* @param max
* @return
*/
public static double getRandomForDoubleBounded4(double min, double max) {
double generatedDouble = ThreadLocalRandom.current().nextDouble(min, max);
System.out.println(generatedDouble);
return generatedDouble;
}
}