Filter、Interceptor、Aspect 区别及实现

Fliter 过滤器

请求在到达Controller之前进行与返回去之后 调用 入参为 reuqest,response,chian,过滤器获取不了具体调用哪一个类,哪一个方法。

实现:

1、继承 Filter 接口

import java.io.IOException;
import java.util.Date;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.stereotype.Component;

//@Component
public class TimeFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("TimeFilter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("TimeFilter in");
        long startTime = new Date().getTime();
        chain.doFilter(request, response);
        System.out.println("TimeFilter out 耗时:" + (new Date().getTime() - startTime));
    }

    @Override
    public void destroy() {
        System.out.println("TimeFilter destroy");
    }
}

2、声明:两种方式,一是在类前加入@Component ,不能指定拦截的路径;二是  对于SSM 在web.xml中进行声明,对于 SpringBoot 在webConfig中声明

web.xml

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

SpringBoot:

package com.maple.web.config;


import java.util.ArrayList;
import java.util.List;import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import com.maple.web.filter.TimeFilter;
import com.maple.web.interceptor.TimeInterceptor;

@Configuration
public class WebConfig{
@Bean public FilterRegistrationBean timeFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); TimeFilter timeFilter = new TimeFilter(); registrationBean.setFilter(timeFilter); List<String> url = new ArrayList<>(); url.add("/*"); registrationBean.setUrlPatterns(url); return registrationBean; } }

 

Interceptor 拦截器

请求在到达Controller之前进行与返回去之后 调用 入参为 reuqest,response,handler,在过滤器之后调用,能够知道调用哪一个类,但是获取不了参数

1、继承HandlerInterceptor ,perHandler 在进入Controller前执行,若返回false则不进入Controller ,true进入Controller ,postHandler处理完Controller后进入此方法,若发生异常,则不进入postHandler。afterCompletion 都会进入此方法,无论是否发生异常都会进入。

package com.maple.web.interceptor;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author hzc
 *
 */
@Component
public class TimeInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("preHandle");
        
        System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
        System.out.println(((HandlerMethod)handler).getMethod().getName());
        
        request.setAttribute("startTime", new Date().getTime());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
        long startTime = (long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗时: " + (new Date().getTime() - startTime));
        
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("afterCompletion");
        long startTime = (long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗时: " + (new Date().getTime() - startTime));
        System.out.println("ex is " + ex);
    }

}

2、声明,在SSM中需要在spring配置文件中声明,在Springboot中在Config中声明。

SSM:

<mvc:interceptors>  
      <!--   对公众用户进行拦截 -->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>  
          <!--   拦截所有路径   -->
            <bean id="userinterceptor" class="org.sz.source.schedul.common.BaseOrgUserInterceptor">   
                <property name="excludedUrls"><!-- 以下路径不拦截 -->
                   <list>
                       <value>/login.do</value>
                   </list>
                </property>
            </bean>
        </mvc:interceptor> 
</mvc:interceptors>

SpringBoot:

package com.maple.web.config;


import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{

    @Autowired 
    private TimeInterceptor timeInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }
}

Aspect 切面

使用切面,可前置增强,后置增强,环绕增强,在拦截器之后执行,可获取参数信息

1、编写切面方法类

import java.util.Date;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * @author hzc
 *
 */
@Aspect
@Component
public class TimeAspect {

    @Around("execution(* com.maple.web.controller.UserController.*(..))")
    public Object handlerControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("time aspect start");
        Object[] args = pjp.getArgs(); // 获取参数
        for (Object arg : args) {
            System.out.println("arg is " + arg);
        }
        long startTime = new Date().getTime();
        Object object = pjp.proceed();        
        System.out.println("time aspect 耗时: " + (new Date().getTime() - startTime));
        return object;
    }
}

 

Filter、Interceptor、Aspect的作用范围如下:

 

posted @ 2019-04-27 23:47  Topze  阅读(768)  评论(0编辑  收藏  举报