spring拦截器的笔记

本文章主要内容如下
拦截器可以干什么 怎么做
拦截器可以干什么
日志记录:记录日志,以便进行信息监控、信息统计、计算PV(Page View)等。
权限检查:如登录检测;
性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,
从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,
只要是多个处理器都需要的即可使用拦截器实现。
OpenSessionInView:如hibernate,在进入处理器打开Session,在完成后关闭Session。
拦截器本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。

怎么实现|怎么做
1 拦截器接口

public interface HandlerInterceptor {  
    boolean preHandle(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler)   
            throws Exception;  

    void postHandle(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler, ModelAndView modelAndView)   
            throws Exception;  

    void afterCompletion(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler, Exception ex)  
            throws Exception;  
}   

preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Controller实现);
返回值:true表示继续流程(如调用下一个拦截器或处理器);
false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;

afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。

2 配置文件设置

<mvc:resources mapping="/resources/**" location="/resources/"></mvc:resources>  
<!--    
register "global" interceptor beans to apply to all registered HandlerMappings .  
Each inteceptor must implement the org.springframework.web.servlet.HandlerInterceptor or  
org.springframework.web.context.request.WebRequestInterceptor interface  
-->  
<mvc:interceptors>  
    <mvc:interceptor>  
        <mvc:mapping path="/**" />  
        <mvc:exclude-mapping path="/css/**" />  
        <mvc:exclude-mapping path="/js/**" />  
        <mvc:exclude-mapping path="/images/**" />  
        <bean class="com.fpx.common.auth.mgt.framework.interceptor.ContextInterceptor" />  
    </mvc:interceptor>  
</mvc:interceptors>  

<mvc:interceptors>  
    <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->  
    <bean class="com.host.app.web.interceptor.AllInterceptor"/>  
    <mvc:interceptor>  
        <mvc:mapping path="/test/number.do"/>  
        <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->  
        <bean class="com.host.app.web.interceptor.LoginInterceptor"/>  
    </mvc:interceptor>  
</mvc:interceptors> 

 <bean xmlns="http://www.springframework.org/schema/beans" id="authenticateInterceptor"
          class="com.javaplus.castle.authenticate.AuthenticateInterceptor">
        <property name="uncheckUrls">
            <list>
                <value>/index</value>
                <value>/doLogin</value>

            </list>
        </property>
    </bean>
<!-- 注册 DefaultAnnotationHandlerMapping
         如果使用了<mvc:annotation-driven />或者<annotation-driven />它会自动注册
         DefaultAnnotationHandlerMapping 与AnnotationMethodHandlerAdapter
         这两个bean,所以就没有机会再给它注入interceptors属性,就无法指定拦截器。
        当然我们可以通过人工配置上面的两个Bean,不使用 <mvc:annotation-driven />,就可以 给interceptors属性 注入拦截器了。-->

  <beans:bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <beans:property name="interceptors">
            <beans:list>
                <beans:ref bean="authenticateInterceptor"/>
                <!--<beans:ref bean="logInterceptor"/>-->
            </beans:list>
        </beans:property>
    </beans:bean>
``<servlet>
    <servlet-name>airman</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
        classpath:spring/springmvc.xml
      </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>airman</servlet-name>
    <url-pattern>/</url-pattern> 拦截所有
  </servlet-mapping>
 <!--这一部分是3.0新加入的特性,加入这个标记会告诉spring此处是本地资源文件不会当做Action处理。如果不加入这个配置引用的js和css将无法加载-->
    <resources mapping="/resources/**" location="/resources/"/>
    <resources mapping="/ext-4.2.1.883/**" location="/ext-4.2.1.883/"/>
    <resources mapping="/common/**" location="/common/"/>
    <resources mapping="/CAdminLte/**" location="/CAdminLte/"/> 
    <view-controller path="/" view-name="redirect:/index"/>

拦截器的实现代码

public class AuthenticateInterceptor extends HandlerInterceptorAdapter {

private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticateInterceptor.class);
private List<String> uncheckUrls;
public void setUncheckUrls(List<String> uncheckUrls) {
    this.uncheckUrls = uncheckUrls;
}

@Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    HttpSession session = request.getSession();
    String contextPath = request.getContextPath();
    String requestURI = request.getRequestURI();
    LOGGER.info("RequestURI:" + requestURI);
    for (String url : uncheckUrls) {
        if (requestURI.startsWith(contextPath+url)) {
            return true;
        }
    }

    //获取登录用户信息
    Account human = (Account) session.getAttribute(CastleSecurityManager.CURRENT_USER);
    if (human == null) {
        //跳转登录页面
        LOGGER.info("human == null RequestURI:" + requestURI);
        response.sendRedirect("redirect:/index");

        return false;
    }
    return true;
}

}

@Controller
public class LoginController {

Log log = LogFactory.getLog(this.getClass());

@Autowired(required = false)
private IUserService userService;

@RequestMapping(value = "/index")
public String logincheck(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) {
    HttpSession session = request.getSession();
    Account human = (Account) session.getAttribute(CastleSecurityManager.CURRENT_USER);
    if (human == null) {
        return "login";
    } else {
        return "index";//返回到jsp
    }
}

@RequestMapping(value = "/doLogin")
public ModelAndView doLogin( HttpServletRequest request,HttpServletResponse response, @RequestParam Map<String, Object> conditions, ModelAndView mv) {
    HttpSession session = request.getSession();
    String account = String.valueOf(conditions.get("account"));
    String pwd = String.valueOf(conditions.get("pwd"));
    Account user = userService.checkLogin(account, pwd);
    if (user == null) {
         mv.setViewName("login");
        mv.addObject("errorMessage", "用户名或密码错误");
        return mv;
    }
    session.setAttribute(CastleSecurityManager.CURRENT_USER, user);
    }

其他要点

redirect:/index是返回到requestmapping的请求中
view-name=”index”是到jsp里
getRequestDispatcher是服务器内部跳转,地址栏信息不变,只能跳转到web应用内的网页。
sendRedirect是页面重定向,地址栏信息改变,可以跳转到任意

if(controller instanceof UserLogin){
Object user = request.getSession().getAttribute(“user”);
if(user == null){
log.debug(“———–未登录访问 跳回登录页面—-“);
request.getRequestDispatcher(“/home/loginUI”).forward(request, response);
return false;
}
}

    HttpSession session = httpServletRequest.getSession();
    SysUser user = (SysUser) session.getAttribute("loginsucess");
    if (user != null){
        return true;
    }
    //执行到这里说明没有session,需要拦截
    httpServletRequest.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(httpServletRequest,httpServletResponse);
    return false;

public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
boolean flag = false;
String url = request.getRequestURL().toString();
     //不拦截上面定义的路径
for (String str : IGNORE_URL) {
if (url.contains(str)) {
flag = true;
break;
}
}
if (!flag) {
User user = (User)request.getSession().getAttribute(“users”);
if (user != null)
         flag = true;
       else
         response.sendRedirect(“/login.jsp”);
         return false;
}
return true;
}

   request.getRequestDispatcher("/third?name=jay").forward(request, response);  
   或  
   request.getRequestDispatcher("third?name=jay").forward(request, response);  
   或  
   this.getServletContext().getRequestDispatcher("/third?name=jay").forward(request, response); 
response.sendRedirect("http://www.baidu.com");  

本文章参考以下文章

http://www.mamicode.com/info-detail-400138.html

getRequestDispatcher 和sendRedirect区别
http://weidongke123-126-com.iteye.com/blog/1461526

SpringMVC中使用Interceptor拦截器
http://elim.iteye.com/blog/1750680

SpringMVC 常用配置说明
http://blog.csdn.net/strivezxq/article/details/45457067

spring拦截器、与filter的区别
http://blog.csdn.net/zqlsnow/article/details/52946826

SpringMVC拦截器(资源和权限管理)
http://blog.csdn.net/tonytfjing/article/details/39207551

spring mvc拦截器和的详解
http://www.cnblogs.com/yangzhilong/p/3725849.html

spring拦截器(里面有模糊匹配和不拦截地址配置代码)
http://www.cnblogs.com/fdzfd/p/5715699.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值