init:删除无用配置

This commit is contained in:
zhangzq
2025-06-25 09:33:37 +08:00
parent 303b7a08c9
commit 30cc7f94fb
89 changed files with 1429 additions and 3012 deletions

View File

@@ -1,45 +0,0 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nl.config;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
import java.util.Optional;
/**
* @description : 设置审计
* @author : Dong ZhaoYang
* @date : 2019/10/28
*/
@Component("auditorAware")
public class AuditorConfig implements AuditorAware<String> {
/**
* 返回操作员标志信息
*
* @return /
*/
@Override
public Optional<String> getCurrentAuditor() {
try {
// 这里应根据实际业务情况获取具体信息
return Optional.of(null);
}catch (Exception ignored){}
// 用户定时任务或者无Token调用的情况
return Optional.of("System");
}
}

View File

@@ -1,44 +0,0 @@
package org.nl.config;/*
package org.nl.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
*/
/**
* 处理前端和后端Long类型失去精度问题.
* https://blog.51cto.com/u_15127549/3519757
*//*
@Configuration
@EnableWebMvc
public class CustomJsonConfiguration implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
*/
/**
* 序列换成json时,将所有的long变成string
* 因为js中得数字类型不能包含所有的java long值
*//*
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
converters.add(jackson2HttpMessageConverter);
}
}
*/

View File

@@ -1,23 +0,0 @@
//package org.nl.config;
//
//import com.alibaba.druid.pool.DruidDataSource;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.boot.context.properties.ConfigurationProperties;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//
//import javax.sql.DataSource;
//
//@Configuration
//@Slf4j
//public class DataBaseConfig {
//
// @Primary
// @Bean(name = "dataSource")
// @ConfigurationProperties(prefix = "spring.datasource.druid")
// public DataSource dataSource() {
// return new DruidDataSource();
// }
//
//}

View File

@@ -1,9 +0,0 @@
package org.nl.config;
/**
* @Author: lyd
* @Description: 测试
* @Date: 2024/5/28
*/
public class Test {
}

View File

@@ -1,42 +0,0 @@
package org.nl.config.jackson;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.ser.std.NumberSerializer;
import java.io.IOException;
/**
* 超出 JS 最大最小值 处理
*
* @author Lion Li
*/
@JacksonStdImpl
public class BigNumberSerializer extends NumberSerializer {
/**
* 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来
*/
private static final long MAX_SAFE_INTEGER = 9007199254740991L;
private static final long MIN_SAFE_INTEGER = -9007199254740991L;
/**
* 提供实例
*/
public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);
public BigNumberSerializer(Class<? extends Number> rawType) {
super(rawType);
}
@Override
public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException {
// 超出范围 序列化位字符串
if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
super.serialize(value, gen, provider);
} else {
gen.writeString(value.toString());
}
}
}

View File

@@ -1,70 +0,0 @@
package org.nl.config.jackson;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
* <p>
* 对象映射器:基于jackson将Java对象转为json或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
* </p>
*
* @author generator
* @since 2023-11-16
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
//将BigInteger型数字转换成字符串,避免丢失精度
.addSerializer(BigInteger.class, ToStringSerializer.instance)
//将Long型数字转换成字符串,避免丢失精度
.addSerializer(Long.class, ToStringSerializer.instance)
//将Integer型数字转换成字符串
.addSerializer(Integer.class, ToStringSerializer.instance)
//将int型数字转换成字符串
.addSerializer(int.class, ToStringSerializer.instance)
//将long型数字转换成字符串
.addSerializer(long.class, ToStringSerializer.instance)
//序列化和反序列化日期格式
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}

View File

@@ -0,0 +1,32 @@
package org.nl.config.lucene;
/**
* @author ldjun
* @version 1.0
* @date 2023年08月24日 13:00
* @desc desc
*/
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.yomahub.tlog.core.enhance.logback.async.AspectLogbackAsyncAppender;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import java.util.Map;
public class AsyncLuceneAppender extends AspectLogbackAsyncAppender {
@Override
protected void append(ILoggingEvent event) {
String traceId = LuceneAppender.traceIdTL.get();
if (StringUtils.isNotEmpty(traceId)){
MDC.put("traceId",traceId);
Map<String, String> mdcPropertyMap = event.getMDCPropertyMap();
if (mdcPropertyMap.getClass().getName().contains("SynchronizedMap")){
mdcPropertyMap.put("traceId",traceId);
}
MDC.clear();
}
}
}

View File

@@ -1,58 +0,0 @@
package org.nl.config.lucene;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.nio.charset.Charset;
/**
* <p>
* 日志
* </p>
*
* @author generator
* @since 2023-11-16
*/
public class DynamicLogAppender {
/**
* 通过传入的动态名字,动态设置appender
* @param dynamicName
* @return
*/
public RollingFileAppender getAppender(String oldLogPath,String dynamicName) {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
RollingFileAppender appender = new RollingFileAppender();
//appender的name属性
appender.setName(dynamicName);
appender.setContext(context);
//设置文件名
appender.setFile(new File(oldLogPath, dynamicName + "\\" + DateUtil.format(new DateTime(),"yyyy-MM-dd")+".log").getAbsolutePath());
//设置日志文件输出格式
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(context);
encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
encoder.setCharset(Charset.forName("UTF-8"));
encoder.start();
//设置日志记录器的滚动策略
TimeBasedRollingPolicy policy = new TimeBasedRollingPolicy();
policy.setFileNamePattern(oldLogPath+dynamicName+".%d{yyyy-MM-dd}.log");
//设置父节点是appender
policy.setParent(appender);
policy.setContext(context);
policy.start();
//加入下面两个节点
appender.setRollingPolicy(policy);
appender.setEncoder(encoder);
appender.start();
return appender;
}
}

View File

@@ -1,53 +0,0 @@
package org.nl.config.lucene;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.rolling.RollingFileAppender;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* <p>
* 日志储存
* </p>
*
* @author generator
* @since 2023-11-16
*/
public class DynamicLogger {
/**
* 日志存储路径
*/
String logPath;
public DynamicLogger(String logPath) {
this.logPath = logPath;
}
/**
* 对外暴露日志对象:每次拿的对象从内存里拿,没有再构建
*/
private static Map<String,Logger> container = new HashMap<>();
public Logger getLogger(String dynamicName) {
Logger logger = container.get(dynamicName);
if(logger != null) {
return logger;
}
logger = build(dynamicName);
container.put(dynamicName,logger);
return logger;
}
/**
* 构建Logger对象给Logger指定appender
* @param dynamicName /
* @return Logger
*/
private Logger build(String dynamicName) {
RollingFileAppender runTaskAppender =new DynamicLogAppender().getAppender(this.logPath,dynamicName);
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = context.getLogger(dynamicName);
logger.addAppender(runTaskAppender);
return logger;
}
}

View File

@@ -1,187 +0,0 @@
package org.nl.config.lucene;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.springframework.beans.factory.annotation.Value;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Set;
/**
* <p>
* lucene索引器
* </p>
*
* @author generator
* @since 2023-11-16
*/
public class Indexer {
/**
* 写索引实例
*/
private IndexWriter writer;
public IndexWriter getWriter() {
return writer;
}
/**
* 构造方法实例化IndexWriter
*
* @param indexDir
* @throws Exception
*/
public Indexer(String indexDir) throws Exception {
Directory dir = FSDirectory.open(Paths.get(indexDir));
//标准分词器会自动去掉空格啊is a the等单词
// Analyzer analyzer = new StandardAnalyzer();
Analyzer analyzer = new IKAnalyzer();
//将标准分词器配到写索引的配置中
IndexWriterConfig config = new IndexWriterConfig(analyzer);
//实例化写索引对象
writer = new IndexWriter(dir, config);
}
/**
* 索引指定目录下的所有文件
*
* @param dataDir
* @return
* @throws Exception
*/
public int indexAll(String dataDir) throws Exception {
// 获取该路径下的所有文件
File[] files = new File(dataDir).listFiles();
if (null != files) {
for (File file : files) {
//调用下面的indexFile方法对每个文件进行索引
indexFile(file);
}
}
//返回索引的文件数
return writer.numRamDocs();
}
/**
* 索引指定的文件
*
* @param file
* @throws Exception
*/
private void indexFile(File file) throws Exception {
System.out.println("索引文件的路径:" + file.getCanonicalPath());
//调用下面的getDocument方法获取该文件的document
Document doc = getDocument(file);
//添加索引文档
//Document doc = json2Doc(jsonDoc);
// Document doc = new Document();
Field fieldContent = new TextField("fieldContent", FileUtils.readFileToString(null, "UTF-8"), Field.Store.YES);
//将doc添加到索引中
writer.addDocument(doc);
}
/**
* 获取文档,文档里再设置每个字段,就类似于数据库中的一行记录
*
* @param file
* @return
* @throws Exception
*/
private Document getDocument(File file) throws Exception {
Document doc = new Document();
//开始添加字段
//添加内容
doc.add(new TextField("contents", new FileReader(file)));
//添加文件名,并把这个字段存到索引文件里
doc.add(new TextField("fileName", file.getName(), Field.Store.YES));
//添加文件路径
doc.add(new TextField("fullPath", file.getCanonicalPath(), Field.Store.YES));
return doc;
}
public Document json2Doc(String strDoc) {
Document doc = new Document();
JSONObject jsonDoc = JSONObject.parseObject(strDoc);
Set<String> keys = jsonDoc.keySet();
for (String key : keys) {
doc.add(new TextField(key, jsonDoc.getString(key), Field.Store.YES));
}
return doc;
}
public void addLogIndex(String msg) throws IOException {
//步骤一创建Directory对象用于指定索引库的位置 RAMDirectory内存
Directory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
//步骤二创建一个IndexWriter对象用于写索引
// Analyzer analyzer = new StandardAnalyzer();
IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(new IKAnalyzer(false)));
// indexWriter.deleteAll();//清理所有索引库
// IndexWriter indexWriter=new IndexWriter(directory,new IndexWriterConfig(new StandardAnalyzer()));
//记录索引开始时间
long startTime = System.currentTimeMillis();
//步骤三:读取磁盘中文件,对应每一个文件创建一个文档对象
Document document = new Document();
document.add(new TextField("fieldContent", msg, Field.Store.YES));
indexWriter.addDocument(document);
//记录索引结束时间
long endTime = System.currentTimeMillis();
System.out.println("建立索引" + "共耗时" + (endTime - startTime) + "毫秒");
indexWriter.commit();
//步骤八:关闭资源
indexWriter.close();
System.out.println("建立索引成功-----关闭资源");
}
/**
* 系统的日志文件路径
*/
@Value("${logging.file.path}")
private String logUrl;
public static void main(String[] args) throws IOException {
//步骤一创建Directory对象用于指定索引库的位置 RAMDirectory内存
Directory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
//步骤二创建一个IndexWriter对象用于写索引
// Analyzer analyzer = new StandardAnalyzer();
IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(new IKAnalyzer(false)));
indexWriter.deleteAll();//清理所有索引库
// indexWriter=new IndexWriter(directory,new IndexWriterConfig(new StandardAnalyzer()));
//记录索引开始时间
long startTime = System.currentTimeMillis();
//步骤三:读取磁盘中文件,对应每一个文件创建一个文档对象
File file = new File("D:\\testlog");
//步骤四:获取文件列表
File[] files = file.listFiles();
for (File item : files) {
BufferedReader bufferedReader = new BufferedReader(new FileReader(item));
String strLine = null;
while (null != (strLine = bufferedReader.readLine())) {
Document document = new Document();
document.add(new TextField("fieldContent", strLine, Field.Store.YES));
indexWriter.addDocument(document);
}
}
//记录索引结束时间
long endTime = System.currentTimeMillis();
System.out.println("建立索引" + "共耗时" + (endTime - startTime) + "毫秒");
indexWriter.commit();
//步骤八:关闭资源
indexWriter.close();
System.out.println("建立索引成功-----关闭资源");
}
}

View File

@@ -6,86 +6,41 @@ package org.nl.config.lucene;
* @Date: 2023/8/25
*/
public class LogMessageConstant {
/**
* 标签
*/
public final static String FIELD_LABEL = "label";
/**
* 时间
*/
public final static String FIELD_SORT_NAME = "time";
/**
* IP
*/
public final static String FIELD_IP = "ip";
/**
* 级别
*/
/** */
public final static String SORT_NAME = "time";
/** 级别 */
public final static String FIELD_LEVEL = "level";
/**
* 时间
*/
/** 时间 */
public final static String FIELD_TIMESTAMP = "timestamp";
/**
* 类的限定名
*/
/** 类的限定名 */
public final static String FIELD_CLASS_NAME = "logger";
/**
* 线程名
*/
/** 线程名 */
public final static String FIELD_THREAD = "thread";
/**
* 日志内容
*/
/** 日志内容 */
public final static String FIELD_MESSAGE = "message";
/**
* tlogTraceId
*/
public final static String FIELD_TRACEID = "tlogTraceId";
// 定义颜色值
/**
* 文本颜色:黑色
*/
/** 文本颜色:黑色 */
public final static String COLOR_BLACK = "\u001B[30m";
/**
* 文本颜色:红色
*/
/** 文本颜色:红色 */
public final static String COLOR_RED = "\u001B[31m";
/**
* 文本颜色:绿色
*/
/** 文本颜色:绿色 */
public final static String COLOR_GREEN = "\u001B[32m";
/**
* 文本颜色:黄色
*/
/** 文本颜色:黄色 */
public final static String COLOR_YELLOW = "\u001B[33m";
/**
* 文本颜色:蓝色
*/
/** 文本颜色:蓝色 */
public final static String COLOR_BLUE = "\u001B[34m";
/**
* 文本颜色:品红色
*/
/** 文本颜色:品红色 */
public final static String COLOR_MAGENTA = "\u001B[35m";
/**
* 文本颜色:青色
*/
/** 文本颜色:青色 */
public final static String COLOR_CYAN = "\u001B[36m";
/**
* 文本颜色:白色
*/
/** 文本颜色:白色 */
public final static String COLOR_WHITE = "\u001B[37m";
/**
* 文本颜色重置
*/
/** 文本颜色重置 */
public final static String COLOR_RESET = "\u001B[0m";
/**
* 背景颜色:黄色
*/
/** 背景颜色:黄色 */
public final static String BACKGROUND_YELLOW = "\u001B[43m";
/**
* 索引路径
*/
public final static String INDEX_DIR = "D:\\software\\lucene\\index";
/** 索引路径 */
public final static String INDEX_DIR = "E:\\lucene\\index";
}

View File

@@ -8,8 +8,8 @@ package org.nl.config.lucene;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.ttl.TransmittableThreadLocal;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexWriter;
@@ -20,20 +20,21 @@ import org.nl.common.utils.YmlConfigFileUtil;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LuceneAppender extends AppenderBase<ILoggingEvent> {
private Directory index;
public static final TransmittableThreadLocal<String> traceIdTL = new TransmittableThreadLocal();
public LuceneProperties properties;
public static Directory index;
private List<LucenePropertyAndEncoder> encoders;
public static IndexWriter indexWriter;
@Override
public void start() {
super.start();
@@ -43,17 +44,13 @@ public class LuceneAppender extends AppenderBase<ILoggingEvent> {
// 获取配置值
String luceneDir = properties.getProperty("lucene.index.path");
System.out.println("---index地址----"+luceneDir);
index = FSDirectory.open(Paths.get(luceneDir));
} catch (IOException e) {
e.printStackTrace();
}
// 初始化 Lucene 索引
Analyzer analyzer = new IKAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(analyzer);
try {
// 初始化 Lucene 索引
Analyzer analyzer = new IKAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(analyzer);
indexWriter = new IndexWriter(index, config);
} catch (IOException e) {
} catch (Exception e) {
e.printStackTrace();
}
}
@@ -61,53 +58,26 @@ public class LuceneAppender extends AppenderBase<ILoggingEvent> {
@Override
protected void append(ILoggingEvent event) {
String message = event.getFormattedMessage();
Map<String, String> mdcPropertyMap = event.getMDCPropertyMap();
Document doc = new Document();
long timeStamp = event.getTimeStamp();
// 获取本机的IP地址
String ipAddress = "-";
try {
ipAddress = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
for (Property property : this.properties.getProperties()) {
LucenePropertyAndEncoder encoder = new LucenePropertyAndEncoder(property, this.context);
String encode = encoder.encode(event);
doc.add(new StringField(property.getName(), encode, Field.Store.YES));
}
String formattedDateTime = DateUtil.format(new java.util.Date(timeStamp), "yyyy-MM-dd HH:mm:ss.SSS");
doc.add(new LongPoint(LogMessageConstant.FIELD_SORT_NAME, timeStamp));
doc.add(new NumericDocValuesField(LogMessageConstant.FIELD_SORT_NAME, timeStamp));
doc.add(new StringField(LogMessageConstant.FIELD_LEVEL, event.getLevel().toString(), Field.Store.YES));
doc.add(new StringField(LogMessageConstant.FIELD_TIMESTAMP, formattedDateTime, Field.Store.YES));
doc.add(new StoredField(LogMessageConstant.FIELD_CLASS_NAME, event.getLoggerName()));
doc.add(new StoredField(LogMessageConstant.FIELD_IP, ipAddress));
doc.add(new StoredField(LogMessageConstant.FIELD_THREAD, event.getThreadName()));
if (ObjectUtil.isNotEmpty(mdcPropertyMap) && ObjectUtil.isNotEmpty(mdcPropertyMap.get(LogMessageConstant.FIELD_TRACEID))) {
String traceId = mdcPropertyMap.get(LogMessageConstant.FIELD_TRACEID);
doc.add(new StringField(LogMessageConstant.FIELD_TRACEID, traceId, Field.Store.YES));
doc.add(new StringField(LogMessageConstant.FIELD_LABEL, ObjectUtil.isNotEmpty(mdcPropertyMap.get("tag_name"))
? mdcPropertyMap.get("tag_name") : "-", Field.Store.YES));
} else {
// 定义正则表达式匹配17位数字
String regex = "\\d{17}";
// 创建 Pattern 对象
Pattern pattern = Pattern.compile(regex);
// 创建 Matcher 对象
Matcher matcher = pattern.matcher(message);
String matchedNumber = null;
// 查找匹配的数字
while (matcher.find()) {
matchedNumber = matcher.group();
}
if (ObjectUtil.isNotEmpty(matchedNumber)) {
doc.add(new StringField(LogMessageConstant.FIELD_TRACEID, matchedNumber, Field.Store.YES));
} else {
doc.add(new StringField(LogMessageConstant.FIELD_TRACEID, "无生成链路ID", Field.Store.YES));
}
Map<String, String> map = event.getMDCPropertyMap();
if (!map.isEmpty() && StringUtils.isNotEmpty(map.get("traceId"))){
doc.add(new StringField("traceId",map.get("traceId"), Field.Store.YES));
}else {
doc.add(new StringField("traceId"," ", Field.Store.YES));
}
doc.add(new TextField(LogMessageConstant.FIELD_MESSAGE, message, Field.Store.YES));
doc.add(new TextField(LogMessageConstant.FIELD_MESSAGE, event.getFormattedMessage(), Field.Store.YES));
doc.add(new StringField(LogMessageConstant.FIELD_TIMESTAMP, String.valueOf(event.getTimeStamp()),Field.Store.YES));
doc.add(new NumericDocValuesField(LogMessageConstant.SORT_NAME, event.getTimeStamp()));
try {
indexWriter.addDocument(doc);
indexWriter.commit();
} catch (IOException e) {
} catch (Exception e) {
e.printStackTrace();
}
}
@@ -121,4 +91,9 @@ public class LuceneAppender extends AppenderBase<ILoggingEvent> {
e.printStackTrace();
}
}
public void setProperties(LuceneProperties properties) {
this.properties = properties;
}
}

View File

@@ -1,70 +0,0 @@
package org.nl.config.lucene;
import cn.hutool.core.date.DateUtil;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* <p>
* 、
* </p>
*
* @author generator
* @since 2023-11-16
*/
public class LuceneIndexWriter {
private static IndexWriter indexWriter;
static {
try {
Directory directory = FSDirectory.open(new File(UrlConfig.luceneUrl).toPath());
IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
indexWriter = new IndexWriter(directory, config);
} catch (Exception e) {
e.printStackTrace();
}
/**当当前线程结束时自动关闭IndexWriter使用Runtime对象*/
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
closeIndexWriter();
} catch (Exception e) {
e.printStackTrace();
}
}));
}
/**在线程结束时自动关闭IndexWriter*/
public static IndexWriter getIndexWriter() {
return indexWriter;
}
/**关闭IndexWriter
* @throws IOException
* @throws CorruptIndexException */
public static void closeIndexWriter() throws Exception {
if(indexWriter != null) {
indexWriter.close();
}
}
public static void main(String[] args) throws IOException {
indexWriter.deleteAll();
}
public static String getDate(String timeString) throws ParseException {
//时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date date = sdf.parse(timeString);
//格式化后的时间
timeString = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss.SSS");
return timeString;
}
}

View File

@@ -0,0 +1,23 @@
package org.nl.config.lucene;
import java.util.ArrayList;
import java.util.List;
public class LuceneProperties {
private List<Property> properties;
public LuceneProperties() {
this.properties = new ArrayList<Property>();
}
public List<Property> getProperties() {
return properties;
}
public void addProperty(Property property) {
properties.add(property);
}
}

View File

@@ -0,0 +1,38 @@
package org.nl.config.lucene;
import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.pattern.PatternLayoutBase;
/*
* @author ZZQ
* @Date 2023/12/22 18:11
*/
public class LucenePropertyAndEncoder {
private Property property;
private PatternLayoutBase layout = new PatternLayout();
public LucenePropertyAndEncoder(Property property, Context context) {
this.property = property;
this.layout.setContext(context);
this.layout.setPattern(String.valueOf(property.getValue()));
this.layout.setPostCompileProcessor(null);
this.layout.start();
}
public String encode(ILoggingEvent event) {
return layout.doLayout(event);
}
public String getName() {
return property.getName();
}
public boolean allowEmpty() {
return property.isAllowEmpty();
}
}

View File

@@ -0,0 +1,44 @@
package org.nl.config.lucene;
/*
* @author ZZQ
* @Date 2023/12/26 15:30
*/
public class Property {
private String name;
private String value;
private boolean allowEmpty;
public Property() {
}
public Property(String name, String value, boolean allowEmpty) {
this.name = name;
this.value = value;
this.allowEmpty = allowEmpty;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public boolean isAllowEmpty() {
return allowEmpty;
}
public void setAllowEmpty(boolean allowEmpty) {
this.allowEmpty = allowEmpty;
}
}

View File

@@ -1,163 +0,0 @@
package org.nl.config.lucene;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.BytesRef;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.io.IOException;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
/**
* lucene查询器
*/
@Slf4j
public class Searcher {
public static Map<String, Object> search(String indexDir, JSONObject whereJson) throws Exception {
//获取要查询的路径,也就是索引所在的位置
Directory dir = FSDirectory.open(Paths.get(indexDir));
IndexReader reader = DirectoryReader.open(dir);
//构建IndexSearcher
IndexSearcher searcher = new IndexSearcher(reader);
//标准分词器会自动去掉空格啊is a the等单词
Analyzer analyzer = new IKAnalyzer(true);
// 实际上Lucene本身不支持分页。因此我们需要自己进行逻辑分页。我们要准备分页参数
// 每页条数
int pageSize = Integer.parseInt(whereJson.get("size").toString());
// 当前页码
int pageNum = Integer.parseInt(whereJson.get("page").toString()) - 1;
// 当前页的起始条数
int start = pageNum * pageSize;
// 当前页的结束条数(不能包含)
int end = start + pageSize;
// 创建排序对象,需要排序字段SortField参数字段的名称、字段的类型、是否反转如果是false升序。true降序
Sort sort = new Sort(new SortField(LogMessageConstant.FIELD_SORT_NAME, SortField.Type.LONG, true));
TopDocs docs = null;
BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder();
Calendar calendar = Calendar.getInstance();
calendar.set(1970, 0, 1);
//时间范围查询
JSONArray createTime = whereJson.getJSONArray("createTime");
String startDate = DateUtil.format(calendar.getTime(), "yyyy-MM-dd HH:mm:ss.SSS");
String endDate = DateUtil.format(new DateTime(), "yyyy-MM-dd HH:mm:ss.SSS");
if (createTime != null) {
startDate = createTime.getString(0);
endDate = createTime.getString(1);
}
// 字段之间的与或非关系MUST表示andMUST_NOT表示notSHOULD表示or有几个fields就必须有几个clauses
TermRangeQuery termRangeQuery = new TermRangeQuery("timestamp", new BytesRef(startDate),
new BytesRef(endDate), true, true);
booleanQueryBuilder.add(termRangeQuery, BooleanClause.Occur.MUST);
if (ObjectUtil.isNotEmpty(whereJson.get(LogMessageConstant.FIELD_MESSAGE))) {
//查询解析器
QueryParser queryParser = new QueryParser("message", analyzer);
Query query = queryParser.parse("message:" + whereJson.getString("message") + "~");
booleanQueryBuilder.add(query, BooleanClause.Occur.MUST);
}
if (ObjectUtil.isNotEmpty(whereJson.get(LogMessageConstant.FIELD_TRACEID))) {
//查询解析器
TermQuery termQuery = new TermQuery(new Term(LogMessageConstant.FIELD_TRACEID,
whereJson.getString(LogMessageConstant.FIELD_TRACEID).trim()));
booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST);
}
if (ObjectUtil.isNotEmpty(whereJson.get(LogMessageConstant.FIELD_LABEL))) {
//查询解析器
TermQuery termQuery = new TermQuery(new Term(LogMessageConstant.FIELD_LABEL,
whereJson.getString(LogMessageConstant.FIELD_LABEL).trim()));
booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST);
}
if (ObjectUtil.isNotEmpty(whereJson.get(LogMessageConstant.FIELD_LEVEL))) {
//查询解析器
TermQuery termQuery = new TermQuery(new Term(LogMessageConstant.FIELD_LEVEL,
whereJson.get(LogMessageConstant.FIELD_LEVEL).toString()));
booleanQueryBuilder.add(termQuery, BooleanClause.Occur.MUST);
}
List<String> list = new ArrayList<>();
TopFieldCollector collector = TopFieldCollector.create(sort, 20000, 0);
searcher.search(booleanQueryBuilder.build(), collector);
docs = collector.topDocs(pageNum*pageSize, pageSize);
ScoreDoc[] scoreDocs = docs.scoreDocs;
int totalSize = collector.getTotalHits();
for (ScoreDoc scoreDoc : scoreDocs) {
Document doc = reader.document(scoreDoc.doc);
String logInfo = LogMessageConstant.COLOR_RED + doc.get(LogMessageConstant.FIELD_TIMESTAMP) +
LogMessageConstant.COLOR_RESET + " - " +
LogMessageConstant.COLOR_BLUE + doc.get(LogMessageConstant.FIELD_IP) +
LogMessageConstant.COLOR_RESET + " - " +
LogMessageConstant.COLOR_GREEN + "[" + doc.get(LogMessageConstant.FIELD_THREAD) + "]" +
LogMessageConstant.COLOR_RESET + " - " +
LogMessageConstant.COLOR_BLACK + doc.get(LogMessageConstant.FIELD_LEVEL) +
LogMessageConstant.COLOR_RESET + " - " +
LogMessageConstant.COLOR_MAGENTA + doc.get(LogMessageConstant.FIELD_CLASS_NAME) +
LogMessageConstant.COLOR_RESET + " - " +
LogMessageConstant.COLOR_GREEN + "<" + doc.get(LogMessageConstant.FIELD_TRACEID) + ">" +
LogMessageConstant.COLOR_RESET + " - " +
LogMessageConstant.COLOR_BLACK + highlightKeyword(doc.get(LogMessageConstant.FIELD_MESSAGE), whereJson.getString("message"));
list.add(logInfo);
}
reader.close();
JSONObject jo = new JSONObject();
jo.put("content", list);
jo.put("totalElements", totalSize);
return jo;
}
public static String highlightKeyword(String text, String keyword) {
if (ObjectUtil.isEmpty(keyword)) {
return text;
}
int startIndex = text.indexOf(keyword);
if (startIndex != -1) {
int endIndex = startIndex + keyword.length();
String beforeKeyword = text.substring(0, startIndex);
String afterKeyword = text.substring(endIndex);
String highlightedKeyword = LogMessageConstant.BACKGROUND_YELLOW + keyword + LogMessageConstant.COLOR_RESET
+ LogMessageConstant.COLOR_BLACK;
return beforeKeyword + highlightedKeyword + afterKeyword;
} else {
return text;
}
}
public static void main(String[] args) throws IOException, ParseException {
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 减去七天
LocalDateTime sevenDaysAgo = now.minus(7, ChronoUnit.DAYS);
// 转换为 Date 类型
Date sevenDaysAgoDate = Date.from(sevenDaysAgo.atZone(ZoneId.systemDefault()).toInstant());
// 获取时间戳
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date = dateFormat.parse(String.valueOf(sevenDaysAgo));
long timestamp = date.getTime();
System.out.println(now);
System.out.println(sevenDaysAgo);
System.out.println(sevenDaysAgoDate);
System.out.println(timestamp);
}
}

View File

@@ -1,28 +0,0 @@
package org.nl.config.lucene;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* <p>
* 设置静态参数初始化
* </p>
*
* @author generator
* @since 2023-11-16
*/
@Configuration
public class StaticConfig {
/**
* 日志索引目录
*/
@Value("${lucene.index.path}")
private String luceneDir;
@Bean
public int initStatic() {
UrlConfig.setLuceneUrl(luceneDir);
return 0;
}
}

View File

@@ -1,23 +0,0 @@
package org.nl.config.lucene;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @Author: lyd
* @Description: 日志标签枚举
* @Date: 2023/12/28
*/
@Getter
@AllArgsConstructor
public enum TagNameEnum {
/**
* LMS系统
*/
LMS("LMS系统"),
/**
* 标记符号
*/
MARK_SYMBOL("-");
private final String tag;
}

View File

@@ -1,21 +0,0 @@
package org.nl.config.lucene;
/**
* <p>
* url
* </p>
*
* @author generator
* @since 2023-11-16
*/
public class UrlConfig {
public static String luceneUrl;
public static String getLuceneUrl() {
return luceneUrl;
}
public static void setLuceneUrl(String luceneUrl) {
UrlConfig.luceneUrl = luceneUrl;
}
}

View File

@@ -1,18 +0,0 @@
package org.nl.config.mybatis;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import org.springframework.stereotype.Component;
/**
* @Author: lyd
* @Description: ID自动生成策略
* @Date: 2023/5/4
*/
@Component
public class CustomIdGenerator implements IdentifierGenerator {
@Override
public Number nextId(Object entity) {
return IdUtil.getSnowflake(1,1).nextId();
}
}

View File

@@ -0,0 +1,91 @@
package org.nl.config.mybatis;
import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.filter.FilterEventAdapter;
import com.alibaba.druid.proxy.jdbc.JdbcParameter;
import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
import com.alibaba.druid.proxy.jdbc.StatementProxy;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.util.JdbcUtils;
import com.mysql.cj.jdbc.result.ResultSetImpl;
import lombok.extern.slf4j.Slf4j;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/*
* @author ZZQ
* @Date 2023/2/10 11:27 上午
*/
@Slf4j
public class DruidFilter extends FilterEventAdapter {
@Override
public int preparedStatement_executeUpdate(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
return super.preparedStatement_executeUpdate(chain, statement);
}
@Override
public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
return super.statement_executeUpdate(chain, statement, sql);
}
@Override
protected void statementExecuteAfter(StatementProxy statement, String sql, boolean result) {
int size = statement.getParametersSize();
String executeSql = sql;
int count = 0;
try {
count=statement.getUpdateCount();
}catch (Exception ex){ }
if (count>0) {
if (size > 0) {
Collection<JdbcParameter> values = statement.getParameters().values();
List<Object> params = new ArrayList<>();
for (JdbcParameter value : values) {
params.add(value.getValue());
}
executeSql = SQLUtils.format(executeSql, JdbcUtils.MYSQL, params);
}
log.info("[----SQL----][update][ SQL: {} ]", executeSql);
}
super.statementExecuteAfter(statement, sql, result);
}
@Override
public ResultSetProxy statement_getResultSet(FilterChain chain, StatementProxy statement) throws SQLException {
ResultSetProxy rs = super.statement_getResultSet(chain, statement);
String executeSql = statement.getLastExecuteSql();
if (true){
int result = 0;
if (rs != null) {
ResultSetImpl rss = rs.getResultSetRaw().unwrap(ResultSetImpl.class);
result = rss.getRows().size();
}
try {
int size = statement.getParametersSize();
if (size>0){
Collection<JdbcParameter> values = statement.getParameters().values();
List<Object> params = new ArrayList<>();
for (JdbcParameter value : values) {
params.add(value.getValue());
}
executeSql = SQLUtils.format(executeSql, JdbcUtils.MYSQL, params);
}
}catch (Exception ex){
log.warn("[-SQL解析异常-][{}]",ex.getMessage());
}
log.info("[----SQL----][select][执行结果:{}][ SQL: {} ]",result, executeSql);
}
return rs;
}
}

View File

@@ -1,13 +1,19 @@
package org.nl.config.mybatis;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
/**
* <p>
* MybatisPlus配置
@@ -16,10 +22,13 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
* @author generator
* @since 2023-11-16
*/
@EnableTransactionManagement
@Configuration
@Slf4j
public class MybatisPlusConfig {
@Autowired
private DataSource dataSource;
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
添加自增插件
@@ -35,5 +44,10 @@ public class MybatisPlusConfig {
return interceptor;
}
@PostConstruct
public void datainnit() {
String url = ((DruidDataSource) dataSource).getUrl();
System.out.println("项目数据库地址:" + url);
log.debug("项目数据库地址:{}", url);
}
}

View File

@@ -1,56 +0,0 @@
//package org.nl.config.saconfig;
//
//import org.springframework.core.annotation.Order;
//import org.springframework.stereotype.Component;
//import org.springframework.web.cors.CorsConfiguration;
//
//import javax.servlet.*;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//
///**
// * 跨域过滤器
// * @author kong
// */
//@Component
//@Order(-200)
//public class CorsFilter implements Filter {
//
// static final String OPTIONS = "OPTIONS";
//
// @Override
// public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
// throws IOException, ServletException {
// HttpServletRequest request = (HttpServletRequest) req;
// HttpServletResponse response = (HttpServletResponse) res;
// // 允许指定域访问跨域资源
// response.setHeader("Access-Control-Allow-Origin", "*");
// // 允许所有请求方式
// response.setHeader("Access-Control-Allow-Methods", "*");
// // 有效时间
// response.setHeader("Access-Control-Max-Age", "3600");
// // 允许的header参数
// response.setHeader("Access-Control-Allow-Headers", "*");
// response.setHeader("Access-Control-Allow-Credentials", "true");
//
// // 如果是预检请求,直接返回
// if (OPTIONS.equals(request.getMethod())) {
// System.out.println("=======================浏览器发来了OPTIONS预检请求==========");
// response.getWriter().print("");
// return;
// }
//
// // System.out.println("*********************************过滤器被使用**************************");
// chain.doFilter(req, res);
// }
//
// @Override
// public void init(FilterConfig filterConfig) {
// }
//
// @Override
// public void destroy() {
// }
//
//}

View File

@@ -1,25 +0,0 @@
package org.nl.config.saconfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.springframework.stereotype.Component;
import java.util.function.BiFunction;
/**
* s
* @author ZZQ
* @Date 2022/11/24 3:47 下午
*/
@Component
public class LoginUserHandler implements BiFunction<String, String, Object> {
@Override
public Object apply(String user, String password) {
//用户登入账号密码查询:
StpUtil.login(Long.valueOf(password));
return SaResult.ok("登录成功!").setData(StpUtil.getTokenValue());
}
}

View File

@@ -1,35 +0,0 @@
package org.nl.config.saconfig;
import cn.dev33.satoken.config.SaSsoConfig;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ModelAndView;
/**
* s
* @author ZZQ
* @Date 2022/11/28 10:58 上午
*/
@Configuration
public class SaInitConfig {
@Autowired
LoginUserHandler loginUserHandler;
@Autowired
public void configSso(SaSsoConfig sso) {
System.out.println("启动初始化-----SaSsoConfig");
// 配置未登录时返回的View
sso.setNotLoginView(() -> new ModelAndView("sa-login"));
// 配置:登录处理函数
sso.setDoLoginHandle(loginUserHandler);
sso.setSendHttp(s -> {
HttpResponse execute = HttpRequest.get(s).execute();
return execute.body();
});
}
}

View File

@@ -0,0 +1,21 @@
package org.nl.config.satoken;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
/**
* @author: lyd
* @description:
* @Date: 2022/10/8
*/
@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}

View File

@@ -0,0 +1,44 @@
package org.nl.config.satoken;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author: lyd
* @description: sa-token的配置路由拦截
* @Date: 2022-09-20
*/
@Slf4j
@ConfigurationProperties(prefix = "security")
@Configuration
@Data
public class SaTokenConfigure implements WebMvcConfigurer {
// 白名单
private String[] excludes;
// Sa-Token 整合 jwt (Simple 简单模式)
@Bean
public StpLogic getStpLogicJwt() {
return new StpLogicJwtForSimple();
}
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
.addPathPatterns("/**")
.excludePathPatterns(excludes); // 白名单
}
}

View File

@@ -0,0 +1,38 @@
package org.nl.config.satoken;
import cn.dev33.satoken.stp.StpInterface;
import org.nl.common.utils.SecurityUtils;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author: lyd
* @description: stp接口impl 自定义权限验证接口扩展 保证此类被springboot扫描即可完成sa-token的自定义权限验证扩展
* @Date: 2022-09-20
*/
@Component
public class StpInterfaceImpl implements StpInterface {
/**
* 用户权限获取
* @param o login存入的值此处存放用户id
* @param s
* @return
*/
@Override
public List<String> getPermissionList(Object o, String s) {
return SecurityUtils.getCurrentUserPermissions();
}
/**
* 角色权限获取 - 数据库没有设计角色code因此不推荐使用角色鉴权
* @param o
* @param s
* @return
*/
@Override
public List<String> getRoleList(Object o, String s) {
return null;
}
}

View File

@@ -0,0 +1,88 @@
## 关于satoken的提示
### 本系统采用两个session存放相关信息
1、其中tokenSession存放的是
提供公共模块使用获取是Object可以直接强转此实体.
主要使用在 SecurityUtils类上使用的key: userInfo
```java
@Data
public class CurrentUser implements Serializable {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String username;
private Object user;
private List<String> permissions = new ArrayList<>();
}
```
2、Session存放的是UserDto,提供业务模块使用使用的key: UserDto
```java
@Getter
@Setter
public class UserDto extends BaseDTO implements Serializable {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private Set<RoleSmallDto> roles;
private Set<JobSmallDto> jobs;
private DeptSmallDto dept;
private Long deptId;
private String username;
private String nickName;
private String email;
private String phone;
private String gender;
private String avatarName;
private String avatarPath;
private String extId;
private String extuserId;
@JsonIgnore
private String password;
private Boolean enabled;
@JsonIgnore
private Boolean isAdmin = false;
private Date pwdResetTime;
}
```
### 加密规则
```
SaSecureUtil.md5BySalt("123456", "salt")
```
### 另一种拦截
```
registry.addInterceptor(new SaRouteInterceptor((request, response, handler) -> {
System.out.println(SaHolder.getRequest().getRequestPath());
// 登录验证 -- 排除多个路径
SaRouter
// 获取所有的
.match("/**")
// 排除下不需要拦截的
.notMatch(securityProperties.getExcludes())
// 对未排除的路径进行检查
.check(() -> {
// 检查是否登录 是否有token
StpUtil.checkLogin();
});
})).addPathPatterns("/**");
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
```