log4j2过滤器篇

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了log4j2过滤器篇相关的知识,希望对你有一定的参考价值。

参考技术A

简单来说,log4j2中的过滤器主要是对日志的输出进行过滤,符合条件的日志可以被当前过滤器通过,进入到后续的处理;不符合条件的日志应该被忽略,不做处理。这是比较常见的使用方式,文末的相关文章里对于过滤器的使用作出了较为详细的说明,这里主要总结一下个人的实践感悟。

MapFilter主要是对 MapMessage(log4j2框架中的类) 进行过滤,一般的日志信息,此过滤器不会处理,举例来说,专门处理类似以下方法中的参数。

分析与MapFilter几乎一致。 对于日志信息中的标记进行过滤 ,看一下 Logger 类的 info() 方法,如下:

特定的Marker标记的信息可以通过过滤,否则不会通过过滤(包括没有使用Marker)。

符合正则表达式的日志信息才会通过过滤器,看如下appender:

正则表达式 .* test .* 表示若干个任意字符(排除若干个,这里不做说明) + 空格 + test单词 + 空格 + 若干个任意字符。

例如: i an a test 是不符合要求的,因为test后面没有空格。

ASP.NET MVC学习之过滤器篇

http://www.cnblogs.com/yaozhenfa/p/asp_net_mvc_filter_1.html

一.前言

继前面四篇ASP.NET MVC的随笔,我们继续向下学习。上一节我们学习了关于控制器的使用,本节我们将要学习如何使用过滤器控制用户访问页面。

 

二.正文

以下的示例建立在ASP.NET MVC 4之上(VS2012)

 

1.授权过滤器

只要涉及用户的网站,都一定会涉及到什么权限的用户可以访问哪个页面。对于新手而言可能都在每个页面中单独写这个功能方法,导致的后果就是大量重复的代码,并且不便于以后的变动。有用一定经验之后,就会采用集中控制的方式,让所有的页面先执行特定的方法去判断,这样的优点就是减少了代码的重复,同时也能够灵活的配置。但是对于某些拥有特殊需求的页面就有点力所不能及,而且这种权限判断的代码会和页面的逻辑代码混为一体,难以区分。而今天介绍的授权过滤器是采用注解属性的方式去控制每个动作,并且可以灵活的配置。

 

首先我们在网站根目录新建一个Filter文件夹,在其中新建一个CustAuthorizeAttribute类,类中的具体代码如下所示

技术分享
 1 namespace MvcStudy.Filter
 2 {
 3     public class CustAuthorizeAttribute : AuthorizeAttribute
 4     {
 5         private string[] roles;
 6 
 7         public CustAuthorizeAttribute(params String[] role)
 8         {
 9             roles = role;
10         }
11 
12         protected override bool AuthorizeCore(HttpContextBase httpContext)
13         {
14             String role = httpContext.Request.QueryString["role"];
15             if (role != null)
16             {
17                 return roles.Contains(role);
18             }
19             return base.AuthorizeCore(httpContext);
20         }
21     }
22 }
技术分享

 

通过上面的代码我们知道这个过滤器将会在使用时要求使用者传入可以访问的角色有哪些,其中最终的是AuthorizeCore方法,该方法是负责判断当前的请求是有具有权限,这里我们为了演示,所以直接根据查询字符串的role的值来判断。

 

既然我们已经有了过滤器,下面我们新建一个Home控制器,并在Views下新建一个Home文件夹,同时在Home文件夹下新建名为Index的视图以及List的视图。接着我们打开Home控制器。

在其中写入如下代码

技术分享
 1 namespace MvcStudy.Controllers
 2 {
 3     public class HomeController : Controller
 4     {
 5         [CustAuthorize("vip")]
 6         public ActionResult Index()
 7         {
 8             return View();
 9         }
10 
11         [CustAuthorize("admin")]
12         public ActionResult List()
13         {
14             return View();
15         }
16     }
17 }
技术分享

 

 

我们可以看到笔者将Index动作规定为只有rolevip才能访问,而List则是admin。接着我们运行项目,浏览器会默认打开http://localhost:7575/(端口请根据实际情况而定),但是你会发现你将会被转移到http://localhost:7575/Account/Login?ReturnUrl=%2f这个页面,因为项目中我们并没有新建这个视图,所以会报404错误。而这个是被通过授权后ASP.NET MVC默认的行为,当然我们可以改变这个行为,下面我们来改变这个行为,让其直接跳转到Login视图,修改CustAuthorizeAttribute类。

代码如下所示:

技术分享
 1 namespace MvcStudy.Filter
 2 {
 3     public class CustAuthorizeAttribute : AuthorizeAttribute
 4     {
 5         private string[] roles;
 6 
 7         public CustAuthorizeAttribute(params String[] role)
 8         {
 9             roles = role;
10         }
11 
12         protected override bool AuthorizeCore(HttpContextBase httpContext)
13         {
14             String role = httpContext.Request.QueryString["role"];
15             if (role != null)
16             {
17                 return roles.Contains(role);
18             }
19             return base.AuthorizeCore(httpContext);
20         }
21 
22         protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
23         {
24             UrlHelper url = new UrlHelper(filterContext.RequestContext);
25             filterContext.Result = new RedirectResult("/Login");
26         }
27     }
28 }
技术分享

 

其中关键的是我们重写了HandleUnauthorizedRequest方法,这个方法只有在AuthorizeCore返回false情况才会调用,同时该方法的参数中有一个Result属性,该属性是将最终的处理结果赋给它。

 

重新编译,我们继续访问默认的路径,这个时候我们可以发现转移的路径已经变成了http://localhost:7575/Login,到这里我们已经可以处理授权失败的情况了,现在我们就要开始测试几个正确的结果首先是Index,我们只需要访问该路径即可http://localhost:7575/Home/Index?role=vip(同http://localhost:7575/?role=vip),如果要访问List,我们就需要访问这个路径http://localhost:7575/Home/List?role=admin,通过这个简单的例子,我们就可以知道在ASP.NET MVC中是通过何种方式去控制用户访问页面的权限。

 

2.异常过滤器

在我们的开发过程我们很多的时间都在修改异常,防止异常的发生。但是在实际的运行过程中总会发生很多我们未曾发现的问题,以及其他恶意的攻击。这个时候我们就需要一个统一的机制可以控制并处理这些异常,或许我一说到异常很多人都会联想到try{}catch{},的确没错,异常的捕获是用他们,但是你有没有想过,如果一个网站导出充斥着try{}catch{},不仅仅是不美观,同时也能以控制。而ASP.NET MVC为我们提供了异常过滤器,可以为每个动作添加这个注解属性,这样我们就可以灵活的控制并处理这些异常。

 

首先我们在Filter文件中新建一个CustExceptionAttribute类,并在其中写入如下的代码

技术分享
 1 namespace MvcStudy.Filter
 2 {
 3     public class CustExceptionAttribute : FilterAttribute , IExceptionFilter
 4     {
 5         public void OnException(ExceptionContext filterContext)
 6         {
 7             if (!filterContext.ExceptionHandled)
 8             {
 9                 filterContext.Result = new RedirectResult("error.html");
10                 filterContext.ExceptionHandled = true;
11             }
12         }
13     }
14 }
技术分享

 

我们可以看到这里我们依然还是用Result来将我们处理后的结果赋值给它,但是我们这里还判断了ExceptionHandled属性,这个属性的含义是如果其他的异常过滤器已经处理了该异常,则该属性的值为true,为了能够适应大的范围,所以笔者这里建议读者也要先判断是否已经有其他的异常过滤器已经处理过这个异常了。

 

下面我们在Home控制器中的Index动作中使用:

技术分享
 1 namespace MvcStudy.Controllers
 2 {
 3     public class HomeController : Controller
 4     {
 5         [CustException()]
 6         public ActionResult Index()
 7         {
 8             throw new NullReferenceException();
 9             return View();
10         }
11     }
12 }
技术分享

 

这个时候我们访问http://localhost:7575/将会跳转至http://localhost:7575/error.html页面(因为笔者没有建这个页面所以会显示404),但是读者可以看到这里我仅仅只是根据异常跳转到一个特定的页面,其实ASP.NET MVC中已经默认为我们实现了这个注解属性,这个注解属性就是HandleError类,我们只需要传入需要捕获的异常类型,以及对应的页面即可。

 

下面我们修改Home控制器的Index动作:

技术分享
 1 namespace MvcStudy.Controllers
 2 {
 3     public class HomeController : Controller
 4     {
 5         [HandleError(ExceptionType=typeof(NullReferenceException),View="error")]
 6         public ActionResult Index()
 7         {
 8             throw new NullReferenceException();
 9             return View();
10         }
11     }
12 }
技术分享

 

 

然后我们重新编译,并访问页面,会发现页面没有按照我们的预想跳转到特定的页面而是直接显示了错误的详情。这是因为ASP.NET MVC默认情况下没有开启自定义异常处理,所以就会出现这个默认的页面,下面我们修改Web.Config在其中添加如下的配置

技术分享

 

这时我们重新编译刷新页面,但是我们会发现页面会有内容,因为这个页面调用的是Views/Shared/Error.cshtml页面。

 

未完待续…

以上是关于log4j2过滤器篇的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 应用程序中未针对休眠和弹簧过滤 Log4j2 日志级别

如何将log4j StringMatchFilter转换为log4j2?

如果我们将它与slf4j api一起使用,我们可以使用log4j2的所有功能吗?

JavaWeb_Filter过滤器篇

JavaWeb_Filter过滤器篇

javaWeb--之--过滤器(filter)篇