Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.lx.boot.OS Maven / Gradle / Ivy
package com.lx.boot;//说明:
/**
* 创建人:游林夕/2019/4/28 09 04
*/
import com.lx.annotation.Note;
import com.lx.boot.web.AuthUtil;
import com.lx.entity.CustomDbInfo;
import com.lx.entity.ExpireCache;
import com.lx.entity.UserInfo;
import com.lx.entity.Var;
import com.lx.util.LX;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.util.StreamUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.lx.constant.DefaultBaseConstant.*;
import static com.lx.constant.DefaultRedisConstant.RedisPrefix.NUMBER_OF_LIMIT;
@Slf4j
@Configuration
public class OS implements BeanPostProcessor, ApplicationContextAware, EnvironmentAware {
private static final ThreadLocal> tl = new ThreadLocal() {
@Override
protected Map initialValue() {
return new HashMap(4);
}
};
private static Environment environment;
private static ApplicationContext applicationContext;
private static StringRedisTemplate stringRedisTemplate;
@Note("缓存系统配置,提高效率")
private static ExpireCache expireCache = new ExpireCache();
@Note("获取当前线程ThreadLocal里存储的数据")
public static T get(String key){
return (T) tl.get().get(key);
}
@Note("当前线程ThreadLocal进行存储数据")
public static void put(String key,Object obj){
tl.get().put(key,obj);
}
@Note("删除当前线程ThreadLocal里存储的数据")
public static void del(String key){
tl.get().remove(key);
}
@Note("清理当前线程ThreadLocal里存储的所有数据")
public static void remove(){
tl.remove();
}
@Note("设置用户信息")
public static void setUserInfo(UserInfo userInfo){
put(USER_INFO, userInfo);
}
@Note("获取用户信息")
public static UserInfo getUserInfo(){
return LX.ifNull(get(USER_INFO), new UserInfo());
}
@Note("获取用户信息")
public static UserInfo getRealUserInfo(){
return get(USER_INFO);
}
@Note("获取用户信息, T为UserInfo的子类")
public static T getUserInfo(Class t){
return OS.getBean(AuthUtil.class).getUserInfo(t,getRequest());
}
@Note("获取用户ID")
public static String getUserId(){
return getUserInfo().getUserId();
}
@Note("获取用户类型")
public static String getUserType(){
return getUserInfo().getUserType();
}
@Note("设置自定义数据源链接")
public static void setCustomDbInfo(CustomDbInfo customDbInfo){
put(CUSTOM_DB_INFO, customDbInfo);
}
@Note("获取自定义数据源信息")
public static CustomDbInfo getCustomDbInfo(){
return get(CUSTOM_DB_INFO);
}
@Note("删除自定义数据源信息")
public static void delCustomDbInfo(){
del(CUSTOM_DB_INFO);
}
@Note("通过name获取 Bean对象")
public static T getBean(String name){
return (T)applicationContext.getBean(name);
}
@Note("通过Class类型获取 Bean对象")
public static T getBean(Class t){
return applicationContext.getBean(t);
}
@Note("设置公司ID")
public static void setFirmId(String firmId){
put(FIRM_ID, firmId);
}
@Note("获取公司ID")
public static String getFirmId(){
return get(FIRM_ID);
}
@Note("设置第三方接口appid")
public static void setAppId(String appId){
put(API_APPID, appId);
}
@Note("获取第三方接口appid")
public static String getAppId(){
return get(API_APPID);
}
@Note("获取配置文件中配置, 优先获取firmid.key 没有获取 key对应的配置信息")
public static String getProperty(String key){
if (environment == null){
return null;
}
// 直接获取比较慢
return expireCache.get(key, ()->{
return LX.ifNull(environment.getProperty(OS.getFirmId()+"."+key),()->{return environment.getProperty(key);});
});
}
@Note("获取配置文件中配置, 为null时取默认值")
public static String getProperty(String key, String defaultValue){
return LX.ifNull(getProperty(key) ,defaultValue);
}
@Note("获取配置文件中配置,转成int类型")
public static int getIntProperty(String key, String defaultValue){
return Integer.parseInt(getProperty(key, defaultValue));
}
@Note("获取配置文件中配置是否是1")
public static boolean getPropertyEquals1(String key, String defaultValue){
return "1".equals(getProperty(key,defaultValue));
}
@Note("获取配置文件中配置是否是true")
public static boolean getPropertyIsTrue(String key, String defaultValue){
return "true".equals(getProperty(key,defaultValue));
}
@Note("动态修改系统配置")
public static void setProperty(Map map){
addProperty("os.defaultProperty",map);
}
@Note("通过程序新增配置 name:配置信息标识, map:配置信息; 注意name名称相同时配置信息会被覆盖")
public static void addProperty(String name , Map map){
if (environment == null){
environment = new StandardEnvironment();
}
ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;
MapPropertySource propertySource = new MapPropertySource(name,map);
configurableEnvironment.getPropertySources().addFirst(propertySource);
}
@Note("获取当前服务名")
public static String getApplicationName(){
return getProperty("spring.application.name","");
}
@Note("获取当前环境, 配置信息中的spring.profiles.active")
public static String getEnv(){
return getProperty("spring.profiles.active");
}
@Note("判断当前环境是否为dev环境")
public static boolean isDev(){
return "dev".equals(getProperty("spring.profiles.active"));
}
@Note("判断当前环境是否为prod环境")
public static boolean isProd(){
return "prod".equals(getProperty("spring.profiles.active"));
}
@Note("设置日志追踪ID")
public static void setLogTraceId(){
setLogTraceId(LX.uuid32(10));
}
@Note("设置日志追踪ID")
public static void setLogTraceId(String requestId){
MDC.put("requestId", requestId);
}
@Note("获取日志追踪ID")
public static String getLogTraceId(){
return MDC.get("requestId");
}
@Note("设置指定包下的日志等级")
public static void setLogLevel(String packageName , LogLevel logLevel){
getBean(LoggingSystem.class).setLogLevel(packageName, logLevel);
}
@Note("获取当前线程的HttpServletRequest")
public static HttpServletRequest getRequest(){
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
@Note("获取请求头里的参数")
public static String getHeader(String key) {
return getRequest().getHeader(key);
}
private static final List POST_METHOD = Arrays.asList("POST","PUT");
@Note("获取Request的参数")
public static Var getParamter() throws IOException {
HttpServletRequest request = getRequest();
if (POST_METHOD.contains(request.getMethod().toUpperCase())) {
return LX.toMap(StreamUtils.copyToString(request.getInputStream(), Charset.forName("UTF-8")));
}else{
Var res = new Var();
request.getParameterMap().forEach((k,v)->{
res.put(k, v[0]);
});
return res;
}
}
@Note("单位时间内指定key调用次数; key:限制标识, callFrequency:次数/时间 [1-9]\\d{0,5}/([M,d]|([1-9]\\d{0,3}[H,m,s]))")
public static boolean allowAccessByCallFrequency(String key, String callFrequency) {
//次数/ 时间
if (!callFrequency.matches("[1-9]\\d{0,5}/([M,d]|([1-9]\\d{0,3}[H,m,s]))")){
LX.exMsg("接口限制次数配置有误!=> [1-9]\\d{0,5}/([M,d]|([1-9]\\d{0,3}[H,m,s]))");
}
String [] arr = callFrequency.split("/");
switch (callFrequency.charAt(callFrequency.length()-1)){
case 'M':
return allowAccessTo(LX.getDate("yyyy-MM")+":"+key,arr[0], TimeUnit.DAYS.toSeconds(31)+"");
case 'd':
return allowAccessTo(LX.getDate("yyyy-MM-dd")+":"+key,arr[0], TimeUnit.DAYS.toSeconds(1)+"");
case 'H':
return allowAccessTo(key,arr[0],TimeUnit.HOURS.toSeconds(Integer.parseInt(arr[1].substring(0,arr[1].length()-1)))+"");
case 'm':
return allowAccessTo(key,arr[0],TimeUnit.MINUTES.toSeconds(Integer.parseInt(arr[1].substring(0,arr[1].length()-1)))+"");
case 's':
return allowAccessTo(key,arr[0],arr[1].substring(0,arr[1].length()-1)+"");
default:
return false;
}
}
@Note("单位时间内指定key调用次数,limit:次数 , time:秒")
public static boolean allowAccessTo(String key , String limit, String time){
String lua = "local limit = tonumber(ARGV[1]);local time = tonumber(ARGV[2]);local ttl = redis.call(\"ttl\",KEYS[1]);local incr = redis.call(\"incr\",KEYS[1]);if (ttl > 0) then if incr > limit then return ttl;end;else redis.call(\"expire\",KEYS[1],ARGV[2]);end;return 0;";
key = NUMBER_OF_LIMIT +key;
DefaultRedisScript redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(lua);
redisScript.setResultType(Long.class);
return stringRedisTemplate.execute(redisScript, Arrays.asList(key),limit,time) == 0;
}
@Note("清除已记录单位时间内的key")
public static void allowAccessKeyClear(String key){
stringRedisTemplate.delete(NUMBER_OF_LIMIT +key);
}
@Note("判断当前ip是否匹配白名单")
public static boolean allowAccessByIp(String ipWhiteList){
String ip = OS.getIp(getRequest());
return !(LX.isEmpty(ip) || LX.isEmpty(ipWhiteList) || !ip.matches(ipWhiteList));
}
@Note("获取当前调用者IP")
public static String getIp() {
return getIp(getRequest());
}
@Note("获取Request的IP")
public static String getIp(HttpServletRequest request) {
String ip = request.getHeader("x-real-ip");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("x-forwarded-for");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if ("0:0:0:0:0:0:0:1".equals(ip)){
return "127.0.0.1";
}
return ip;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
OS.applicationContext = applicationContext;
stringRedisTemplate = getBean(StringRedisTemplate.class);
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setEnvironment(Environment environment) {
OS.environment = environment;
}
public static Environment getEnvironment() {
return environment;
}
}