百味皆苦 java后端开发攻城狮

ft工具类

2020-08-28
百味皆苦

配置文件读取

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;
    }
}

Comments

Content