springboot+thymeleaf基于全局异常处理实现session过期处理

最近的新搞的系统中需要添加session过期处理,这里没有使用继承HandlerInterceptor自定义拦截器的方式,采用了一种简单的方式进行处理.在此记录一下.
页面中有从session中获取用户对象信息的地方:${session.user.userName},如果session已过期或是服务器非正常关闭,都会导致页面报错关于thymeleaf相关的userName不能为null的错误.此异常全局异常处理类可以捕获,指定跳转到公共错误页面,点击回到首页进入到首页的逻辑中,在设置登陆首页的地方判断了session是否过期,如果已经过期,直接弹出提示:用户信息已经过期.重新登陆!
全局异常处理类:

	@ControllerAdvice
public class GloableExcption extends RuntimeException {
    
    

private final Logger logger = LoggerFactory.getLogger(this.getClass());

//此注解表示自定义异常处理方法,参数是指定对哪种异常进行处理
@ExceptionHandler(Exception.class)
public ModelAndView toError(HttpServletRequest request, Exception e) throws Exception{
    
    
    logger.debug(e.getMessage());
    ModelAndView modelAndView = new ModelAndView();

    if(e instanceof BussinessExcption){
    
    
        logger.debug("业务异常",e.getMessage());
        modelAndView.addObject("exceptionMsg",e.getMessage());

    }
    else if(e instanceof AuthorizationException){
    
    
        logger.debug("权限问题",e);
        modelAndView.addObject("exceptionMsg","权限不足,禁止访问");
    }
    else if ( e instanceof Exception) {
    
    
        logger.debug("未知类型异常",e);
        modelAndView.addObject("exceptionMsg","未知类型异常,请联系管理员:"+e.getMessage());
    }
    modelAndView.setViewName("./error");
    return  modelAndView;
}
}`

跳转到首页的逻辑:

 // 跳转到首页
    @RequestMapping("/index")
    public ModelAndView goToIndex(HttpServletRequest request){
    
    
        ModelAndView modelAndView = new ModelAndView();
        // 如果用户session过期.重新登陆,否则点击链接直接跳转到首页
        if(request.getSession().getAttribute("adminUser") ==null){
    
    
            modelAndView.addObject("message","用户信息已过期,请重新登陆");
            modelAndView.setViewName("./login");
            return modelAndView;
        }
        modelAndView.setViewName("index");
        return modelAndView;
    }

错误页面上添加两个a标签进行跳转:
在这里插入图片描述
补充:自定义拦截器+全局异常处理实现session是否过期判断
session是否过期实现原理:
自定义拦截器实现HandlerInterceptor接口并实现preHandle方法,此方法表示是对拦截到的方法对执行该方法具体业务逻辑之前进行逻辑处理,preHandle方法方法中添加判断session是否过期的判断逻辑,如果用户信息已经过期,直接抛出session的自定义异常.自定义的全局异常处理类会捕获到该异常并将错误信息返回到前端.
实现步骤:
1.自定义登录拦截器
2.注册自定义登录拦截器并置顶拦截以及过滤的路径
3.全局异常处理类中添加接收异常是否是自定义session异常的判断逻辑
4.配置文件application-dev.yml中指定session的过期时间
# 设置端口以及session过期时间:30分钟
server:
port: 8080
servlet:
session:
timeout: PT30M
代码:
自定义登录拦截器:

		@Component
public class LoginInterceptor implements HandlerInterceptor {
    
    
    private static Logger logger= LoggerFactory.getLogger(LoginInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        HttpSession session = request.getSession();
        // 从session中获取用户信息
        User user = (User) session.getAttribute("user");

        // session过期
        if(user == null){
    
    
            logger.info("session过期处理,抛出异常");
            throw new SessionExcption("用户信息已过期");
        }else{
    
    
            return true;
        }
    }
}
配置拦截器:
@Configuration
public class LoginInterceptorConfig extends WebMvcConfigurerAdapter {
    
    

    // 注入自定义拦截器
    @Autowired
    private LoginInterceptor loginInterceptor;

    /**
     * 定义拦截规则, 根据自己需要进行配置拦截和排除的接口
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(loginInterceptor)
                // .addPathPatterns() 是配置需要拦截的路径
                .addPathPatterns("/**")
                // .excludePathPatterns() 用于排除拦截
                .excludePathPatterns("/user/login") // 登录接口
                .excludePathPatterns("/user/logout") // 退出接口
                .excludePathPatterns("/lib/**") // 排除静态文件
                .excludePathPatterns("/js/**")
                .excludePathPatterns("/img/**")
                .excludePathPatterns("/css/**");
    }

}
全局异常处理类:
@ControllerAdvice
public class GloableException  {
    
    

private final Logger logger = LoggerFactory.getLogger(this.getClass());

//@ExceptionHandler(Exception.class)表示自定义异常处理方法,参数是指对Exception会进行处理,@ResponseBody表示是返回前端json格式数据
@ExceptionHandler(Exception.class)
@ResponseBody
public ResultVo toError(Exception e) {
    
    
    logger.debug(e.getMessage());

    // 判断是否是session过期异常
    if(e instanceof SessionExcption){
    
    
        logger.debug("用户信息过期",e.getMessage());
        return ResultVoUtil.error("异常处理,用户信息已过期");
    }
    // 判断是否是自定义业务类型异常,其他的异常都归入到未知业务异常
    if(e instanceof BussinessExcption){
    
    
        logger.debug("业务异常",e.getMessage());
        return  ResultVoUtil.error("业务异常:"+e.getMessage());
    }
     else {
    
    
        logger.debug("未知类型异常",e.getMessage());
        return  ResultVoUtil.error("未知类型异常:"+e.getMessage());
    }
    }
    备注:此处返回的是自定义的返回数据并封装了工具类进行返回,实现简单就不做代码展示;

猜你喜欢

转载自blog.csdn.net/weixin_43401380/article/details/106479083