• ABP throw UserFriendlyException() 源码


    ABP  throw UserFriendlyException() ,会让前端弹出界面。

    实现的话,首先 throw UserFriendlyException()  并不会在后端产生真正的异常,否则就是500 错误了。

    ABP 的默认实现,是所有的请求,包裹在result { },里面,这个是ABP 封装的(可以去掉)

    这个是怎么在前端解析出来实际的响应内容呢?  前端有 abpHttpInterceptor.js  这在前端启动的时候注册的一个HttpInterceptor。

    里面有这个方法,来解析出来实际的 response.  这个Interceptor 会在发送请求的时候拦截,响应回来的时候拦截,也相当于一节管道了。

     1 AbpHttpConfiguration.prototype.handleAbpResponse = function (response, ajaxResponse) {
     2         var newResponse;
     3         if (ajaxResponse.success) {
     4             newResponse = response.clone({
     5                 body: ajaxResponse.result
     6             });
     7             if (ajaxResponse.targetUrl) {
     8                 this.handleTargetUrl(ajaxResponse.targetUrl);
     9                 ;
    10             }
    11         }
    12         else {
    13             newResponse = response.clone({
    14                 body: ajaxResponse.result
    15             });
    16             if (!ajaxResponse.error) {
    17                 ajaxResponse.error = this.defaultError;
    18             }
    19             this.logError(ajaxResponse.error);
    20             this.showError(ajaxResponse.error);
    21             if (response.status === 401) {
    22                 this.handleUnAuthorizedRequest(null, ajaxResponse.targetUrl);
    23             }
    24         }
    25         return newResponse;
    26     };

     再来看后端怎么实现的。

    后端有一个AbpMvcAuditFilter.cs  他的 一部分代码在这里。通过这儿,可以看出这里的Filter把  filterContext.Result 进行改动。我们也可以在这里加上一层。

    这里是Audit 的部分,原理类似。

                if (_auditingConfiguration.SaveReturnValues && filterContext.Result != null)
                {
                    switch (filterContext.Result)
                    {
                        case AbpJsonResult abpJsonResult:
                            if (abpJsonResult.Data is AjaxResponse ajaxResponse)
                            {
                                auditData.AuditInfo.ReturnValue = _auditSerializer.Serialize(ajaxResponse.Result);
                            }
                            else
                            {
                                auditData.AuditInfo.ReturnValue = _auditSerializer.Serialize(abpJsonResult.Data);
                            }
                            break;
    
                        case JsonResult jsonResult:
                            auditData.AuditInfo.ReturnValue = _auditSerializer.Serialize(jsonResult.Data);
                            break;
    
                        case ContentResult contentResult:
                            auditData.AuditInfo.ReturnValue = contentResult.Content;
                            break;
    
                    }
                }

     在  .Netcore api 中生成的 swagger 文档中,前端Angular 在拦截器中添加如下 处理

    return next.handle(req1).pipe(tap(() => { },
                (err: any) => {
                    if (err instanceof HttpErrorResponse) {
                        if (err.status !== 401) {
                            console.error(err.message);
                            return;
                        }
                        this.router.navigate(['login']);
                    }
                }));
    

      handle(req),执行的就是请求后端。 这里的返回是一个Observable 对象。可以pipe或者 subscribe().

    pipe里可以有一些 operator.  也就是一些方法。 scan()是一个累加器,会接受一个一个的值,然后把这些值一个一个的算出一个结果来,也就是会记住历史,累计历史。

    他的初始值是一个参数:seed.

    https://stackblitz.com/edit/dcm2d1?file=index.ts

    下面的代码,说明了merge和contact的差别

    import { merge, interval, concat } from 'rxjs';
    import { take, tap } from 'rxjs/operators';
    
    const timer1 = interval(1000).pipe(tap(t=>console.log('timer1')),take(3));
    const timer2 = interval(2000).pipe(tap(t=>console.log('timer2')));
    const timer3 = interval(500).pipe(tap(t=>console.log('timer3')));
    const concurrent = 2; // the argument
    const merged = merge(timer1, timer2, timer3); // 可以替换为 contact 看看
    merged.subscribe(x => console.log(x));
    气功波(18037675651)
  • 相关阅读:
    springboot 整合Elasticsearch
    SpringBoot 使用AOP记录接口访问日志
    Java8 Collectors类的静态工厂方法
    Java8 Stream流方法
    Java8 Lambda表达式
    Java通过行为参数化传递代码
    springboot使用SpringTask实现定时任务
    Cron表达式
    springboot整合swagger-ui
    springboot整合redis
  • 原文地址:https://www.cnblogs.com/qgbo/p/13267531.html
Copyright © 2020-2023  润新知