日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

SpringBoot 共有三種攔截http請求方式Filter,interceptor和aop。

1、FIlter

使用Filter的時候需要在Application啟動類上加入@ServletComponentScan注解

import JAVAx.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
 * 在SpringBoot中通過注解注冊的方式簡單的使用Filter
 * @author rayfoo
 */
@WebFilter(urlPatterns = "/*", filterName = "MyFilter")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilter  Filter初始化中");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("MyFilter  開始進行過濾處理");
        //調(diào)用該方法后,表示過濾器經(jīng)過原來的url請求處理方法
        chain.doFilter(request, response);
        System.out.println("MyFilter  處理后的操作");
    }

    @Override
    public void destroy() {
        System.out.println("MyFilter  Filter銷毀中");
    }
}

上述代碼中,重寫了Filter的三個方法,分別是:

init:在此Filter被創(chuàng)建時執(zhí)行

doFilter:處理Filter的真正業(yè)務邏輯,可以在這個方法中對請求進行放行,在放行前后都可以執(zhí)行代碼,也可以在此方法中進行重定向和請求轉發(fā),但是一旦使用了請求轉發(fā)、重定向,拋出異常,出現(xiàn)異常,被攔截的路徑對應的業(yè)務方法就不會被執(zhí)行。

destory:在此FIlter被銷毀時執(zhí)行

2、Interceptor

Interceptor依賴于web框架,我們經(jīng)常在Spring MVC中用到該配置,在這個場景下Interceptor 就依賴于SpringMVC框架。

使用Interceptor之前要先創(chuàng)建類并實現(xiàn)HandlerInterceptor接口

import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class MyInterceptor implements HandlerInterceptor {
    /**
     * 在業(yè)務處理器處理請求之前被調(diào)用。預處理,可以進行編碼、安全控制、權限校驗等處理
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor  方法執(zhí)行之前...");
        return true;
    }

    /**
     * 在業(yè)務處理器處理請求執(zhí)行完成后,生成視圖之前執(zhí)行。后處理(調(diào)用了Service并返回ModelAndView,但未進行頁面渲染),有機會修改ModelAndView
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor  回調(diào)操作...");
    }

    /**
     * 在DispatcherServlet完全處理完請求后被調(diào)用,可用于清理資源等。返回處理(已經(jīng)渲染了頁面)
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("MyInterceptor  方法執(zhí)行之后...");
    }
}

創(chuàng)建完實現(xiàn)類還需要注冊Interceptor

在SpringBoot2中,建議使用的注冊攔截器的方法有如下兩種:

1)實現(xiàn)WebMvcConfigurer接口

2)繼承WebMvcConfigurerAdapter類(此類也是實現(xiàn)了WebMvcConfigurer)

下面介紹一下實現(xiàn)WebMvcConfigurer方法注冊攔截器

import com.xa.filter.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //1.得到自定義的攔截器
        InterceptorRegistration interceptor = registry.addInterceptor(new MyInterceptor());
        //2.需要攔截的路徑 /**所有資源都攔截
        interceptor.addPathPatterns("/**");
        //3.設置不攔截的路徑 (登錄頁需要的和靜態(tài)資源)
        interceptor.excludePathPatterns("/","/index.html","/login","/css/**","/img/**","/js/**");
    }
}

3、AOP

使用AOP首先要引入jar包

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
     <version>2.1.1.RELEASE</version>
 </dependency>

定義切面


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Aspect
@Component
@Order(1) //指定切面類執(zhí)行順序,數(shù)字越小越先執(zhí)行
public class MyAspect {
    /**
     * 定義那個包下的執(zhí)行 面向切換
     * 該示例 實現(xiàn) 所有controller 包下的方法執(zhí)行的切面
  	 * 第一個*含義是:代表所有類型的返回值
		 * 第二個*是代表com.mall.web.controller包下的所有類
		 * 第三個是類下的所有方法,括號中兩個點表示任意個形參
	*/
    @Pointcut("execution(public * com.*.controller.*.*(..))")
    public void webLog(){}

    /**
     * 請求之前 進入控制之前 執(zhí)行,但是在攔截器之后執(zhí)行
     * @param joinPoint
     * @throws Throwable
     */
    @Before("webLog()")
    public void deBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到請求,記錄請求內(nèi)容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 記錄下請求內(nèi)容
        System.out.println("MyAspect  URL : " + request.getRequestURL().toString());
        System.out.println("MyAspect  HTTP_METHOD : " + request.getMethod());
        System.out.println("MyAspect  IP : " + request.getRemoteAddr());
        System.out.println("MyAspect  CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        System.out.println("MyAspect  ARGS : " + Arrays.toString(joinPoint.getArgs()));


    }

    /**
     * 控制器執(zhí)行之后執(zhí)行,得到控制器方法的返回值
     * @param ret
     * @throws Throwable
     */
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 處理完請求,返回內(nèi)容
        System.out.println("MyAspect  方法的返回值 : " + ret);
    }

    //后置異常通知
    @AfterThrowing("webLog()")
    public void throwss(JoinPoint jp){
        System.out.println("MyAspect  方法異常時執(zhí)行.....");
    }

    //后置最終通知,final增強,不管是拋出異?;蛘哒M顺龆紩?zhí)行
    @After("webLog()")
    public void after(JoinPoint jp){
        System.out.println("MyAspect  方法最后執(zhí)行.....");
    }

    //環(huán)繞通知,環(huán)繞增強,相當于 請求方法的攔截器
    @Around("webLog()")
    public Object arround(ProceedingJoinPoint pjp) {
        System.out.println("MyAspect  方法環(huán)繞start....."); // 最先執(zhí)行
        try {
            Object o =  pjp.proceed();
            System.out.println("MyAspect  方法環(huán)繞proceed,結果是 :" + o); // 最后執(zhí)行
            return o;
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }
}

我們新增個Controller來測試下他們的運行順序

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class DemoController {

    @GetMapping("/demo")
    public Map test() {
        Map map = new HashMap() ;
        map.put("a","123") ;
        return map ;
    }
}

我們訪問http://localhost:{port}/demo可以看到后臺打印如下日志

 

springboot三種攔截器

 

可以看出他們的攔截順序:filter—>Interceptor—->@Aspect 。以下這個圖可以比較直觀看出他們之間的攔截順序

springboot三種攔截器

 

總結: 過濾器和攔截器的區(qū)別,過濾器是依賴于servlet容器(struts),在實現(xiàn)上基于函數(shù)回調(diào),可以對幾乎所有的請求進行過濾。但缺點是一個過濾器實例只能在容器初始化時調(diào)用一次,來進行過濾操作,獲得我們想要的數(shù)據(jù)。

三者之間主要還是粒度的差異,應用場景的不同。

過濾器(Filter) :采用filter過濾器,可以獲取http、http請求和響應,但無法獲取與spring框架相關的信息,如哪個control處理,哪個方法處理,有哪些參數(shù),這些都是無法獲取的。

攔截器(Interceptor):采用interceptor攔截器,除了獲取http、http請求和響應對象,還可以獲取請求的類名、方法名,但攔截器無法獲取請求參數(shù)的值。

切片 (Aspect) : 切片 aspect 可以獲取傳入的參數(shù)值,但無法獲取原始的http,http請求和響應對象。

分享到:
標簽:springboot
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定