springmvc/springboot拦截器+ThreadLocal验证用户和用户信息共享传递

 ThreadLocal 类定义

package com.jt.web.thread;
import java.util.Map;
import com.jt.web.pojo.User;
public class UserThreadLocal {
	/**
	 * 关于参数的说明
	 * 	如果需要传递多值则使用Map集合封装
	 */
	private static ThreadLocal userThread = 
			new ThreadLocal();
	
	public static void set(User user){
		userThread.set(user);
	}
	
	public static User get(){
		return userThread.get();
	}
	
	//防止内存泄漏
	public static void remove(){
		userThread.remove();
	}
}

拦截器编写

package com.jt.web.intercept;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.web.pojo.User;
import com.jt.web.thread.UserThreadLocal;

import redis.clients.jedis.JedisCluster;

//handler处理器 作用:真正执行COntroller-Servic-Mapper
public class UserInterceptor implements HandlerInterceptor{
	
	@Autowired
	private JedisCluster jedisCluster;
	private static ObjectMapper objectMapper = new ObjectMapper();
	
	//在执行COntroller方法之前执行
	/**
	 * boolean 表示是否放行 
	 * 	 true:放行 用户可以跳转页面
	 * 	 false:拦截  之后给定重定向路径
	 * 
	 * 业务逻辑:
	 * 	1.判断用户客户端是否有Cookie/token数据
	 * 		如果用户没有token则重定向到用户登陆页面
	 *  2.如果用户token中有数据,则从redis缓存中获取数据
	 *  	如果redis中数据为null,则重定向到用户登陆页面
	 *  3.如果reids中有数据,则放行请求.
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		String token = "";
		//获取Cookie数据
		Cookie[] cookies = request.getCookies();
		for (Cookie cookie : cookies) {
			if("JT_TICKET".equals(cookie.getName())){
				token = cookie.getValue();
				break;
			}
		}
		//判断Cookie是否为null
		if(!StringUtils.isEmpty(token)){
			//检测缓存中是否有该数据
			String userJSON = jedisCluster.get(token);
			if(!StringUtils.isEmpty(userJSON)){
				
				//将userJSON转化为User对象
				User user = 
						objectMapper.readValue(userJSON, User.class);
				//思路.使用Session共享
				//request.getSession().setAttribute("JT_USER", user);
				UserThreadLocal.set(user);
				//用户已经登陆 放行请求
				return true;
			}
		}
		//表示用户没有登陆
		response.sendRedirect("/user/login.html");
		return false;
	}
	
	//执行完业务逻辑后拦截
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		
	}

	//返回页面之前拦截
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		
		//将ThreadLocal数据清空
		UserThreadLocal.remove();
	}
}

 xml中配置拦截器 (方式1,springmvc方式)


	
		
			
			
		
	

springboot方式配置 (方式2)

@Configuration
//定制SpringMVC的一些功能都使用WebMvcConfigurer
public class AdminWebConfig implements WebMvcConfigurer {
 
    /**
     * 配置拦截器
     * @param registry 相当于拦截器的注册中心
     * addPathPatterns 配置要拦截哪些路径 
     *    如 addPathPatterns("/**")表示拦截所有请求,包括我们的静态资源
     * excludePathPatterns 表示我们要放行哪些(表示不用经过拦截器)
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

         registry.addInterceptor(new UserInterceptor())
                  .addPathPatterns("/**") 
                  .excludePathPatterns("/login");
    }
}

 

 使用线程变量

Long userId = UserThreadLocal.get().getId();

你可能感兴趣的:(功能模块,#,springboot,spring,boot,后端,java)