Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 407|回复: 0

Mbp通过筛选器和中间件实现异常,日志,事务及接口返回数据格式化aop处理.

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-8-27 13:27:43 | 显示全部楼层 |阅读模式

    Mbp应用服务层的AOP实现

    实现方法:asp.net core mvc 筛选器 + 中间件

    日志,事务,和接口返回结果统一格式化采用操作筛选器,而异常处理采用中间件来处理.

    最开始,我是打算用autofac的高级特性的拦截器来做AOP的,但是遇到一个问题,poco controller没办法注入到autofac的容器里面.导致拦截器不能正常工作,所以就采用了筛选器来做.这里的场景有以下几个:

    • AOP是在应用层,而应用层是用poco controller做的,而在asp.net core web api的基架中,controller处在管线的末端.所以可以在这层进行全局拦截.
    • 中间件处理异常更加灵活,可以有更多的定制化需求,而异常筛选器是响应抓捕的异常来处理,它相当于是异常发生后的一个处理程序,而中间件可以来实现类似异常筛选器.
    • 中间件不短路,只是在程序运行的管线上添加了try catch,同时也解决了异步方法出现的异常无法被捕获的问题.

    实现代码

    • Mbp.AspNetCore.Filter 添加MbpLogFilter,MbpTransActionFilter,ResponseMiddleware三个操作筛选器
    • Mbp.AspNetCore.Middleware 添加MbpGlobaExceptionMiddleware中间件
    • 在模块MbpAspNetCoreModule中注册筛选器和中间件
    public override IServiceCollection AddServices(IServiceCollection services)
            {
                services.AddMvc().AddNewtonsoftJson(options =>
                {
                    // 忽略循环引用
                    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                    // 不使用驼峰
                    options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                    // 设置时间格式
                    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                }).AddMvcOptions(options =>
                {
                    // 禁用Version的绑定
                    options.ModelMetadataDetailsProviders.Add(new ExcludeBindingMetadataProvider(typeof(System.Version)));
    
                    // 统一事务处理中间件
                    options.Filters.Add(typeof(MbpTransActionFilter));
    
                    // 统一日志处理中间件
                    options.Filters.Add(typeof(MbpLogFilter));
    
                    // 请求响应统一格式处理中间件
                    options.Filters.Add(typeof(ResponseMiddleware));
    
                }); ;
    
                AddAutoWebApi(services, new AutoWebApiOptions());
    
                // 创建Cors策略
                services.AddCors(options =>
                {
                    options.AddPolicy("MbpCors",
                    builder =>
                    {
                        builder.WithOrigins(services.BuildServiceProvider().GetService<IConfiguration>().GetSection("AllowedHosts").Value)
                        .AllowAnyMethod()
                        .AllowAnyHeader(); ;
                    });
                });
    
                return base.AddServices(services);
            }
    
    public override void UseModule(IApplicationBuilder app)
            {
                // 启用跨域请求中间件
                app.UseCors("MbpCors");
    
                // 启用应用服务层全局错误处理中间件
                app.UseMiddleware(typeof(MbpGlobaExceptionMiddleware));
    
                base.UseModule(app);
            }
    

    异常中间件对并发冲突进行单独处理

     public async Task InvokeAsync(HttpContext context, ILogger<MbpGlobaExceptionMiddleware> logger)
            {
                try
                {
                    // Call the next delegate/middleware in the pipeline
                    await _next(context);
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    // 发生冲突时候,牺牲后者.不做具体数据合并操作.提示当前用户数据已经发生修改,需要重试.
                    logger.LogError("并发冲突:" + ex.Message);
    
                    context.Response.ContentType = "application/json";
    
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(new { Code = 500, Message = "提交并发冲突", Version = "1", Data = new List<object>() }));
                }
                catch (Exception ex)
                {
                    // 其他异常
                    logger.LogError($"请求[{context.Request.Path}]发生异常:" + ex.Message);
    
                    context.Response.ContentType = "application/json";
    
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(new { Code = 500, Message = "服务器异常", Version = "1", Data = new List<object>() }));
                }
            }
    

    代码详细地址:https://github.com/mbpframework/Mbp

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 09:08 , Processed in 0.059290 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表