自用工具类
# JAVA
# TreeNode
/**
*
* @author :jiangmh
* @create :Created in 2023/6/17 7:04
**/
public class NodeTreeUtils {
private static final String PARENT_ID_ROOT = "0";
/**
* 将所有数据按节点ID存进map
* @author J-Ming
* @date 2023/6/17 6:50
* @param allCosts 待转换为树形的数据,拥有节点nodeId、parentId以及存放子节点信息的List<CostInfo> children
* @return java.util.Map<java.lang.String, com.ming.demo.costinfo.entity.CostInfo>
*/
private Map<String, CostInfo> toCostMap(List<CostInfo> allCosts) {
Map<String, CostInfo> costMap = new ConcurrentHashMap<>(allCosts.size());
for (CostInfo cost : allCosts) {
costMap.put(cost.getNodeId(), cost);
}
return costMap;
}
/**
* 拿到所有parentId为0的根节点
* @author J-Ming
* @date 2023/6/17 6:54
* @param costMap
* @return java.util.List<com.ming.demo.costinfo.entity.CostInfo>
*/
private List<CostInfo> getRootCosts(Map<String, CostInfo> costMap) {
return costMap.values().stream()
.filter(cost -> PARENT_ID_ROOT.equals(cost.getParentId()))
.collect(Collectors.toList());
}
/**
* 转换为树形
* @author J-Ming
* @date 2023/6/17 6:55
* @param costMap
*/
private void buildCostTree(Map<String, CostInfo> costMap) {
for (CostInfo cost : costMap.values()) {
if (!PARENT_ID_ROOT.equals(cost.getParentId())) {
CostInfo parent = costMap.get(cost.getParentId());
if (parent != null && !parent.getNodeId().equals(cost.getNodeId())) {
parent.addChildren(cost);
}
}
}
}
public List<CostInfo> getCostsTreeBy3(List<CostInfo> allCosts) {
StopWatch watch = new StopWatch();
watch.start("处理耗时");
Map<String, CostInfo> costMap = toCostMap(allCosts);
buildCostTree(costMap);
List<CostInfo> rootCosts = getRootCosts(costMap);
watch.stop();
System.out.println(watch.prettyPrint());
return rootCosts;
}
/**
* 获得树形的数据
* @author J-Ming
* @date 2023/6/15 2:51
* @param allCosts 需要变成树形的数据
* @return java.util.List<com.ming.demo.entity.Costs>
*/
private List<CostInfo> getCostsTreeBy2(List<CostInfo> allCosts) {
StopWatch watch = new StopWatch();
watch.start("处理耗时");
Map<String, CostInfo> costMap = toCostMap(allCosts);
List<CostInfo> rootCosts = new ArrayList<>();
for (CostInfo cost : allCosts) {
CostInfo parent = costMap.get(cost.getParentId());
if (parent != null && !parent.getNodeId().equals(cost.getNodeId())) {
parent.addChildren(cost);
continue;
}
rootCosts.add(cost);
}
watch.stop();
System.out.println(watch.prettyPrint());
return rootCosts;
}
# MyBatisLog
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;
/**
* 获取SQL语句
* @author :jiangmh
* @date :Created in 2023/6/12 19:17
**/
public class SqlLogInterceptor implements InnerInterceptor {
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
String statement = ms.getId();
showSql(ms.getConfiguration(), boundSql, statement);
}
@Override
public void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) {
Configuration configuration = ms.getConfiguration();
BoundSql boundSql = ms.getBoundSql(parameter);
showSql(configuration, boundSql, ms.getId());
}
private void showSql(Configuration configuration, BoundSql boundSql, String statement) {
// 获得参数值
Map<Integer, Object> parameterValues = buildParameterValues(configuration, boundSql);
// 语句赋值
String sqlWithValues = getSqlWithValues(boundSql.getSql(), parameterValues);
String logText = formatMessage(sqlWithValues, statement);
// 打印红色 SQL 日志
System.err.println(logText);
}
public static String getSqlWithValues(String statementQuery, Map<Integer, Object> parameterValues) {
final StringBuilder sb = new StringBuilder();
// iterate over the characters in the query replacing the parameter placeholders
// with the actual values
int currentParameter = 0;
for (int pos = 0; pos < statementQuery.length(); pos++) {
char character = statementQuery.charAt(pos);
if (statementQuery.charAt(pos) == '?' && currentParameter <= parameterValues.size()) {
// replace with parameter value
Object value = parameterValues.get(currentParameter);
sb.append(value != null ? value.toString() : "");
currentParameter++;
} else {
sb.append(character);
}
}
return sb.toString();
}
// com.baomidou.mybatisplus.core.MybatisParameterHandler#setParameters
private static Map<Integer, Object> buildParameterValues(Configuration configuration, BoundSql boundSql) {
Object parameterObject = boundSql.getParameterObject();
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
Map<Integer, Object> parameterValues = new HashMap<>();
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
for (int i = 0; i < parameterMappings.size(); i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;
String propertyName = parameterMapping.getProperty();
if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
value = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(propertyName);
}
parameterValues.put(i, value);
}
}
return parameterValues;
}
return Collections.emptyMap();
}
public static String formatMessage(String sql, String statement) {
return StringUtils.hasText(sql) ? " ms " + " (" + statement + ")" +
"\n Execute SQL:" + sql.replaceAll("[\\s]+", " ") + "\n" : "";
}
}
# TemplateProcess
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;
import com.ming.common.annotation.Template;
/**
* 模板字符串处理工具类
* @author :jiangmh
* @date :Created in 2022/4/16 15:30
**/
public class TemplateProcessUtils {
/**
* 解析模板实体
* @author J-Ming
* @date 2022/4/16 18:10
* @param o 需要替换模板的实体对象
* @return java.util.Map<java.lang.String,java.lang.Object>
*/
public static Map<String, Object> templateHandle(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
Field[] superFields = o.getClass().getSuperclass().getDeclaredFields();
ArrayList<Field> fields1 = CollectionUtil.toList(fields);
ArrayList<Field> fields2 = CollectionUtil.toList(superFields);
fields1.addAll(fields2);
Map<String,Object> map = new HashMap<>();
for (Field field : fields1) {
Template annotation = field.getDeclaredAnnotation(Template.class);
Object value = ReflectUtil.getFieldValue(o, field.getName());
if (annotation != null && StrUtil.isNotEmpty(annotation.key()) && value != null) {
map.put(annotation.key(),value);
}
}
return map;
}
}
# ValidationExceptionHandler
import com.bairuitech.anychat.facex.model.ResultModel;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
/**
*
* @author :jiangmh
* @date :Created in 2022/6/29 10:04
**/
@ControllerAdvice
public class ValidationExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
return new ResponseEntity<>(getError(ex.getBindingResult().getFieldErrors()),status);
}
@Override
protected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
List<FieldError> allErrors = ex.getFieldErrors();
return new ResponseEntity<>(getError(allErrors),status);
}
private ResultModel getError(final List<FieldError> errors) {
StringBuilder buffer = new StringBuilder();
for (FieldError error : errors) {
buffer.append(error.getField()).append(" ").append(error.getDefaultMessage()).append(";");
}
return ResultModel.fail("ERROR",buffer);
}
}
# EasyExcel
/**
* easyExcel初始化工具类
* @author :jiangmh
* @date :Created in 2023/6/19 19:04
**/
public class ExcelService {
/**
* 获取excel读取对象
* @author J-Ming
* @date 2023/6/20 1:51
* @param file excel文件
* @param head 文件对应实体
* @param readListener 整个文件的监听器
* @return com.alibaba.excel.ExcelReader
*/
public static <T> ExcelReader getExcelReader(File file, Class<T> head, ReadListener<T> readListener) {
return EasyExcel.read(file, head, readListener).build();
}
/**
*
* @author J-Ming
* @date 2023/6/20 1:51
* @param file excel文件
* @return com.alibaba.excel.ExcelReader
*/
public static ExcelReader getExcelReader(File file) {
return EasyExcel.read(file).build();
}
/**
*
* @author J-Ming
* @date 2023/6/20 1:51
* @param file web上传的excel文件
* @return com.alibaba.excel.ExcelReader
*/
public static ExcelReader getExcelReader(MultipartFile file) throws IOException {
return EasyExcel.read(file.getInputStream()).build();
}
/**
*
* @author J-Ming
* @date 2023/6/20 1:51
* @param file excel文件
* @param head 文件对应实体
* @param readListener 整个文件的监听器
* @return com.alibaba.excel.ExcelReader
*/
public static <T> ExcelReader getExcelReader(MultipartFile file, Class<T> head, ReadListener<T> readListener) throws IOException {
return EasyExcel.read(file.getInputStream(), head, readListener).build();
}
/**
* 获取需要读的sheet页
* @author J-Ming
* @date 2023/6/20 1:56
* @param sheetNo sheet序号,从0开始
* @param headRowNumber 第几行开始读取,从1开始
* @return com.alibaba.excel.read.metadata.ReadSheet
*/
public static ReadSheet getReadSheet(Integer sheetNo, Integer headRowNumber) {
return EasyExcel.readSheet(sheetNo).headRowNumber(headRowNumber).build();
}
/**
*
* @author J-Ming
* @date 2023/6/20 1:58
* @param sheetNo sheet序号,从0开始
* @param headRowNumber 第几行开始读取,从1开始
* @param head 对应sheet的实体对象
* @param listener 每个sheet页的单独监听器
* @return com.alibaba.excel.read.metadata.ReadSheet
*/
public static <T> ReadSheet getReadSheet(Integer sheetNo, Integer headRowNumber, Class<T> head, ReadListener<T> listener) {
return EasyExcel.readSheet(sheetNo).headRowNumber(headRowNumber).head(head).registerReadListener(listener).build();
}
}
/**
* easyExcel数据读取监听器
* @author :jiangmh
* @date :Created in 2023/6/19 19:01
**/
public class ExcelDataListener<T> extends AnalysisEventListener<T> {
private static final int BATCH_COUNT = 100;
private List<T> cachedDataList = new ArrayList<>(BATCH_COUNT);
private Consumer<List<T>> consumer;
/**
* 回调函数
*/
private BiConsumer<T, AnalysisContext> callBack;
public ExcelDataListener(Consumer<List<T>> consumer) {
this.consumer = consumer;
}
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
// System.out.println(headMap);
}
@Override
public void invoke(T t, AnalysisContext analysisContext) {
if (callBack != null) {
callBack.accept(t, analysisContext);
}
cachedDataList.add(t);
if (cachedDataList.size() >= BATCH_COUNT) {
if (consumer != null) {
saveData(consumer);
}
// 存储完成清理 list
cachedDataList.clear();
cachedDataList = new ArrayList<>(BATCH_COUNT);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
if (consumer != null) {
saveData(consumer);
}
// 防止携带上个sheet页数据
cachedDataList.clear();
}
/**
*
* @author J-Ming
* @date 2023/6/20 1:40
* @param consumer 对读取数据的处理函数
*/
private void saveData(Consumer<List<T>> consumer) {
consumer.accept(cachedDataList);
}
public void setCallBack(BiConsumer<T, AnalysisContext> callBack) {
this.callBack = callBack;
}
public List<T> getList() {
return this.cachedDataList;
}
}
# CustomApplicationContextInitializer
/**
* 配置文件密文解析
* @author :J-Ming
* @date :Created in 2023/12/28 19:56
**/
public class CustomApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
final String prefix = "EK(";
final String suffix = ")";
final String encKeyEnv = "data.enc.key";
ConfigurableEnvironment environment = applicationContext.getEnvironment();
String encKey = environment.getProperty(encKeyEnv);
if (encKey == null || encKey.length() == 0) {
System.out.println("encKey为空");
}
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, HexUtil.decodeHex(encKey));
Map<String, Object> updatedSource = new HashMap<>();
MutablePropertySources propertySources = environment.getPropertySources();
for (PropertySource<?> propertySource : propertySources) {
if (propertySource instanceof MapPropertySource) {
MapPropertySource mapPropertySource = (MapPropertySource) propertySource;
for (Map.Entry<String, Object> entry : mapPropertySource.getSource().entrySet()) {
String key = entry.getKey();
String value = entry.getValue().toString();
if (value.startsWith(prefix) && value.endsWith(suffix)) {
String decryptedValue;
String res = value.substring(prefix.length(), value.length() - suffix.length());
decryptedValue = aes.decryptStr(res, CharsetUtil.CHARSET_UTF_8);
updatedSource.put(key, decryptedValue);
}
}
}
}
propertySources.addFirst(new MapPropertySource("custom-property-source", updatedSource));
}
}
# HtmlUtil
public class HtmlUtil {
public static void main(String[] args) {
String filePath1 = "E:\\document\\1.html";
String filePath2 = "E:\\document\\2.html";
List<Map<String, Object>> href1 = getHref(filePath1);
List<Map<String, Object>> href2 = getHref(filePath2);
List<Map<String, Object>> elementsOnlyInHref = new ArrayList<>(href1);
elementsOnlyInHref.removeAll(href2);
System.out.println(href1.size());
System.out.println(href2.size());
System.out.println(elementsOnlyInHref.size());
String hl = "<DT><A HREF=\"{websiteUrl}\" ADD_DATE=\"{addDate}\" ICON=\"{icon}\">{websiteName}</A>";
StrBuilder strBuilder = new StrBuilder();
for (Map<String, Object> map : elementsOnlyInHref) {
String format = StrUtil.format(hl, map);
strBuilder.append(format).append("\n");
}
// System.out.println(strBuilder.toString());
FileUtil.writeString(strBuilder.toString(),new File("E:\\document\\websiteUrl.txt"),"UTF-8");
}
// 查找两个列表中的不同数据
private static List<Map<String, Object>> findDifferences(List<Map<String, Object>> href1, List<Map<String, Object>> href2) {
List<Map<String, Object>> differences = new ArrayList<>();
Set<Map<String, Object>> set1 = new HashSet<>(href1);
Set<Map<String, Object>> set2 = new HashSet<>(href2);
// // 找到在href1中但不在href2中的数据
// for (Map<String, Object> item : set1) {
// if (!set2.contains(item)) {
// differences.add(item);
// }
// }
// 找到在href2中但不在href1中的数据
for (Map<String, Object> item : set2) {
if (!set1.contains(item)) {
differences.add(item);
}
}
return differences;
}
private static List<Map<String, Object>> getHref(String filePath) {
ArrayList<Map<String, Object>> list = new ArrayList<>();
try {
// 从HTML文件中加载文档
File input = new File(filePath);
Document doc = Jsoup.parse(input, "UTF-8");
// 使用CSS选择器选择所有的<a>标签
Elements links = doc.select("a");
// 遍历每个链接元素并提取网站名称和链接
for (Element link : links) {
String websiteName = link.text(); // 提取网站名称
String websiteUrl = link.attr("href"); // 提取网站链接
String addDate = link.attr("add_date");
String icon = link.attr("icon");
HashMap<String, Object> map = MapUtil.newHashMap();
map.put("websiteName", websiteName);
map.put("websiteUrl", websiteUrl);
map.put("addDate", addDate);
map.put("icon", icon);
list.add(map);
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
}
# LINUX
# ClearCatalinaLog
#!/bin/bash
# 定义日志路径
log_path=/home/ops/work/logs/
tomcat_path=/home/ops/tomcat/apache-tomcat-9.0.34/logs/catalina.out
# 定义当前日期
d=`date -d '1 day ago' +%Y-%m-%d`
# 定义15天前的日期
d15=`date -d'15 day ago' +%Y-%m-%d`
# 跳转到tomcat日志文件夹,复制catalina.out到catalina.out.${d}.log
cd ${log_path} && cp ${tomcat_path} ${log_path}/catalina.out.${d}.log
# 清空cat文件alina.out
echo > catalina.out
# 删除15天前的catalina.out.${d15}.log
rm -rf ${log_path}/catalina.out.${d15}.log
# TomcatDeploy
#!/bin/bash
project_name=AnyChatPlatform
tomcat_path=/home/ops/tomcat/apache-tomcat-9.0.34
work_path=/home/ops/work
if [[ !(-f ${work_path}/war/${project_name}.war) ]]
then
echo "工作目录中,未检测到war包"
exit 1;
fi
######################################### kill启动过的tomcat #########################################
echo "1、kill之前启动过的${project_name}"
tomcatPid=$(ps -ef | grep $tomcat_path/bin/bootstrap.jar | grep -v grep | awk '{print $2}')
kill -9 $tomcatPid
echo "tomcat线程:$tomcatPid已杀死..."
sleep 1
######################################### 清除旧war #########################################
oldFile=${tomcat_path}/webapps
echo "3、备份旧${project_name}文件"
cp ${oldFile}/${project_name}.war $work_path/bak
sleep 1
echo "4、清除旧${project_name}文件"
rm -rf "${oldFile}/${project_name} ${oldFile}/${project_name}.war"
sleep 1
######################################### 拷贝新war包至web目录 #########################################
echo "5、拷贝新war包至web目录"
cp ${work_path}/war/${project_name}.war $tomcat_path/webapps/
sleep 2
######################################### 启动tomcat #########################################
echo "6、启动tomcat"
sh $tomcat_path/bin/startup.sh
read -n1 -p "是否查看日志[y/n]" answer
if [ $answer="y" ] || [ $answer="Y" ]; then
tail -f -n1 $tomcat_path/logs/catalina.out
else
echo "发布war结束"
fi
编辑 (opens new window)
上次更新: 2024/06/14, 04:38:55