最近一直在学习javaWeb,并且自己尝试着写个项目练手,今天实现了登录验证功能,整理一下做个笔记。
有两种方法可以实现这个功能:
- Servlet过滤器Filter
- SpringMVC拦截器
我在项目中使用的是第二种方式来实现的。
1.创建Interceptor拦截器
- 通过实现
HandlerInterceptor接口 - 通过继承
HandlerInterceptorAdapter抽象类 - 通过实现
WebRequestInterceptor接口
1.1 实现HandlerInterceptor接口
废话少说,直接上代码
/**
* 登陆拦截器
* Created by LiuZongRui on 17/2/20.
*/
public class LoginInterceptor implements HandlerInterceptor {
/**
* 该方法将在Controller处理之前进行调用,return false则请求中止
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
// 获取请求的url
String url = httpServletRequest.getRequestURI();
if (StringUtils.equals(url, "/console/login.do")) {
// 登陆接口,放行
return true;
} else {
HttpSession session = httpServletRequest.getSession();
User user = (User) session.getAttribute(Constans.USER);
if (user != null) {
return true;
}
}
// 不符合条件的跳转到登录界面
// 客户端跳转
httpServletResponse.sendRedirect("/console/login.do");
return false;
}
/**
* Controller处理之后,ModelAndView返回之前调用这个方法
*/
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
/**
* 在ModelAndView视图渲染之后调用这个方法,一般此方法用于清理资源
*/
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
1.2 继承HandlerInterceptorAdapter抽象类
/**
*通过查看HandlerInterceptorAdapter的源码可以发现,它其实也是实现HandlerInterceptor接口的,
*只是进一步进行了封装,重写对应的方法即可。
*/
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
super.preHandle(request, response, handler);
return false;
}
}
1.3 实现WebRequestInterceptor接口
public class LoginWebInterceptor implements WebRequestInterceptor {
/**
*在请求处理之前执行,该方法主要是用于准备资源数据的,然后可以把它们当做请求属性放到WebRequest中。
*它与HandlerInterceptor的preHandle是不同,它没有返回值。
*/
public void preHandle(WebRequest webRequest) throws Exception {
//这个是放到request范围内的,所以只能在当前请求中的request中获取到
request.setAttribute("request", "request", WebRequest.SCOPE_REQUEST);
//这个是放到session范围内的,如果环境允许的话它只能在局部的隔离的会话中访问,否则就是在普通的当前会话中可以访问
request.setAttribute("session", "session", WebRequest.SCOPE_SESSION);
//如果环境允许的话,它能在全局共享的会话中访问,否则就是在普通的当前会话中访问
request.setAttribute("globalSession", "globalSession", WebRequest.SCOPE_GLOBAL_SESSION);
}
/**
* 该方法将在Controller执行之后,返回视图之前执行,ModelMap表示请求Controller处理之后返回的Model对象,所以可以在
* 这个方法中修改ModelMap的属性,从而达到改变返回的模型的效果。
*/
public void postHandle(WebRequest webRequest, ModelMap modelMap) throws Exception {
}
public void afterCompletion(WebRequest webRequest, Exception e) throws Exception {
}
}
大概总结了一下SpringMVC拦截器的三种实现方法。万变不离其中,都是针对请求的三个阶段进行拦截,进行相应的操作。在实现登录验证的功能时,只需要处理preHandle()方法就行了,并且第三种方式不可取,因为它用于准备资源数据。
2.在spring-mvc的xml配置文件中配置拦截器
直接上代码
<!--拦截器-->
<mvc:interceptors>
<!--多个拦截器,顺序执行-->
<mvc:interceptor>
<!--匹配多级路径-->
<mvc:mapping path="/**"/>
<!--登陆权限拦截器-->
<bean class="com.ws.console.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
配置代码简单易懂,但是映射路径还是需要注意:
<mvc:mapping path="/*"/>这个不是匹配所有的请求,而是代表着根目录的第一级请求,如请求路径为:http://localhost:8080/project/path1,如上配置可以拦截,如果请求路径为:http://localhost:8080/project/path1/path2,如上配置则不能拦截,需要修改配置为: <mvc:mapping path="/*/*"/>。如果想拦截http://localhost:8080/project/path1/path2,而不想拦截http://localhost:8080/project/path2/path1,可以配置为:<mvc:mapping path="/path1/*">。
通过SpringMVC拦截器可以非常方便的实现登录拦截功能,以上就是全部的实现代码了,不过还存在两个问题,由于篇幅原因,将另外写一篇文章来记录。