在工作中实用SpringBoot已经有一段时间了,但却因为一次吃饭被师傅的一句话点醒,决定仔细认真的研究一下自己学习的东西,加深理解。找了本SpringBoot应用书籍,直接看书有的时候看的有点晕,就索性结合着博客学习,感觉博客里的兄弟搞的挺好的,通俗易懂。
我们为什么学习实用拦截器,拦截器可以实现什么功能,有什么优势呢,下面是我直接搜的一个兄弟的总结:
原文链接:原文链接
拦截器可以说相当于是个过滤器:就是把 不想要的或不想显示的内容给过滤掉。拦截器可以抽象出一部分代码可以用来完善原来的action。同时可以减轻代码冗余,提高重用率。
比如在登入一个页面时,如果要求用户密码、权限等的验证,就可以用自定义的拦截器进行密码验证和权限限制。对符合的登入者才跳转到正确页面。这样如果有新增权限的话,不用在action里修改任何代码,直接在interceptor里修改就行了。
1、好处:拦截器也可以让你将通用的代码模块化并作为可重用的类。Struts2中的很多特性都是由拦截器来完成的。
2、作用:可以构成拦截器栈,完成特定功能。比如日志记录、登录判断、权限检查等作用。
那么我们准备实用拦截器之前需要学习一点东西:
我们先学习两个东西,HandlerInterceptor 和 WebMvcConfigurerAdapter
第一种:实现HandlerInterceptor 接口,或者是继承实现了HandlerInterceptor 接口的类,例如HandlerInterceptorAdapter;
第二种:实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。
HandlerInterceptor接口中定义了三个方法。
boolean preHandle() 该方法在处理请求之前进行调用,就是在执行Controller的任务之前。如果返回true就继续往下执行,返回false就放弃执行。
void postHandle()该方法将在请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用,可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作,比如可以在这里将渲染的视图名称更改为其他视图名称。
void afterCompletion()该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行,也就是页面已经渲染完毕后调用此方法。用于进行资源清理。
public class SessionInterceptor implements HandlerInterceptor{
/*在执行Controller的任务之前判断是否有Session信息
如果有Session信息就往下执行,去调用Controller。
如果没有Session就跳转到登录页面
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session=request.getSession();
if(session.getAttribute("User")!=null){
return true;
}
String url = "/login.html";
request.getRequestDispatcher(url).forward(request,response);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//controller 方法处理完毕后,调用此方法。
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//页面渲染完毕后调用此方法,通常用来清除某些资源,类似Java语法的finally。
}
}
WebMvcConfigurerAdapter:对Spring进行配置
@Configuration
public class WebSecurityConfig extends WebMvcConfigurerAdapter {
@Bean
public SessionInterceptor getSessionInterceptor() {
return new SessionInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
/*调用我们创建的SessionInterceptor。
* addPathPatterns("/api/**)的意思是这个链接下的都要进入到SessionInterceptor里面去执行
* excludePathPatterns("/login")的意思是login的url可以不用进入到SessionInterceptor中,直接
* 放过执行。
*
* 注意:如果像注释那样写是不可以的。这样等于是创建了多个Interceptor。而不是只有一个Interceptor
* 所以这里有个大坑,搞了很久才发现问题。
*
* */
SessionInterceptor sessionInterceptor=new SessionInterceptor();
registry.addInterceptor(sessionInterceptor).addPathPatterns("/api/**")
.excludePathPatterns("/login","/verify");
// registry.addInterceptor(sessionInterceptor).excludePathPatterns("/login");
// registry.addInterceptor(sessionInterceptor).excludePathPatterns("/verify");
super.addInterceptors(registry);
}
}
WebMvcConfigurer
WebMvcConfigurer是用来全局定制化SpringBoot的MVC特性。开发者通过实现WebMvcConfigurer接口来配置应用的MVC全局特性。
@Configuration
public class MvcConfigurer implements WebMvcConfigurer{
//拦截器
public void addInterceptors(InterceptorRegistry registry){
}
//跨域访问配置
public void addCorsMappings(CorsRegistry registry){
}
//格式化
public void addFormatters(FormatterRegistry registry){
}
//URI到视图的映射
public void addViewControllers(ViewControllerRegistry registry){
}
//其他更多全局定制接口
}
上面的代码就是实现这个功能的。来回顾一下需求和解决方法。
需求1、在登录前不管那个链接都跳转到Login页面。从WebMvcConfigurationAdapter里面看到,除了/login和verify其他的页面都要进入到Interceptor里面。
需求2、在登录验证成功里面添加Session就好了。
需求3、在Interceptor里面我们可以看到如果有Session就会通过,如果没有就会跳转到登录页面。
参考文档链接:https://blog.youkuaiyun.com/qq_24210767/article/details/78516616