- 在我们全局MVC请求拦截器的时候,从Session获取当前操作的员工id,将id存储到该请求线程域空间当中,给到MP自动填充字段值的update业务方法中updateUser使用
- ThreadLocal线程类介绍
- 功能完善
- 代码实现
- 基于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());
}
}