`

Spring拦截器实现登陆验证

阅读更多

Spring为我们提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter这个适配器,
继承此类,可以非常方便的实现自己的拦截器。他有三个方法:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)  
        throws Exception {  
         return true;  
     }   
    public void postHandle(   
         HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)  
             throws Exception {  
     }   
     public void afterCompletion(   
       HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)   
             throws Exception {  
     } 

 

分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面) 
在preHandle中,可以进行编码、安全控制等处理;  在postHandle中,有机会修改ModelAndView; 
在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。  
如果基于xml配置使用Spring MVC,可以利用SimpleUrlHandlerMapping、
BeanNameUrlHandlerMapping进行Url映射(相当于 struts的path映射)和拦截请求(注入interceptors),
如果基于注解使用Spring MVC,可以使用DefaultAnnotationHandlerMapping注入interceptors。注意无论
基于xml还是基于注 解,HandlerMapping bean都是需要在xml中配置的。

<bean id="timeBasedAccessInterceptor" class="com.spring.handler.TimeBasedAccessInterceptor">   
     <property name="openingTime" value="9" />  
    <property name="closingTime" value="12" />   
     <property name="mappingURL" value=".*/user\.do\?action=reg.*" />  
 </bean>   
 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">   
    <property name="interceptors">  
        <list>   
            <ref bean="timeBasedAccessInterceptor"/>  
         </list> 
     </property>  
 </bean>

 

这里我们定义了一个mappingURL属性,实现利用正则表达式对url进行匹配,从而更细粒度的进行拦截。当然如果不定义mappingURL,则默认拦截所有对Controller的请求。  
UserController:

@Controller   
@RequestMapping("/user.do")   3. public class UserController{ 
    @Autowired   
     private UserService userService;   
     @RequestMapping(params="action=reg")   
    public ModelAndView reg(Users user) throws Exception {  
         userService.addUser(user);   
         return new ModelAndView("profile","user",user);   
     }   
    // other option ...   
 }

 这个Controller相当于Struts的DispatchAction  
你也可以配置多个拦截器,每个拦截器进行不同的分工。

拦截器接口:

package org.springframework.web.servlet;  
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来产生响应;

postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。

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

//拦截器适配器
//doDispatch方法  
//1、处理器拦截器的预处理(正序执行)  
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();  
if (interceptors != null) {  
    for (int i = 0; i < interceptors.length; i++) {  
    HandlerInterceptor interceptor = interceptors[i];  
        if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {  
            //1.1、失败时触发afterCompletion的调用  
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
            return;  
        }  
        interceptorIndex = i;//1.2、记录当前预处理成功的索引  
}  
}  
//2、处理器适配器调用我们的处理器  
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
//当我们返回null或没有返回逻辑视图名时的默认视图名翻译(详解4.15.5 RequestToViewNameTranslator)  
if (mv != null && !mv.hasView()) {  
    mv.setViewName(getDefaultViewName(request));  
}  
//3、处理器拦截器的后处理(逆序)  
if (interceptors != null) {  
for (int i = interceptors.length - 1; i >= 0; i--) {  
      HandlerInterceptor interceptor = interceptors[i];  
      interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);  
}  
}  
//4、视图的渲染  
if (mv != null && !mv.wasCleared()) {  
render(mv, processedRequest, response);  
    if (errorView) {  
        WebUtils.clearErrorRequestAttributes(request);  
}  
//5、触发整个请求处理完毕回调方法afterCompletion  
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
// triggerAfterCompletion方法  
private void triggerAfterCompletion(HandlerExecutionChain mappedHandler, int interceptorIndex,  
            HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {  
        // 5、触发整个请求处理完毕回调方法afterCompletion (逆序从1.2中的预处理成功的索引处的拦截器执行)  
        if (mappedHandler != null) {  
            HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();  
            if (interceptors != null) {  
                for (int i = interceptorIndex; i >= 0; i--) {  
                    HandlerInterceptor interceptor = interceptors[i];  
                    try {  
                        interceptor.afterCompletion(request, response, mappedHandler.getHandler(), ex);  
                    }  
                    catch (Throwable ex2) {  
                        logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);  
                    }  
                }  
            }  
        }  
    }  
//性能监控
package cn.javass.chapter5.web.interceptor;  
public class StopWatchHandlerInterceptor extends HandlerInterceptorAdapter {  
    private NamedThreadLocal<Long>  startTimeThreadLocal =   
new NamedThreadLocal<Long>("StopWatch-StartTime");  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,   
Object handler) throws Exception {  
        long beginTime = System.currentTimeMillis();//1、开始时间  
        startTimeThreadLocal.set(beginTime);//线程绑定变量(该数据只有当前请求的线程可见)  
        return true;//继续流程  
    }  
      
    @Override  
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,   
Object handler, Exception ex) throws Exception {  
        long endTime = System.currentTimeMillis();//2、结束时间  
        long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)  
        long consumeTime = endTime - beginTime;//3、消耗的时间  
        if(consumeTime > 500) {//此处认为处理时间超过500毫秒的请求为慢请求  
            //TODO 记录到日志文件  
            System.out.println(  
String.format("%s consume %d millis", request.getRequestURI(), consumeTime));  
        }          
    }  
}  
//登录检测
@Override  
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,   
Object handler) throws Exception {  
    //1、请求到登录页面 放行  
    if(request.getServletPath().startsWith(loginUrl)) {  
        return true;  
    }  
          
    //2、TODO 比如退出、首页等页面无需登录,即此处要放行 允许游客的请求  
          
    //3、如果用户已经登录 放行    
    if(request.getSession().getAttribute("username") != null) {  
        //更好的实现方式的使用cookie  
        return true;  
    }  
          
    //4、非法请求 即这些请求需要登录后才能访问  
    //重定向到登录页面  
    response.sendRedirect(request.getContextPath() + loginUrl);  
    return false;  
}

 

分享到:
评论

相关推荐

    spring boot 登录拦截器

    在Spring Boot应用中,登录拦截器是一个至关重要的组件,它用于保护特定的Web资源,确保只有经过身份验证的用户才能访问。Spring Boot结合了Spring MVC框架,提供了方便的方式来实现这样的拦截器。本篇文章将深入...

    Flex-Spring拦截器

    在深入研究Flex-Spring拦截器时,理解Spring AOP的核心概念和AMF的工作原理是至关重要的。通过这样的集成,开发者可以在保持Flex客户端的灵活性和交互性的同时,利用Spring的强大功能来处理复杂的业务逻辑和系统管理...

    Spring拦截器示例

    而Spring拦截器则是实现AOP的一种方式,它类似于Java的Servlet过滤器,可以在方法调用前后执行自定义的操作。 AOP拦截器在Spring中主要通过`HandlerInterceptor`接口或者`@AspectJ`注解来实现。下面我们将详细探讨...

    spring拦截器的简单例子

    Spring 拦截器是 Spring 框架中一个非常重要的组件,主要用于处理请求和响应,实现业务逻辑之前和之后的预处理和后处理。它为开发者提供了在 MVC 模式下实现统一处理机制的机会,比如权限验证、日志记录、性能监控等...

    springmvc拦截器实现登录验证

    在本场景中,我们探讨的是如何利用拦截器来实现登录验证功能,确保只有经过身份验证的用户才能访问受保护的资源。 首先,我们需要了解Spring MVC的拦截器工作原理。拦截器链是由多个拦截器组成,每个拦截器都有`...

    struts2整合spring实现拦截器

    我们可以通过自定义拦截器来实现特定的功能,比如权限验证、日志记录等。在Struts2的配置文件中,我们可以注册这个拦截器: ```xml ``` 然后在Action类上声明需要使用的拦截器: ```xml ...

    springboot拦截器实现拦截器 权限校验,登录demo

    本文将详细介绍如何在Spring Boot中实现拦截器以进行权限校验和登录验证,通过一个简单的Demo来阐述整个过程。 首先,我们需要创建一个自定义的拦截器类。这个类通常会继承`HandlerInterceptorAdapter`,这是一个...

    spring MVC(新增拦截器demo)

    拦截器在Spring MVC中扮演着关键的角色,它们可以用来执行一些全局性的任务,如日志记录、权限验证、性能统计等,而不必在每个控制器方法中重复编写这些代码。接下来,我们将深入理解拦截器的工作原理和创建步骤。 ...

    企业级开发-SpringMVC使用拦截器实现用户登录权限验证实验报告.docx

    本实验报告将探讨如何利用 SpringMVC 的拦截器(Interceptor)来实现用户登录权限验证,确保只有已登录的用户才能访问特定的受保护资源。 首先,我们来看一下实验的基本步骤: 1. 创建 `User` 类:这是表示用户...

    springmvc(spring4版本)+自带登录和拦截器

    通过运行这个项目,你可以学习如何整合Spring MVC、Spring 4以及实现登录和拦截器功能,这对你理解Web应用开发的整个流程非常有帮助。同时,这个项目也适用于快速搭建一个具有基础认证功能的Web应用,是学习和实践...

    ssm+maven用拦截器实现登录小Demo

    在这个"ssm+maven用拦截器实现登录小Demo"中,我们将探讨如何利用SSM框架和Maven来构建一个简单的登录系统,并通过拦截器实现权限控制。 首先,Spring MVC中的拦截器(Interceptor)是一种预处理和后处理请求的机制...

    SpringMVC拦截器实现登录认证

    总的来说,SpringMVC拦截器是实现登录认证的强大工具,它可以与其他Spring组件无缝集成,提供灵活的控制和扩展性。通过理解其工作原理和配置方式,开发者可以更好地管理和保护Web应用程序的资源。

    Java SpringBoot实现的过滤器(和拦截器)控制登录页面跳转

    本项目主要关注的是如何使用过滤器(Filter)和拦截器(Interceptor)来实现登录页面的控制与跳转。以下是对这些知识点的详细说明: 1. **SpringBoot**: SpringBoot是Spring框架的一个子项目,旨在简化Spring应用...

    SSM+Ajax+maven+拦截器实现登录功能

    在这个项目中,我们将重点讨论如何利用SSM框架结合Ajax和Maven,以及使用拦截器来实现登录功能。 首先,**Spring**作为核心容器,管理着应用中的bean和依赖注入,提供了AOP(面向切面编程)和事务管理等功能。在...

    java + spring boot +jpa 拦截器分库分表demo

    在Spring Boot中注册拦截器,我们需要在配置类中使用`@EnableAspectJAutoProxy`开启AOP代理,并通过`@Bean`注解声明拦截器实例。然后,使用`@Around`注解定义切点,即拦截所有的JPA操作。 在实际开发中,为了使分库...

    spring-boot添加 拦截器

    本篇文章将详细探讨如何在Spring Boot中添加和使用拦截器来实现登录拦截。 首先,我们需要了解Spring Boot中的拦截器是如何工作的。在Spring MVC框架中,拦截器是基于AOP(面向切面编程)的概念实现的。我们可以...

    自己spring boot 拦截器

    总结起来,Spring Boot中的拦截器是增强应用程序功能的重要工具,通过实现或扩展拦截器接口,我们可以灵活地控制请求处理流程,实现自定义逻辑,如权限验证、日志记录等。在实际项目中,正确配置和使用拦截器能够...

    SpringBoot的拦截器

    在Spring Boot应用中,拦截器(Interceptor)是一个重要的组件,主要用于处理HTTP请求和响应,它在控制器(Controller)处理请求之前和之后进行拦截,可以实现如权限验证、日志记录、性能统计等功能。Spring Boot...

    SpringBoot拦截器实现对404和500等错误的拦截

    首先,创建自定义拦截器类并实现`HandlerInterceptor`接口是实现拦截器功能的第一步。如示例代码所示,我们需要创建一个名为`ErrorInterceptor`的类,并在其中实现`preHandle`和`postHandle`方法。这两个方法都是在...

    Spring AOP 拦截器 Advisor

    Spring AOP 拦截器 Advisor 是 Spring 框架中的一个重要概念,它与切面编程密切相关,用于实现细粒度的控制和增强应用程序的行为。在 Spring AOP 中,Advisor 是一个组合了通知(Advice)和切入点(Pointcut)的对象...

Global site tag (gtag.js) - Google Analytics