NET Core 实现AOP Filter 的几种方式

本文详细介绍了ASP.NET Core中的五种过滤器:权限控制、资源、异常处理、动作及结果过滤器,并提供了每种过滤器的具体实现示例与应用场景。

Filter 主要有以下5种 分别是验证、资源、动作、异常捕获、结果。


1. Authorization  主要用于身份验证。

2.Resource  发生在控制器实例之前。

3、Action  发生在Action (事件 方法)  之前。(主要用于日记 )

4. Exception 主要是捕获异常.

5. Result Filter : 发生在视图替换环节

有以下五种Filter 可以使用: - Authorization Filter: Authorization是五种Filter中优先级最高的,通常用于验证Request合不合法,不合法后面就直接跳过。 - Resource Filter:Resource是第二优先,会在Authorization之后,Model Binding之前执行。通常会是需要对Model加工处理才用。 - Exception Filter:异常处理的Filter。 - Action Filter:最常使用的Filter,封包进出都会经过它,使用上没什么需要特别注意的。跟Resource Filter很类似,但并不会经过Model Binding。 - Result Filter:当Action完成后,最终会经过的Filter。

1 Authonization Filter

权限控制过滤器 通过 Authonization Filter 可以实现复杂的权限角色认证登陆授权等操作 实现事例代码如下:

public class AuthonizationFilter :Attribute,IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            //这里可以做复杂的权限控制操作
            if (context.HttpContext.User.Identity.Name != "1") //简单的做一个示范
            {
                //未通过验证则跳转到无权限提示页
                RedirectToActionResult content = new RedirectToActionResult("NoAuth", "Exception", null);
                context.Result = content;
            }
        }
    }

2 Resource Filter

资源过滤器 可以通过Resource Filter 进行资源缓存防盗链等操作。 使用Resource Filter 要求实现IResourceFilter 抽象接口

public class ResourceFilter : Attribute,IResourceFilter
    {
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            // 执行完后的操作
        }
 
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            // 执行中的过滤器管道
        }
    }

3 Exception Filter

通过Execption Filter 过滤器可以进行全局的异常日志收集 等操作。

public class ExecptionFilter : Attribute, IExceptionFilter
  {
        private ILogger<ExecptionFilter> _logger;
        //构造注入日志组件
        public ExecptionFilter(ILogger<ExecptionFilter> logger)
        {
            _logger = logger;
        }
 
        public void OnException(ExceptionContext context)
        {
            //日志收集
            _logger.LogError(context.Exception, context?.Exception?.Message??"异常");
        }
    }

4 Action Filter

作用:可以通过ActionFilter 拦截 每个执行的方法进行一系列的操作,比如:执行操作日志参数验证权限控制 等一系列操作。

使用Action Filter 需要实现IActionFilter 抽象接口,IActionFilter 接口要求实现OnActionExecuted 和OnActionExecuting 方法

public class ActionFilter : Attribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
            //执行完成....
        }
 
        public void OnActionExecuting(ActionExecutingContext context)
        {
            //执行中...
        }
    }

5 Result Filter

结果过滤器,可以对结果进行格式化、大小写转换等一系列操作。

public class ResultFilter : Attribute, IResultFilter
 {
        public void OnResultExecuted(ResultExecutedContext context)
        { 
            // 在结果执行之后调用的操作...
        }
 
        public void OnResultExecuting(ResultExecutingContext context)
        {
            // 在结果执行之前调用的一系列操作
        }
    }

过滤器的注册方式(使用方式)

1。 Action 注册方式:

[AuthonizationFilter()]
 public IActionResult Index()
 {
            return View();
 }

2 Controller 注册方式

[AuthonizationFilter()]
 public class FirstController : Controller
  {
        private ILogger<FirstController> _logger;
 
        public FirstController(ILogger<FirstController> logger)
        {
            _logger = logger;
        }
 
        public IActionResult Index()
        {
            return View();
        }
 }

3 全局注册方式

public void ConfigureServices(IServiceCollection services)
  {
            //全局注册异常过滤器
            services.AddControllersWithViews(option=> {
                option.Filters.Add<ExecptionFilter>();
            });
 
            services.AddSingleton<ISingletonService, SingletonService>();
}

4 TypeFilter 和 ServiceFilter 注册方式

public class ExecptionFilter : Attribute, IExceptionFilter
    {
        private ILogger<ExecptionFilter> _logger;
        //构造注入日志组件
        public ExecptionFilter(ILogger<ExecptionFilter> logger)
        {
            _logger = logger;
        }
 
        public void OnException(ExceptionContext context)
        {
            //日志收集
            _logger.LogError(context.Exception, context?.Exception?.Message??"异常");
        }
    }

TypeFilter 使用方式

   滤器中构造函数中存在参数,需用到TypeFilter

[TypeFilter(typeof(ExecptionFilter))]
public IActionFilter Index2()
{
      return View();
}

ServiceFilter 使用方式

控制器中的代码如下:

[ServiceFilter(typeof(ExecptionFilter))]
public IActionFilter Index2()
{
           return View();
}

注册服务的代码

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
       Console.WriteLine("ConfigureServices");
       services.AddControllersWithViews();
 
       //services.AddControllersWithViews(option=> {
       //    option.Filters.Add<ExecptionFilter>();
       //});
 
        //注册过滤器服务,使用ServiceFilter 方式必须要注册 否则会报没有注册该服务的相关异常
        services.AddSingleton<ExecptionFilter>();
}

<think>我们讨论的是Java中RestTemplate和WebClient的拦截方式种类。根据之前的知识和引用内容,我们可以总结如下:1.**RestTemplate的拦截方式**:-**ClientHttpRequestInterceptor**:这是RestTemplate提供的拦截器接口,允许我们在发送请求前和收到响应后执行自定义逻辑。我们可以通过实现该接口并添加到RestTemplate的拦截器链中。-**AOP(面向切面编程)**:我们可以使用SpringAOP来拦截RestTemplate的方法调用,例如在方法执行前后进行日志记录、性能监控等。2.**WebClient的拦截方式**:-**ExchangeFilterFunction**:这是WebClient提供的过滤器函数,类似于拦截器。我们可以通过定义ExchangeFilterFunction并将其添加到WebClient的过滤器链中,在请求发送前和响应处理前执行自定义逻辑。-**AOP(面向切面编程)**:同样,我们也可以使用AOP来拦截WebClient的方法调用,但由于WebClient是异步非阻塞的,使用AOP拦截其方法可能不如使用内置的ExchangeFilterFunction方便和直接。下面我们分别详细说明这两种客户端的不同拦截方式。###1.RestTemplate的拦截方式####方式一:使用ClientHttpRequestInterceptor这是RestTemplate内置的拦截机制。我们可以创建一个或多个拦截器,并将它们添加到RestTemplate中。每个拦截器都会在请求执行前后被调用。**示例代码:**```javaimportorg.springframework.http.HttpRequest;importorg.springframework.http.client.ClientHttpRequestExecution;importorg.springframework.http.client.ClientHttpRequestInterceptor;importorg.springframework.http.client.ClientHttpResponse;importjava.io.IOException;publicclassLoggingInterceptorimplementsClientHttpRequestInterceptor{@OverridepublicClientHttpResponseintercept(HttpRequestrequest,byte[]body,ClientHttpRequestExecutionexecution)throwsIOException{//在请求执行前的逻辑System.out.println("RequestURI:"+request.getURI());System.out.println("RequestMethod:"+request.getMethod());//执行请求ClientHttpResponseresponse=execution.execute(request,body);//在响应处理前的逻辑System.out.println("ResponseStatusCode:"+response.getStatusCode());returnresponse;}}```将拦截器添加到RestTemplate:```java@BeanpublicRestTemplaterestTemplate(){RestTemplaterestTemplate=newRestTemplate();restTemplate.getInterceptors().add(newLoggingInterceptor());returnrestTemplate;}```####方式二:使用AOP拦截我们可以定义一个切面,针对RestTemplate的方法进行拦截。这种方式可以拦截到RestTemplate的任意方法,比如`getForObject`、`postForEntity`等。**示例代码:**```javaimportorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.springframework.stereotype.Component;@Aspect@ComponentpublicclassRestTemplateAspect{@Around("execution(*org.springframework.web.client.RestTemplate.*(..))")publicObjectlogRestTemplateCall(ProceedingJoinPointjoinPoint)throwsThrowable{//方法执行前的逻辑System.out.println("BeforeRestTemplatemethod:"+joinPoint.getSignature().getName());Objectresult=joinPoint.proceed();//执行原方法//方法执行后的逻辑System.out.println("AfterRestTemplatemethod:"+joinPoint.getSignature().getName());returnresult;}}```###2.WebClient的拦截方式####方式一:使用ExchangeFilterFunctionWebClient使用过滤器链来处理请求。我们可以定义一个或多个ExchangeFilterFunction,并将其添加到WebClient中。**示例代码:**```javaimportorg.springframework.web.reactive.function.client.ExchangeFilterFunction;importreactor.core.publisher.Mono;publicclassLoggingFilter{publicstaticExchangeFilterFunctionlogRequest(){returnExchangeFilterFunction.ofRequestProcessor(clientRequest->{System.out.println("Request:"+clientRequest.method()+""+clientRequest.url());returnMono.just(clientRequest);});}publicstaticExchangeFilterFunctionlogResponse(){returnExchangeFilterFunction.ofResponseProcessor(clientResponse->{System.out.println("ResponseStatus:"+clientResponse.statusCode());returnMono.just(clientResponse);});}}```将过滤器添加到WebClient:```java@BeanpublicWebClientwebClient(){returnWebClient.builder().filter(LoggingFilter.logRequest()).filter(LoggingFilter.logResponse()).build();}```####方式二:使用AOP拦截同样,我们可以使用AOP来拦截WebClient的方法调用。但由于WebClient的方法返回的是Mono或Flux,我们需要特别注意异步处理。**示例代码:**```javaimportorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.springframework.stereotype.Component;@Aspect@ComponentpublicclassWebClientAspect{@Around("execution(*org.springframework.web.reactive.function.client.WebClient.*(..))")publicObjectlogWebClientCall(ProceedingJoinPointjoinPoint)throwsThrowable{//方法执行前的逻辑System.out.println("BeforeWebClientmethod:"+joinPoint.getSignature().getName());Objectresult=joinPoint.proceed();//执行原方法//注意:这里返回的可能是Mono或Flux,我们可以对它们进行日志记录,但不要阻塞returnresult;}}```###总结对比|客户端|拦截方式|特点||--------------|------------------------------|----------------------------------------------------------------------||RestTemplate|ClientHttpRequestInterceptor|同步拦截,直接操作请求和响应对象,简单易用。||RestTemplate|AOP|可以拦截任意方法,但可能对性能有影响,且需要处理同步调用。||WebClient|ExchangeFilterFunction|异步非阻塞,适合响应式编程,可以操作请求和响应的发布者。||WebClient|AOP|可以拦截任意方法,但由于异步特性,处理起来相对复杂,可能不直观。|###建议-对于RestTemplate,推荐使用`ClientHttpRequestInterceptor`,因为它专为同步HTTP请求设计,使用简单。-对于WebClient,推荐使用`ExchangeFilterFunction`,因为它与响应式编程模型紧密结合,可以非阻塞地处理请求和响应。###相关问题§§相关问题§§1.如何在RestTemplate的拦截器中修改请求头?2.在WebClient的过滤器中如何实现重试机制?3.使用AOP拦截RestTemplate时,如何避免对某些特定方法进行拦截?4.在WebClient的过滤器中如何读取和修改请求体?5.RestTemplate和WebClient在异常处理上有什么不同,如何在拦截中进行统一异常处理?</think>### Java中RestTemplate和WebClient拦截方式种类 在Java中,对RestTemplate和WebClient进行拦截主要通过以下两种核心方式实现: #### 一、RestTemplate拦截方式 1. **ClientHttpRequestInterceptor(内置拦截器)** RestTemplate原生支持的拦截机制,通过实现接口拦截HTTP请求/响应: ```java public class CustomInterceptor implements ClientHttpRequestInterceptor { @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { // 请求前逻辑(如修改header) request.getHeaders().add("X-Trace-ID", UUID.randomUUID().toString()); // 执行请求 ClientHttpResponse response = execution.execute(request, body); // 响应后逻辑(如日志记录) System.out.println("Response status: " + response.getStatusCode()); return response; } } // 注册拦截器 RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add(new CustomInterceptor()); ``` **特点**:直接操作请求/响应对象,同步阻塞模型[^2]。 2. **AOP(面向切面编程)** 通过Spring AOP拦截RestTemplate方法调用: ```java @Aspect @Component public class RestTemplateAspect { @Around("execution(* org.springframework.web.client.RestTemplate.*(..))") public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); Object result = joinPoint.proceed(); // 执行原方法 long duration = System.currentTimeMillis() - start; System.out.println("Method " + joinPoint.getSignature().getName() + " executed in " + duration + "ms"); return result; } } ``` **特点**:可拦截所有方法调用,适用于监控/日志等横切关注点[^2]。 --- #### 二、WebClient拦截方式 1. **ExchangeFilterFunction(内置过滤器)** WebClient原生支持的响应式拦截机制: ```java ExchangeFilterFunction logFilter = (request, next) -> { System.out.println("Request: " + request.method() + " " + request.url()); return next.exchange(request).doOnNext(response -> System.out.println("Response: " + response.statusCode()) ); }; WebClient client = WebClient.builder() .filter(logFilter) .build(); ``` **特点**:非阻塞异步模型,支持链式处理[^1]。 2. **AOP(面向切面编程)** 拦截WebClient构建过程或方法调用: ```java @Aspect @Component public class WebClientAspect { @Before("execution(* org.springframework.web.reactive.function.client.WebClient.*(..))") public void logWebClientCall(JoinPoint joinPoint) { System.out.println("WebClient method invoked: " + joinPoint.getSignature().getName()); } } ``` **特点**:适用于方法级拦截,但需注意异步特性(如Reactor的Mono/Flux)[^1]。 --- ### 核心对比总结 | 特性 | RestTemplate | WebClient | |---------------------|---------------------------------------|------------------------------------| | **拦截机制** | `ClientHttpRequestInterceptor` | `ExchangeFilterFunction` | | **编程模型** | 同步阻塞 | 异步非阻塞 | | **AOP适用性** | 方法级拦截简单 | 需处理响应式类型(Mono/Flux) | | **典型场景** | 传统应用/简单拦截 | 高并发/响应式系统 | | **请求修改能力** | 直接操作HttpRequest对象 | 通过ClientRequest.from()克隆修改 | > **最佳实践建议**: > - 优先使用原生拦截机制(`ClientHttpRequestInterceptor`/`ExchangeFilterFunction`)进行HTTP层拦截 > - AOP更适合业务层拦截(如统一日志、性能监控) > - WebClient拦截需配合Reactor操作符(如`doOnNext`, `doOnError`)处理异步流[^1][^3] ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值