1.拦截器概念
java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截器是AOP思想的一个实现。
拦截器和过滤器的区别:
1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
4. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
4. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
package cn.limbo.controller;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by limbo on 2016/10/18.
*/
public class MyInterceptor implements HandlerInterceptor {
//请求处理的方法之前
//返回true那么执行下一个拦截器,返回false不执行下一个拦截器
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("------处理前-------");
return true;
}
//请求处理的方法执行之后
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("------处理后-------");
}
//在DispatcherServlet处理后执行-------一般做一些清理工作
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
3.配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<!--
/** 包括路径及其子路径
如果是/admin/* 拦截的是/admin/add,/admin/list 等,/admin/user/add不被拦截
如果是/admin/** 拦截/admin/add,/admin/list /admin/user/add
-->
<mvc:mapping path="/**"/>
<!--对应拦截器的类-->
<bean class="cn.limbo.controller.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
案例----登录控制
springmvc-servlet.xml
<mvc:interceptors>
<mvc:interceptor>
<!--
/** 包括路径及其子路径
如果是/admin/* 拦截的是/admin/add,/admin/list 等,/admin/user/add不被拦截
如果是/admin/** 拦截/admin/add,/admin/list /admin/user/add
-->
<mvc:mapping path="/**"/>
<mvc:mapping path="*.jsp" />
<!--对应拦截器的类-->
<bean class="cn.limbo.controller.LoginInterceptor">
<!--注入参数,记得要有set方法-->
<property name="allowPass">
<list>
<value>login.do</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
LoginInterceptor.java
package cn.limbo.controller;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* Created by limbo on 2016/10/19.
*/
public class LoginInterceptor implements HandlerInterceptor {
//设置直接放行的url
private List<String> allowPass;
public void setAllowPass(List<String> allowPass) {
this.allowPass = allowPass;
}
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//session中已经有了登录信息,则直接放行
Object session = httpServletRequest.getSession().getAttribute("user");
if(session != null) {
return true;
}
//如果拦截的url在allowPass中,放行
String url = httpServletRequest.getRequestURL().toString();
for(String temp:allowPass){
if(url.endsWith(temp))
return true;
}
//否则需要登录
httpServletResponse.sendRedirect(httpServletRequest.getContextPath()+"/login.jsp");
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
LoginController.java
package cn.limbo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by limbo on 2016/10/19.
*/
@Controller
@RequestMapping("/loginController")
public class LoginController {
@RequestMapping("/login.do")
public String login(HttpServletRequest request, HttpServletResponse response){
String userName = request.getParameter("userName").trim();
String password = request.getParameter("password").trim();
boolean flag = false;
if(!userName.equals("") && !password.equals("")){
if(userName.equals("aaa")&&password.equals("111")){
flag = true;
request.getSession().setAttribute("user",userName);
}
}
if(flag){
return "aaa";
}else{
return "redirect:/login.jsp";
}
}
@RequestMapping("/add.do")
public String add(){
System.out.println("add");
return "redirect:/index.jsp";
}
}
几个坑点:1.不能拦截jsp:拦截器只能拦截action,不能拦截jsp等资源页面,也就是说可以直接在地址栏访问到你需要的页面
解决方式:1.设置filter来过滤jsp。2.将需要登录来看的jsp页面放在WEB-INF文件夹下面。(springMVC推荐这样使用,防止其它你希望隐藏的页面被用户访问到)
2.配置文件里面的路径问题和注入问题,解决的方式写在注释里面了