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);
//        }
    }
}

以上根據以下文章學習所得

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

註解Annotation實現原理與自定義註解例子

什麼是反射機制?反射機制的應用場景有哪些?

代理模式詳解:靜態代理+JDK/CGLIB 動態代理實戰


Elasticsearch學習

參考筆記鏈接

這塊的話是簡單入了個門,所以我是在B站上找的「狂神說」的影片,至於影片中的筆記,網上也是一搜一大堆
這裡的話貼一個比較全面的筆記鏈接://blog.csdn.net/qq_21197507/article/details/115076913
image

體會

初次安裝運行體驗,感覺整體很像資料庫,所以比較好上手,然後目前是未感受到它的魅力,畢竟還未在
實際項目中使用,但是感覺這個技術還是挺強的。

RestfulApi://restfulapi.cn/

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

image
image


ES仿京東搜索Demo

我的倉庫地址://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調試image

最後

基本上也就這些內容了,所以接下來,還要通過一些的實踐內容去體會這些技術,不然僅僅只是看過而已。
共勉!
「他鄉縱有當頭月,不及家鄉一盞燈」

貼幾張圖
image
image

image

Tags: