Elasticsearch、XXLJob以及最近的学习记录
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);
//        }
    }
}
以上根据以下文章学习所得
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,这个定时任务框架真香!
正巧还是今天发的
入门xxljob
Spring Job?Quartz?XXL-Job?年轻人才做选择,艿艿全莽~
最近看到的一些文章分享
其实看到官网通知很及时,因为我当时正在看文档,没想到出了事,个人还是很意外吧,毕竟自己才刚开始
打算去学着用,因为是感觉挺方便的,虽然没有vue和elementUI的好,但各有各的好处吧,只不过就是有点遗憾
没有早接触作者这么优秀的技术作品。
Debug调试
最后
基本上也就这些内容了,所以接下来,还要通过一些的实践内容去体会这些技术,不然仅仅只是看过而已。
共勉!
“他乡纵有当头月,不及家乡一盏灯”
贴几张图



Elasticsearch、XXLJob以及最近的学习记录的更多相关文章
- ElasticSearch 学习记录之ES几种常见的聚合操作
		ES几种常见的聚合操作 普通聚合 POST /product/_search { "size": 0, "aggs": { "agg_city&quo ... 
- ElasticSearch 学习记录之ES短语匹配基本用法
		短语匹配 短语匹配故名思意就是对分词后的短语就是匹配,而不是仅仅对单独的单词进行匹配 下面就是根据下面的脚本例子来看整个短语匹配的有哪些作用和优点 GET /my_index/my_type/_sea ... 
- ElasticSearch 学习记录之 分布式文档存储往ES中存数据和取数据的原理
		分布式文档存储 ES分布式特性 屏蔽了分布式系统的复杂性 集群内的原理 垂直扩容和水平扩容 真正的扩容能力是来自于水平扩容–为集群添加更多的节点,并且将负载压力和稳定性分散到这些节点中 ES集群特点 ... 
- ElasticSearch 学习记录之如任何设计可扩容的索引结构
		扩容设计 扩容的单元 一个分片即一个 Lucene 索引 ,一个 Elasticsearch 索引即一系列分片的集合 一个分片即为 扩容的单元 . 一个最小的索引拥有一个分片. 一个只有一个分片的索引 ... 
- ElasticSearch 学习记录之ES高亮搜索
		高亮搜索 ES 通过在查询的时候可以在查询之后的字段数据加上html 标签字段,使文档在在web 界面上显示的时候是由颜色或者字体格式的 GET /product/_search { "si ... 
- ElasticSearch 学习记录之ES查询添加排序字段和使用missing或existing字段查询
		ES添加排序 在默认的情况下,ES 是根据文档的得分score来进行文档额排序的.但是自己可以根据自己的针对一些字段进行排序.就像下面的查询脚本一样.下面的这个查询是根据productid这个值进行排 ... 
- ElasticSearch 学习记录之父子结构的查询
		父子结构 父亲type属性查询子type 的类型 父子结构的查询,可以通过父亲类型的字段,查询出子类型的索引信息 POST /product/_search { "query": ... 
- ElasticSearch 学习记录之Text keyword 两种基本类型区别
		ElasticSearch 系列文章 1 ES 入门之一 安装ElasticSearcha 2 ES 记录之如何创建一个索引映射 3 ElasticSearch 学习记录之Text keyword 两 ... 
- Elasticsearch学习记录(分布式的特性)
		Elasticsearch学习记录(分布式的特性) 分布式的特性 我们提到Elasticsearch可以扩展到上百(甚至上千)的服务器来处理PB级的数据.然而我们的例子只给出了一些使用Elastics ... 
随机推荐
- NOIP 模拟 $23\; \rm 赛$
			题解 将所有物品分成四类,分别为两人共同喜欢的,只有一人喜欢的,没人喜欢的. 首先,先从两人共同喜欢的物品里找出 \(k\) 个,这时,就要从剩余的找出 \(\rm m-k\) 个,而且是最小的. 用 ... 
- python中的logging日志
			logging使用 import logging import os from logging import handlers from constants.constants import Cons ... 
- C++进阶—>带你理解多字节编码与Unicode码
			参考网址:https://blog.csdn.net/u011028345/article/details/78516320 多字节字符与宽字节字符 char与wchar_t 我们知道C++基本数据类 ... 
- wpf实现轮播效果
			在web上面轮播非常常见 WPF中似乎要自己搞,那么我依葫芦画瓢搞一个 如下,平时按一定的时间轮播,点击右下角的灰色圆点(不是很明显0.0),则切换到对应图片 先放 源码:https://gitee ... 
- 转:C语言自增自減问题总结
			C语言自增自減问题总结 在程序设计中,经常遇到"i=i+1"和"i=i-1"这两种极为常用的操作.C语言为这种操作提供了两个更为简洁的运算符,即++和--,分别 ... 
- Linkerd 2.10(Step by Step)—控制平面调试端点
			Linkerd 2.10 系列 快速上手 Linkerd v2 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traefik2 ... 
- Shell脚本一键部署——源码编译安装MySQL及自动补全工具
			Shell脚本一键部署--源码编译安装MySQL及自动补全工具 编译安装MySQL 1.软件包 Mysql安装包 将安装包拖至/opt目录下,编辑一个脚本文件,将以下内容复制进去,然后source或者 ... 
- WEB漏洞——XXE
			XXE漏洞又称XML外部实体注入(XML External Entity) 介绍XXE漏洞前先说一下什么是XML XML语言 XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据定义数据类 ... 
- LeetCode刷题模板(1):《我要打10个》之二分法
			Author : 叨陪鲤 Email : vip_13031075266@163.com Date : 2021.01.23 Copyright : 未 ... 
- Node.js躬行记(9)——微前端实践
			后台管理系统使用的是umi框架,随着公司业务的发展,目前已经变成了一个巨石应用,越来越难维护,有必要对其进行拆分了. 计划是从市面上挑选一个成熟的微前端框架,首先选择的是 icestark,虽然文档中 ... 
