Elasticsearch、XXLJob以及最近的学习记录


前言

在这九月的最后一周,来总结一下最近的学习记录,主要是对于Elasticsearch、XXLjob的初步学习,想着还是多记录点,以便后面去看看,具体的错误认知点在哪,以及找到一些自己的认识点。


后台数据脱敏

一、普通方式

首先该功能是基于Spring Boot项目做的,所以这是一个简单的流程。

具体实现:首先设定一个角色code,比如 “涉密人员” “secret”;

通过登录时获取token中的用户名然后通过用户名去获取他的角色code,同时去动态的获取涉密人员的角色code(即做判断的时候不能写死,从数据库中获取),

然后将他们的code做判断;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest;
import java.util.List; /**
* <p>
*
* </p>
*
* @author yuyueq
* @since 2021/9/13
*/
@Component
@Slf4j
public class JudgeSecret {
//TODO
@Autowired
private BosuserIdentityService bosuserIdentityService; @Autowired
private BosRoleService bosRoleService; public Boolean judgingSecret(HttpServletRequest servletRequest) {
boolean flag = false;
String token = JwtTokenUtil.getToken(servletRequest);
String username = JwtUtil.getUsername(token);
//做角色code获取并进行判断
for (*:*) {
if (role.getId().equals(sRole.getId())) {
flag = true;// 是涉密员
break;
}
}
return flag;
} public String mobileReplace(String mobile) {
if (StrUtil.isNotBlank(mobile)) {
return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
} else {
return "-";
}
} public String nameReplace(String name) {
if (StrUtil.isNotBlank(name)) {
return StringUtils.rightPad(StringUtils.left(name, 1), StringUtils.length(name), "*");
} else {
return "-";
}
} }

二、Spring AOP实现

只需要给serviceImpl加EncryptMethod注解,以及在需要加密的字段加上EncryptMobileField、EncryptNameField注解


package net.liangyihui.dhbos.aspect; import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; /**
* @ClassName : ServiceAspect
* @Author : yuyueq
* @Date: 2021/9/18 14:23
* @Description :
*/
@Slf4j
@Configuration
@Aspect
public class ServiceAspect { private final String ExpGetResultDataPoint = "@annotation(位置)"; @Autowired
private JudgeSecret judgeSecret; @Pointcut(ExpGetResultDataPoint)
public void EncryptMethod() { } @Around("EncryptMethod()")
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
log.info("环绕通知的目标方法名:" + proceedingJoinPoint.getSignature().getName());
processInputArg(proceedingJoinPoint.getArgs());
try {//obj之前可以写目标方法执行前的逻辑
Object obj = proceedingJoinPoint.proceed();
processOutPutObj(obj);
return obj;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
} /**
* 处理返回对象
*/
private void processOutPutObj(Object object) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest servletRequest = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
boolean flag = !judgeSecret.judgingSecret(servletRequest);
if (flag) {
if (object instanceof Page) {
//page
Page page = (Page) object;
page.getRecords().forEach(o -> {
try {
Field[] fields = o.getClass().getDeclaredFields();
for (Field field : fields) {
encrypt(field, o);
}
} catch (Exception e) {
log.info("反射错误" + e);
}
});
} else {
try {
Class clazz = object.getClass();
Field[] fields = ReflectUtil.getFieldsDirectly(clazz, true);
for (Field field : fields) {
field.setAccessible(true);
String proType = field.getGenericType().toString();
if (proType.contains("class java.lang")
|| proType.contains("class java.math.")
|| proType.contains("class java.util")) {
encrypt(field, object);
} else if ("byte".equals(proType) || "short".equals(proType) || "int".equals(proType) || "long".equals(proType) || "double".equals(proType) || "float".equals(proType) || "boolean".equals(proType)) {
encrypt(field, object);
} else if (proType.startsWith("java.util")) {
// if (field.getGenericType() instanceof ParameterizedType) {
// Class newClazz = (Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
// Object obj = newClazz.newInstance();
// processOutPutObj(obj);
// }
} else if (field.getType().isArray()) {
//属性是数组类型则遍历 } else {
//class类型的遍历
PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), clazz);
Method method = descriptor.getReadMethod();
Object obj = method.invoke(object);
if (null != obj) {
processOutPutObj(obj);
}
}
}
} catch (Exception e) {
e.printStackTrace();
log.info("脱敏加密失败" + e);
}
}
}
} private Field encrypt(Field field, Object obj) {
try {
if (field.isAnnotationPresent(EncryptMobileField.class)) {
field.setAccessible(true);
Object value = field.get(obj);
if (value instanceof Long || value == null) {
field.set(obj, null);
} else {
field.set(obj, judgeSecret.mobileReplace(value.toString()));
}
}
if (field.isAnnotationPresent(EncryptNameField.class)) {
field.setAccessible(true);
Object value = field.get(obj);
if (value != null) {
field.set(obj, judgeSecret.nameReplace(value.toString()));
} else {
field.set(obj, null);
}
}
} catch (IllegalAccessException e) { }
return field;
} /**
* 处理输入参数
*
* @param args 入参列表
*/
private void processInputArg(Object[] args) {
// for (Object arg : args) {
// System.out.println("ARG原来为:" + arg);
// }
}
}

以上根据以下文章学习所得

Springboot(二十一)@Aspect 切面注解使用

注解Annotation实现原理与自定义注解例子

什么是反射机制?反射机制的应用场景有哪些?

代理模式详解:静态代理+JDK/CGLIB 动态代理实战


Elasticsearch学习

参考笔记链接

这块的话是简单入了个门,所以我是在B站上找的“狂神说”的视频,至于视频中的笔记,网上也是一搜一大堆

这里的话贴一个比较全面的笔记链接:https://blog.csdn.net/qq_21197507/article/details/115076913

体会

初次安装运行体验,感觉整体很像数据库,所以比较好上手,然后目前是未感受到它的魅力,毕竟还未在

实际项目中使用,但是感觉这个技术还是挺强的。

RestfulApi:https://restfulapi.cn/

MVP:https://choerodon.io/zh/blog/mvp/




ES仿京东搜索Demo

我的仓库地址:https://gitee.com/yuyueq/esjd


XXLJob学习

这块的话还是分享我所看到的文章,毕竟我也是根据这些文档跟着学的

了解xxljob

再见 Spring Task,这个定时任务框架真香!

正巧还是今天发的

在Spring Boot中优雅的实现定时任务

入门xxljob

Spring Job?Quartz?XXL-Job?年轻人才做选择,艿艿全莽~

官方文档


最近看到的一些文章分享

羊哥最近看了上百封简历,发现很多小可爱技术词汇都乱拼

Layui的落幕,是否预示一个时代的结束?

其实看到官网通知很及时,因为我当时正在看文档,没想到出了事,个人还是很意外吧,毕竟自己才刚开始

打算去学着用,因为是感觉挺方便的,虽然没有vue和elementUI的好,但各有各的好处吧,只不过就是有点遗憾

没有早接触作者这么优秀的技术作品。

java学成什么样子可以出去实习

熟练掌握 MyBatis-Plus,这一篇就够了!

Spring最常用的7大类注解,史上最强整理!

何为架构?

简单说一下Kafka

简单吹一下微服务

Debug调试

最后

基本上也就这些内容了,所以接下来,还要通过一些的实践内容去体会这些技术,不然仅仅只是看过而已。

共勉!

“他乡纵有当头月,不及家乡一盏灯”

贴几张图



Elasticsearch、XXLJob以及最近的学习记录的更多相关文章

  1. ElasticSearch 学习记录之ES几种常见的聚合操作

    ES几种常见的聚合操作 普通聚合 POST /product/_search { "size": 0, "aggs": { "agg_city&quo ...

  2. ElasticSearch 学习记录之ES短语匹配基本用法

    短语匹配 短语匹配故名思意就是对分词后的短语就是匹配,而不是仅仅对单独的单词进行匹配 下面就是根据下面的脚本例子来看整个短语匹配的有哪些作用和优点 GET /my_index/my_type/_sea ...

  3. ElasticSearch 学习记录之 分布式文档存储往ES中存数据和取数据的原理

    分布式文档存储 ES分布式特性 屏蔽了分布式系统的复杂性 集群内的原理 垂直扩容和水平扩容 真正的扩容能力是来自于水平扩容–为集群添加更多的节点,并且将负载压力和稳定性分散到这些节点中 ES集群特点 ...

  4. ElasticSearch 学习记录之如任何设计可扩容的索引结构

    扩容设计 扩容的单元 一个分片即一个 Lucene 索引 ,一个 Elasticsearch 索引即一系列分片的集合 一个分片即为 扩容的单元 . 一个最小的索引拥有一个分片. 一个只有一个分片的索引 ...

  5. ElasticSearch 学习记录之ES高亮搜索

    高亮搜索 ES 通过在查询的时候可以在查询之后的字段数据加上html 标签字段,使文档在在web 界面上显示的时候是由颜色或者字体格式的 GET /product/_search { "si ...

  6. ElasticSearch 学习记录之ES查询添加排序字段和使用missing或existing字段查询

    ES添加排序 在默认的情况下,ES 是根据文档的得分score来进行文档额排序的.但是自己可以根据自己的针对一些字段进行排序.就像下面的查询脚本一样.下面的这个查询是根据productid这个值进行排 ...

  7. ElasticSearch 学习记录之父子结构的查询

    父子结构 父亲type属性查询子type 的类型 父子结构的查询,可以通过父亲类型的字段,查询出子类型的索引信息 POST /product/_search { "query": ...

  8. ElasticSearch 学习记录之Text keyword 两种基本类型区别

    ElasticSearch 系列文章 1 ES 入门之一 安装ElasticSearcha 2 ES 记录之如何创建一个索引映射 3 ElasticSearch 学习记录之Text keyword 两 ...

  9. Elasticsearch学习记录(分布式的特性)

    Elasticsearch学习记录(分布式的特性) 分布式的特性 我们提到Elasticsearch可以扩展到上百(甚至上千)的服务器来处理PB级的数据.然而我们的例子只给出了一些使用Elastics ...

随机推荐

  1. flutter中修改键盘状态

    当用户进行表格输入时,为更方便的方便用户操作,我们需要设置键盘状态方便用户点击,如当表格填写完成时,用户可以直接点击键盘下面的"完成"状态完成提交. 实现如下: TextFormF ...

  2. 盘点 HashMap 的实现原理及面试题

    1.请你谈谈 HashMap 的工作原理如果被问到 HashMap 相关的问题,它的工作原理都会被作为面试的开场白,这个时候先装作若有所思的样子冷静一下.首先 HashMap 是基于 hashing ...

  3. Qt 的MDI 多文档窗口

    一.MDI简介 MDI就是多文档界面(Multi-document Interface,MDI)应用程序 MDI就是在主窗口里创建多个同类型的MDI子窗口,这些MDI子窗口在主窗口里显示,并共享主窗口 ...

  4. Java之Apache Commons-IO使用精讲

    Commons IO是针对开发IO流功能的工具类库.主要包括六个区域: 工具类--使用静态方法执行共同任务输入--用于InputStream和Reader实现输出--用于OutputStream和Wr ...

  5. python某个module使用了相对引用,同时其__name__又是__main__导致的错误

    主要讲解 某个module中使用了相对引用,同时这个module的 __name__ 属性 又是 __main__ 会报错的问题 1.问题复现 文件结构很简单: |--------package | ...

  6. Javascript - Vue - 动画

    动画状态类名 vue动画通过将需要执行动画的标签放入transition标签中,再通过设置预置的vue动画类名的css样式来控制动画的呈现效果. 开场动画状态的三个类名 v-enter:动画开始之前的 ...

  7. go实现堆排序

    package main import "fmt" func main(){ arr:=[]int{4,8,2,1,6,9,3,5,7,8,1,4} dui(arr) fmt.Pr ...

  8. canvas——离屏

    离屏操作: 1.创建一个新的离屏canvas; 2.把一些复杂额绘画操作(背景),画在离屏canvas上: 3.将离屏canvas通过drawImage(离屏canvas对象,x1,y1,offcan ...

  9. Java反射的浅显理解

    一.回顾反射相关的知识 1.在xml文件中使用反射的好处: 1)代码更加灵活,后期维护只需要修改配置文件即可 · 初学者一般习惯于在代码本身上直接修改,后期也可以修改配置文件达到相同的目的 · 修改配 ...

  10. JS_DOM操作之常用事件

    1 - onload 事件:加载完成后立即执行 <!DOCTYPE html> <html lang="en"> <head> <meta ...