公共字段填充——同一请求属于同一线程(存储线程参数)

  1. 在我们全局MVC请求拦截器的时候,从Session获取当前操作的员工id,将id存储到该请求线程域空间当中,给到MP自动填充字段值的update业务方法中updateUser使用

在这里插入图片描述

  1. ThreadLocal线程类介绍

在这里插入图片描述

  1. 功能完善

在这里插入图片描述

  1. 代码实现
  • 基于ThreadLocal封装工具类, 用户保存和获取当前登录用户id
package com.xxz.common;

/**
 * 基于ThreadLocal封装工具类, 用户保存和获取当前登录用户id
 */
public class BaseContext {

    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    //存储值
    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }

    //获取值
    public static Long getCurrentId(){
        return threadLocal.get();
    }

}

  • 登录拦截器LoginCheckFilter.java,存储到BaseContext工具类的ThreadLocal线程类中
    在这里插入图片描述
package com.xxz.filter;

import com.alibaba.fastjson.JSON;
import com.xxz.common.BaseContext;
import com.xxz.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 检查用户是否已经登录
 * @WebFilter标注该类为Web过滤器类, 需要在启动类中定义@ServletComponentScan //扫描到Spring容器
 */
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {

    //路径配置工具对象 [路径匹配符、支持通配符]
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    /**
     * 拦截 方法
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //对象转换
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //拦截逻辑实现
        //1. 判断本次请求的URI
        String requestURI = request.getRequestURI();
        //提示拦截到的请求RUI
        log.info("拦截到请求:{}", requestURI);
        //定义不需要处理的路径
        String[] urls = new String[]{  //问题: /backend/index.html 如何与路径 /backend/** 匹配上需要工具对象AntPathMatcher
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**"
        };
        //2. 判断本次请求是否需要处理
        boolean check = check(urls, requestURI);
        //3. 如果不需要处理,则直接放行
        if(check){
            log.info("本次请求{}不需要处理..");
            filterChain.doFilter(request, response);
            return;
        }
        //4. 判断登录状态,如果已登录,则直接放行
        if(request.getSession().getAttribute("employee") != null){
            log.info("用户已登录..., 用户id为:{}", request.getSession().getAttribute("employee"));
            //获取当前操作的用户
            Long empId = (Long) request.getSession().getAttribute("employee");
            //设置到当前线程中[基于ThreadLocal封装工具类, 用户保存和获取当前登录用户id]
            BaseContext.setCurrentId(empId); 

            filterChain.doFilter(request, response);
            return;
        }
        //用户未登录提示
        log.info("用户未登录...");
        //5. 如果未登录则返回未登录结果,提示需要登录,通过输出流方式
        response.getWriter().write(JSON.toJSONString(Result.error("NOTLOGIN")));
        //提示信息
        return;
//        log.info("拦截到请求:{}", request.getRequestURI());
        //放行
//        filterChain.doFilter(request, response);
    }

    /**
     * 路径匹配, 检查本次请求是否需要放行
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls, String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            //如果匹配成功,则返回true
            if(match){
                return true;
            }
        }
        //如果整个循环没有结束,则返回false
        return false;
    }

}

  • MP自动填充处理器类
    在这里插入图片描述
package com.xxz.common;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 自定义MP数据对象处理器
 */
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入操作,自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自动填充[insert]...");
        log.info(metaObject.toString());
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
        //从请求工具类BaseContext请求线程基准类获取当前请求线程存储的此Session中的操作员工id
        metaObject.setValue("createUser", BaseContext.getCurrentId());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }

    /**
     * 更新操作,自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自动填充[update]...");
        log.info(metaObject.toString());
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值