Log4j&Filter&Listener

Log4j&Filter&Listener

日志管理


  • 背景

日志記錄是應(yīng)用程序運(yùn)行中必不可少的一部分蚂维。具有良好格式和完備信息的日志記錄可以在程序出現(xiàn)問(wèn)題時(shí)幫助開(kāi)發(fā)人員迅速地定位錯(cuò)誤的根源

  • Log4J的使用方法
    • 導(dǎo)入包log4j-1.2.17.jar
    • 在資源文件下面創(chuàng)建一個(gè)log4j.properties
    • 使用Java代碼實(shí)現(xiàn)日志的輸出
  • 日志的級(jí)別

Log4J建議只使用四個(gè)級(jí)別刮萌,優(yōu)先級(jí)從高到低分別是ERROR宙搬、WARN斤贰、INFODEBUG

  • 示例代碼
private static Logger logger = Logger.getLogger(ProductServlet.class)

protected void delete(HttpServletRequest req, HttpServletResponse resp) throws Exception {
  logger.debug("This is debug message.");
  logger.error("This is error message.");
  logger.info("This is info message.");
}
  • log4j.properties(必須要確保文件被放到classes目錄下)
### \u8BBE\u7F6E###
log4j.rootLogger = debug,stdout,D,E

### \u8F93\u51FA\u4FE1\u606F\u5230\u63A7\u5236\u62AC ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### \u8F93\u51FADEBUG \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
#log4j.appender.D.File = /logs/log.log
log4j.appender.D.Append = false
log4j.appender.D.Threshold = INFO 
log4j.appender.D.layout = org.apache.log4j.HTMLLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### \u8F93\u51FAERROR \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
#log4j.appender.E.File =/logs/error.log 
log4j.appender.E.Append = false
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]

過(guò)濾器概述


  • WEB中的過(guò)濾器

WEB組件淆珊,在Java中最小的組件就是一個(gè)類(雙向)

  • 特點(diǎn)

開(kāi)發(fā)人員可以實(shí)現(xiàn)用戶在訪問(wèn)某個(gè)目標(biāo)資源之前涮因,對(duì)訪問(wèn)的請(qǐng)求和響應(yīng)進(jìn)行攔截。

簡(jiǎn)單說(shuō)坷虑,就是可以實(shí)現(xiàn)Web容器對(duì)某個(gè)資源的訪問(wèn)前截獲進(jìn)行相關(guān)的處理甲馋,

還可以在某資源向Web容器返回響應(yīng)前進(jìn)行截獲處理

  • Web中過(guò)濾器存在的意義
    • DRY不要重復(fù)自己
    • 責(zé)任分類:各自做自己擅長(zhǎng)的事兒

過(guò)濾器操作和應(yīng)用場(chǎng)景

實(shí)現(xiàn)Web容器對(duì)某資源的訪問(wèn)前截獲進(jìn)行相關(guān)處理,還可以在某資源向Web容器返回響應(yīng)前進(jìn)行截獲處理

  • 過(guò)濾器能夠?qū)崿F(xiàn)的功能
    • 以常規(guī)的方式調(diào)用資源(訪問(wèn)servletJSP頁(yè)面)
    • 利用修改過(guò)的請(qǐng)求信息調(diào)用資源
    • 利用資源猖吴,但在發(fā)送響應(yīng)到瀏覽器之前對(duì)其進(jìn)行修改
    • 阻止該資源調(diào)用摔刁,取而代之的是跳轉(zhuǎn)到其他資源,返回一個(gè)特定的狀態(tài)碼
  • 應(yīng)用場(chǎng)景
    • 可以對(duì)客戶提交的數(shù)據(jù)進(jìn)行重新編碼req.setCharacterEndocing("UTF-8");
    • 使用瀏覽器不緩存頁(yè)面的過(guò)濾器
    • 可以過(guò)濾掉客戶的非法文字
    • 驗(yàn)證客戶是否已經(jīng)登錄
    • 請(qǐng)求分發(fā)器(類似structs2)
    • 頁(yè)面?zhèn)戊o態(tài)化處理(.jsp結(jié)尾的變成.html結(jié)尾)

Filter開(kāi)發(fā)和使用

  • Filter的開(kāi)發(fā)步驟
    • 創(chuàng)建一個(gè)類海蔽,實(shí)現(xiàn)Filter接口
    • 配置Filter(告訴Tomcat來(lái)管理Filter)
<filter>
  <filter-name>HelloFilter</filter-name>
  <filter-class>com.filter.HelloFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>HelloFilter</filter-name>
  <!-- 資源名稱共屈,指定要對(duì)那些資源進(jìn)行過(guò)濾 -->
  <url-pattern>/hello</url-pattern>
</filter-mapping>

Filter的細(xì)節(jié)處理

  • 可以使用注解來(lái)配置Filter

但是使用注解來(lái)配置過(guò)濾器,就無(wú)法控制哪個(gè)過(guò)濾器先執(zhí)行

  • FilterChainFilterConfig
String getFilterName() // 獲取<filter-name>中的內(nèi)容
String getInitParameter(String name) // 獲取Filter中的初始化參數(shù),解決硬編碼
Enumeration getInitParameterNames() 
ServletContext getServletContext() // 獲取當(dāng)前應(yīng)用對(duì)象
  • FilterCHain:過(guò)濾器鏈

注意:

對(duì)請(qǐng)求的攔截操作應(yīng)該在放行之前來(lái)實(shí)現(xiàn)

對(duì)響應(yīng)的攔截操作應(yīng)該在放行之后來(lái)實(shí)現(xiàn)

請(qǐng)求編碼過(guò)濾器

  • 示例代碼
// 對(duì)請(qǐng)求參數(shù)的編碼進(jìn)行設(shè)置
public class CharacterEncodeingFilter implements Filter {
  // 編碼
  private String encoding;
  // 判斷是否要強(qiáng)制使用web.xml中的編碼配置
  private boolean force;
  
  public void init(FilterConfig filterConfig) throws ServletException {
    encoding = filterConfig.getInitParameter("encoding");
    force = Boolean.valueOf(filterConfig.getInitParameter("force"));
  }
  
  protected void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
    // 設(shè)置請(qǐng)求參數(shù)的編碼方式
    // 通常在程序中需要給編碼一個(gè)默認(rèn)值党窜,在絕大多數(shù)情況下拗引,我們不對(duì)其進(jìn)行配置
    if (request.getCharacterEncoding() == null || force && StringUtils.hasLength(encoding)) {
      request.setCharacterEncoding(encoding);
    } else {
      // 設(shè)置默認(rèn)碼
      request.setCharacterEncoding("UTF-8");
    }
    chain.doFilter(request, response);
  }
}

登錄驗(yàn)證過(guò)濾器CheckLoginFilter

  • 示例代碼

LoginCheckFilter

public class LoginCheckFilter implements Filter {
  private String[] uris;
  private String contextPath;

  /**
   * Default constructor.
   */
  public LoginCheckFilter() {
      // TODO Auto-generated constructor stub
  }

  /**
   * @see Filter#destroy()
   */
  public void destroy() {
      // TODO Auto-generated method stub
  }

  /**
   * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
   */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          throws IOException, ServletException {
      HttpServletRequest req = (HttpServletRequest) request;
      HttpServletResponse resp = (HttpServletResponse) response;

      // String uri = req.getRequestURI().substring(1);
      String uri = req.getRequestURI();

      if (Arrays.asList(uris).contains(uri)) {
          chain.doFilter(req, resp);
      } else {
          Object user = req.getSession().getAttribute("USER_IN_SESSION");
          if (user == null) {
              // 說(shuō)明沒(méi)有登錄
              resp.sendRedirect(req.getContextPath() + "/login.jsp");
              return;
          }
          chain.doFilter(req, resp);
      }
  }

  /**
   * @see Filter#init(FilterConfig)
   */
  public void init(FilterConfig fConfig) throws ServletException {
      // 獲取不需要驗(yàn)證的資源名稱
      // login.jsp,login,randomCode
      String notCheck = fConfig.getInitParameter("NOTCHECK");
      contextPath = fConfig.getInitParameter("contextPath");
      uris = notCheck.split(",");
      for (int i = 0; i < uris.length; i++) {
          uris[i] = contextPath + "/" + uris[i];
      }
  }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    metadata-complete="false" version="3.0">

    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com._520.pps.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>force</param-name>
            <param-value>false</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>LoginCheckFilter</filter-name>
        <filter-class>com._520.pps.web.filter.LoginCheckFilter</filter-class>
        <init-param>
            <param-name>NOTCHECK</param-name>
            <param-value>login.jsp,login,randomCode</param-value>
        </init-param>
        <init-param>
            <param-name>contextPath</param-name>
            <param-value>/log4j-filter-listener</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>LoginCheckFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Listener(監(jiān)聽(tīng)器)


  • 在JavaWeb中的監(jiān)聽(tīng)器(對(duì)作用域?qū)ο蟮谋O(jiān)聽(tīng))
// 作用域?qū)ο蟮谋O(jiān)聽(tīng)
// request--ServletRequestListener
void requestDestroyed(ServletRequestEvent sre);
void requestinitialized(ServletRequestEvent sre);

// session--HttpSessionListener
void sessionCreated(HttpSessionEvent se);
void sessionDestroyed(HttpSessionEvent se);

// application--ServletContextListener
void contextDestroyed(ServletContextEvent sce);
void contextInitalized(ServletContextEvent sce);

// 當(dāng)服務(wù)器啟動(dòng)的時(shí)候執(zhí)行該方法
  • 在作用域中屬性監(jiān)聽(tīng)器(對(duì)作用域?qū)ο髮傩宰兓谋O(jiān)聽(tīng))
// ServletRequestAttributeListener
void attributeAdded(ServletRequestAttributeEvent srae);
void attributeRemoved(ServletRequestAttributeEvent srae);
void attributeReplaced(ServletRequestAttributeEvent srae);

// HttpSessionAttributeListener
void attributeAdded(HttpSessionBindingEvent se);
void attributeRemoved(HttpSessionBindingEvent se);
void attributeRepalced(HttpSessionBindingEvent se);

// ServletCOntextAttributeListener
void attributeAdded(ServletContextAttributeEvent scab);
void attributeRemoved(ServletContextAttributeEvent scab);
void attributeReplaced(ServletContextAttributeEvent scab);
  • 注冊(cè)監(jiān)聽(tīng)器
<listener>
  <listener-class></listener-class>
</listener>
  • 示例代碼
public class MySessionAttributeListener implements HttpSessionAttributeListener {
  @Override
  public void attributeAdded(HttpSessionBindingEvent se) {
    System.out.println("添加共享數(shù)據(jù)");
  }
  
  @Override
  public void attributeRemoved(HttpSessionBindingEvent se) {
    System.out.println("刪除共享數(shù)據(jù)");
  }
  
  @Override
  public void attributeReplaced(HttpSessionBindingEvent se) {
    System.out.println("修改共享數(shù)據(jù)");
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市幌衣,隨后出現(xiàn)的幾起案子矾削,更是在濱河造成了極大的恐慌壤玫,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哼凯,死亡現(xiàn)場(chǎng)離奇詭異欲间,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)断部,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門猎贴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蝴光,你說(shuō)我怎么就攤上這事她渴。” “怎么了蔑祟?”我有些...
    開(kāi)封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵趁耗,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我疆虚,道長(zhǎng)苛败,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任装蓬,我火速辦了婚禮著拭,結(jié)果婚禮上纱扭,老公的妹妹穿的比我還像新娘牍帚。我一直安慰自己,他們只是感情好乳蛾,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布暗赶。 她就那樣靜靜地躺著,像睡著了一般肃叶。 火紅的嫁衣襯著肌膚如雪蹂随。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天因惭,我揣著相機(jī)與錄音岳锁,去河邊找鬼。 笑死蹦魔,一個(gè)胖子當(dāng)著我的面吹牛激率,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播勿决,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼乒躺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了低缩?” 一聲冷哼從身側(cè)響起嘉冒,我...
    開(kāi)封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后讳推,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體顶籽,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年银觅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜕衡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡设拟,死狀恐怖慨仿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纳胧,我是刑警寧澤镰吆,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站跑慕,受9級(jí)特大地震影響万皿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜核行,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一牢硅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芝雪,春花似錦减余、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至堡牡,卻和暖如春抒抬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晤柄。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工擦剑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芥颈。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓惠勒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親浇借。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捉撮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)妇垢,斷路器巾遭,智...
    卡卡羅2017閱讀 134,716評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,867評(píng)論 6 342
  • Servlet過(guò)濾器是 Servlet 程序的一種特殊用法肉康,主要用來(lái)完成一些通用的操作,如編碼的過(guò)濾灼舍、判斷用戶的登...
    重山楊閱讀 1,239評(píng)論 0 12
  • 監(jiān)聽(tīng)器(listener) 監(jiān)聽(tīng)器簡(jiǎn)介 :監(jiān)聽(tīng)器就是一個(gè)實(shí)現(xiàn)特定接口的普通java程序吼和,這個(gè)程序?qū)iT用于監(jiān)聽(tīng)另一個(gè)...
    奮斗的老王閱讀 2,517評(píng)論 0 53
  • 本文包括:1、Filter簡(jiǎn)介2骑素、Filter是如何實(shí)現(xiàn)攔截的炫乓?3、Filter開(kāi)發(fā)入門4献丑、Filter的生命周期...
    廖少少閱讀 7,282評(píng)論 3 56