三十四、Springboot 在拦截器中注入对象

(一)问题背景

  因为拦截器是在上下文容器 Spring Context 初始化之前执行,所以没有办法直接在拦截器中注入Service对象,解决办法如下:

(二)拦截器中注入Bean对象
package com.yuedu.config;


import com.yuedu.interceptor.SessionInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author 咸鱼
 * @date 2019-03-11 22:45
 */
@Configuration
public class WebAppConfigure implements WebMvcConfigurer {
    @Bean
    public SessionInterceptor sessionInterceptor(){
        return new SessionInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sessionInterceptor());
    }
}

package com.yuedu.interceptor;

import com.yuedu.entity.ResultEnum;
import com.yuedu.entity.User;
import com.yuedu.exception.BaseException;
import com.yuedu.service.UserService;
import com.yuedu.util.FinalName;
import com.yuedu.util.Md5Utils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

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

/**
 * @author 咸鱼
 * @date 2019-03-11 21:37
 */
public class SessionInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            if (request.getSession().getAttribute(FinalName.SESSION_USER) != null) {
                return true;
            }
            String token = request.getHeader("token");
            /*
             * 若token为空,有以下几个可能:
             *     一、第一次使用,未登录过,此时请求调用的应该是“/user/login”,该请求通过,这里不再处理
             *     二、以前登陆过,但是缓存被删除了,此时请求调用的应该是“/user/login”,该请求通过,这里不再处理
             *     二、并未带token参数,说明该请求无需身份验证,这里不再处理
             * 所以,这里的业务逻辑是:
             *     若带了token,就进行验证,验证通过,则存入Session,没带,则不处理。(PS:若某些页面需要登录才能访问,
             * 则由后续逻辑判断Session中是否有User,有则表明已登录,无则无法处理后续逻辑)
             */
            return StringUtils.isBlank(token) || validateLoginWithToken(token, request);
        } else {
            return super.preHandle(request, response, handler);
        }
    }

    /**
     * 验证身份,并存入session
     * @param token 验证标识
     * @param request 请求对象
     * @return true:验证通过 false:验证失败
     */
    private boolean validateLoginWithToken(String token, HttpServletRequest request) {
        String encryptOpenId = token.split(":")[0];
        Long userId = Long.valueOf(token.split(":")[1]);
        User user = new User();
        user.setId(userId);

        User userInDb = userService.selectUser(user);
        if (userInDb == null) {
            throw new BaseException(ResultEnum.USER_NOT_EXISTS);
        }
        if (encryptOpenId.equals(Md5Utils.getMd5WithSalt(userInDb.getOpenId(), FinalName.MD5_SALT))){
            request.getSession().setAttribute(FinalName.SESSION_USER, userInDb);
            return true;
        } else {
            throw new BaseException(ResultEnum.TOKEN_IS_ERROR);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/panchang199266/article/details/88412207
今日推荐