springboot配置登录拦截器

记一次springboot配置登录拦截器踩的坑

写在前面的话
系统采用的springboot+Mybatis+js+Mysql+Redis前后端分离的一个系统,在写拦截器时,遇到很多的坑,想记录这一次踩坑。

springboot版本

// An highlighted block
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.7.RELEASE</version>
	<relativePath/> 
</parent>

新建WebConfigurer

       在springboot2.0之后WebConfigurer需要实现 WebMvcConfigurer 这个接口,并实现里面的两个方法。(在老版本的 spring-boot 中使用的是WebMvcConfigurerAdapter,新版本中已过时,还有不能通过继承 WebMvcConfigurationSupport 这个类来实现,这样会在某些情况下失效),第二个 addInterceptors 方法用来注册添加拦截器。

package com.example.config;

import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//import com.example.demo.Interceptors.AdminLoginInterceptor;

@Configuration
public class WebConfigurer implements WebMvcConfigurer {

	@Autowired
	private AdminLoginInterceptor adminLoginInterceptor;
	
//	@Bean
//	public AdminLoginInterceptor adminLoginInterceptor() {
//		return new AdminLoginInterceptor();
//	}
	
	 //前后端分离解决跨域问题
	@Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }

	// 用来配置静态资源的,比如html,js,css,等等
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
	}

	// 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(adminLoginInterceptor).addPathPatterns("/Site/**").addPathPatterns("/Test/**")
				.excludePathPatterns("/Login/adminLogin");
	}
}

拦截器部分
新建一个AdminLoginInterceptor ,这里封装了一个message的实体类,
主要有state,massage,和token

package com.example.config;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.example.demo.Redis.RedisDao;
import com.example.demo.base.baseEntity.Message;
import com.example.demo.base.baseTool.Constans;
import com.example.demo.entity.Admin;
import com.example.demo.base.baseTool.GsonUtil;;

@Component
public class AdminLoginInterceptor implements HandlerInterceptor {
	@Autowired private RedisDao redisDao;
	
	// 这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {	
		//测试
		System.out.println("来到了拦截器");
		
		Message message = new Message();

//		Object admin = request.getSession().getAttribute("token");
		String admin2 = request.getHeader("token");
		System.out.println(admin2);
		// 去redis查看有没有这个token存在,
		if ( admin2 == null || !redisDao.existKey(admin2)) {
			message.setState(3);
			message.setMessage("账号过期!请重新登录");
			response.getWriter().write(GsonUtil.object2Json(message));
			System.out.println("未登录");
			return false;
		} else {
			System.out.println("登录");
			return true; 
		}
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}

}

需要特别注意的地方
我的application的文件和拦截器的文件不再同一一个包下
application所在包com.example.demo
拦截器所在包在com.example.config
需要加一个@ComponentScan(basePackages={“com.example”})
这个程序就能够扫描,不然拦截器不会起作用

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages={"com.example"})
@SpringBootApplication
public class Application {
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
 
}

你可能感兴趣的:(springboot配置登录拦截器)