log4j使用详解--创建自己的日志系统

Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输出地;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。那么是不是这样,我们就可以完全使用log4j,而不需要扩展定制了呢?

1、基本介绍Log4j

  Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输出地;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

  log4j的好处在于:

  1) 通过修改配置文件,就可以决定log信息的目的地——控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等

  2) 通过修改配置文件,可以定义每一条日志信息的级别,从而控制是否输出。在系统开发阶段可以打印详细的log信息以跟踪系统运行情况,而在系统稳定后可以关闭log输出,从而在能跟踪系统运行情况的同时,又减少了垃圾代码(System.out.println(......)等)。

  3) 使用log4j,需要整个系统有一个统一的log机制,有利于系统的规划。

  那么是不是这样,我们就可以完全使用log4j,而不需要扩展定制了呢?当然不是这样,因为每个项目的需求不一样,而且log4j本身也提供了灵活的扩展机制。下面我们说说log4j常用的扩展方式。

2、扩展点Log4j

2.1 自己的日志系统

  每一个项目都想有自己的一套日志系统,而不受其他项目、jar包的影响。所以日志系统需要独立存在,且有相应的自己单独的配置文件而不受影响。我们先来看看common-logging和log4j的默认工作流程:

  common-logging

  当我们用Log log = LogFactory.getLog(“loggerName”);取得log时,让我们看看他是如何工作的?
  1)、首先在classpath下寻找自己的配置文件commons-logging.properties,如果找到,则使用其中定义的Log实现类
  2)、如果找不到commons-logging.properties文件,则在查找是否已定义系统环境变量org.apache.commons.logging.Log,找到则使用其定义的Log实现类
  3)、查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类
  4)、使用JDK自身的日志实现类(JDK1.4以后才有日志实现类)
  5)、使用commons-logging自己提供的一个简单的日志实现类SimpleLog

  commons-logging总是能找到一个日志实现类,并且尽可能找到一个"最合适"的日志实现类.
  .可以不需要配置文件
    .自动判断有没有Log4j包,有则自动使用之
    .最悲观的情况下也总能保证提供一个日志实现(SimpleLog)

  log4j

  当我们用Logger.getLogger(loggerName);取得log时,让我们看看他是如何工作的?
  1)、查找是否已定义系统环境变量log4j.configuration,找到则使用其定义的Log配置文件;否则搜索log4j.xml,如果存在,则执行4)
  2)、如果不存在,搜索log4j.properties
  3)、如果不存在,则使用程序默认的日志仓库
  4)、如果存在,注册配置日志仓库
  5)、去日志仓库中查询,如果不存在,则new一个
 
  从上面我们可以看到无论是common-logging还是log4j,以及其他的日志开源系统都会提供一套默认的遍历规则,去搜索他的log记录实例。一般情况下,我们都会使用它的默认规则,但是这样的话,我们就会受制于它,比如如果有人在默认规则中改变了某一个条件。
如果我们不想使用它的默认规则,该怎么办?很简单,在log4j中是通过日志仓库来维护一套独立日志系统,只要我们直接使用它的日志仓库,写一个我们自己的日志工厂就可以了。具体如下:

Public final class CustomLogFactory {
 //日志仓库实例
 Static LoggerRepository h = new Hierarchy(new RootLogger(Level.DEBUG));

 Static {
  //配置文件定制日志仓库属性,这里面你可以做更多的文章
  //来定义自己的配置文件位置等等
  new PropertyConfigurator().configure(h, urlConfigFile);
 }

 public static Logger getLogger(String loggerName) {
  return h.getLogger(loggerName);
 }
}

  这样你的日志系统完全独立了。是不是很容易?

2.2 自己的日志记录器

  Log4j的logger本身提供八种级别的日志记录,如果你想让你的logger没有级别概念,或者让日志信息支持国际化,那该怎么办?

  Log4j用于第三方扩展的记录日志方法API

public boolean isEnabledFor(Priority level);
public void log(String callerFQCN, Priority level, Object message, Throwable t);

  扩展示例

  1)、没有级别概念

Public final class CustomLogger {
 //log4j日志记录器
 Logger log4j;
 
 //自己的FQCN
 Private static final String FQCN = CustomLogger.class.getName();
 
 //构造方法
 Private CustomLogger(String loggerName) {
  log4j = CustomLogFactory.getLogger(loggerName);
 }
 
 //工厂方法
 Public static CustomLogger getLogger(String loggerName) {
  Return new CustomLogger(loggerName);
 }
 
 Public Boolean isEntryEnabled() {
  Return log4j. isEnabledFor(Level.INFO);
 }

 //程序入口日志
 //你完全可以在message上做些手脚,加上一些自己的特殊的日志信息
 //当然你也可以后面介绍的Appender的时候加
 Public void entry(String message, Throwable t) {
  Log4j.log(FQCN , Level.INFO, message, t);
 }
 
 Public Boolean isExitEnabled() {
  Return log4j. isEnabledFor(Level.INFO);
 }

 //程序结束日志
 Public void exit(String message, Throwable t) {
  Log4j.log(FQCN , Level.INFO, message, t);
 }
}

  2)、支持国际化

  主要是在message取得上做点事情。就像上面那个Public void entry(String message, Throwable t);如果你把API改为Public void entry(String messageID, Throwable t);实现改为:

Public void entry(String messageID, Throwable t) {
 Log4j.log(FQCN , Level.INFO, getMessage(messageID), t);
}

//取得相应的国际化信息
Private String getMessage(String messageID) {
 Return InternalResource.getLogMessage(messageID, Locale.getDefault());
}

2.3 自己的日志输出地

  Log4j本身提供了大量的默认Appender实现,已经能很好的解决大部分应用,但是有时候我们还是有一些自己的需要,比如只有在输出到控制台Appender时加一个运行时才能确定的固定前缀。我们可以这么写:

public final class CustomConsoleAppender extends org.apache.log4j.ConsoleAppender {
 
 @Override
 protected void subAppend(LoggingEvent event) {
  StringBuffer msgBuf = new StringBuffer();
 
  //固定前缀
  msgBuf.append('[');
  msgBuf.append(Manager.current ().getName());
  msgBuf.append(']');
 
  //根据配置文件中的格式化信息格式化event
  msgBuf.append(this.layout.format(event));
  this.qw.write(msgBuf.toString());
  ……
 }
}

  也就是我们想定制某一种日志输出地,直接继承相应的log4j中的类似的Appender,然后复写相应的方法即可。最后在配置文件中使用自己定义的Appender类就行了。

2.4 自己的日志过滤器

  Log4j的日志输出控制级别比较中有一个缺陷就是只能大于某个级别时才能输出,没有小于某个级别时才输出的控制,当然一般不会用到,如果有类似这样的需求是不是就做不到了呢?不是的,这时候你可以使用日志过滤器来实现。比如有这样一个需求,输出到控制台的日志信息,当级别小于WARN时,用System.out;当大于等于WARN时,用System.err。

  过滤器定义如下:

public final class CustomWarnLevelFilter extends org.apache.log4j.spi.Filter {
 @Override
 public int decide(LoggingEvent event) {
  //大于等于WARN的日志不允许输出
  if(event.getLevel().toInt() >= Level. WARN.toInt()) {
   return DENY;
  } else {
   return ACCEPT;
  }
 }
}

 
  配置文件中可以这样配置:

<appender class="com.primeton.ext.common.log.EOSConsoleAppender" name="CONSOLE_OUT">
 <param name="Target" value="System.out"/>
 <layout class="org.apache.log4j.PatternLayout">
  <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%p][%C][Line:%L] %m%n"/>
 </layout>
 <filter class=" CustomWarnLevelFilter "/>
</appender>
 
<appender class="com.primeton.ext.common.log.EOSConsoleAppender" name="CONSOLE_ERR">
 <param name="Target" value="System.err"/>
 <param name="Threshold" value="WARN"/>
 <layout class="org.apache.log4j.PatternLayout">
  <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%p][%C][Line:%L] %m%n"/>
 </layout>
</appender>
 
<root>
 <level value="DEBUG"/>
 <appender-ref ref="CONSOLE_OUT"/>
 <appender-ref ref="CONSOLE_ERR"/>
</root>

   因为log4j设计的灵活性,所以当然也有其他的方式来达到这个目的。

  上面简单介绍了对log4j常用的扩展方式,你还可以扩展像layout、errorhandler等等,这里不再赘述。

3、性能影响因素Log4j

  Log4j一直被人所诟病的也就是它的性能问题了,所以在这里简要的说明一下使用log4j的注意事项:
  1)、如果你的日志实例的名称不是经常变化,请将它定义为static变量。
  2)、如果你的message构造很复杂,那么在构造之前,请先使用isXXXEnabled()判断。
  3)、配置文件中格式控制如果不需要,尽量不要输出类名和行号。
  4)、根据log4j的级别判断控制流程,在配置文件中尽可能配置的比较细致。
    Logger.info(message)的比较流程:
    a. 比较日志仓库的threashold
    b. 与自身的有效Level(没有则是父亲的)比较
    c. 与Appender的threashold比较
    d. 询问Appender的filter
    e. Layout格式化
    f. 记录日志
  5)、如果Appender是文件类型,请不要把文件大小设的太小。至少设为10MB(<param name="MaxFileSize" value="10MB"/>)。
  6)、如果不是即时调试程序,把你的级别设定为高级别,最好是threshold=INFO之上。
  7)、如果不是想即时看到日志信息,你也可以把Appender的ImmediateFlush 设为false(<param name="ImmediateFlush" value="false"/>)。
 
4、附录

4.1 Log4j基本概念

  Log4j体系结构图


  日志仓库(或者容器)loggerRepository:跟一个配置文件相对应,顾名思义,里面存放着日志实例。
  1)、属性:threashold(阈值)
  2)、默认实现:org.apache.log4j.Hierarchy
  3)、日志系统━日志仓库━配置文件

 

  日志记录器:根日志和子日志(继承的概念,用“.”来区分,日志名称的重要性)
  1)、的概念(用于第三方封装和继承)FQCN
  2)、属性:level, appender, additivity(是否继承父日志的appender)

  Level:日志级别

  Appender:日志输出端
  属性:threashold(阈值),filter,Layout,Filter,ErrorHandler

  Layout:布局(输出格式)


  Filter:过滤器

查看更多精彩图片

  ErrorHandler:错误处理器   
查看更多精彩图片
 

4.2   Log4j配置文件详细说明(*.properties和*.xml)

4.2.1   属性文件Properties
 

properties 属性文件
编号
配置项
配置项描述
示例
1
log4j.threshold
阈值项
log4j.threshold = error
2
log4j.rootLogger
根日志属性项
log4j.rootLogger = info,stdout1,stdout2
3
log4j.category.
子日志属性项(旧)
log4j.category.com.eos = NULL,stdout1
4
log4j.logger.
子日志属性项(新)
log4j.logger.com.eos.log = debug,stdout2
5
log4j.additivity.
appender是否继承设置
log4j.additivity.com.eos = false
6
log4j.appender.
输出目的地定义项
log4j.appender.stdout2 = org.apache.log4j.ConsoleAppender
7
log4j.appender.A.layout
输出格式定义项
log4j.appender.stdout2.layout = org.apache.log4j.PatternLayout
 
4.2.2   文件xml
 
xml 文件
编号
配置项
配置项描述
示例
1
threshold
阈值项
<log4j:configuration xmlns:log4j=" http://jakarta.apache.org/log4j/" debug="false" threshold="null">
2
root
根日志属性项
<root>
    <priority value="info"/>
     <appender-ref ref="CONSOLE"/>
   </root>
3
priority
级别项(旧)
<priority value="info"/>
4
level
级别项(新)
<level value="info"/>
5
category
子日志属性项(旧)
<category additivity="true" name="com.eos.log">
6
logger
子日志属性项(新)
<logger additivity="true" name="com.eos">
7
appender-ref
输出端控制项
<appender-ref ref="CONSOLE"/>
8
additivity
appender是否继承设置
<logger additivity="true" name="com.eos">
9
appender
输出目的地定义项
<appender class="org.apache.log4j.ConsoleAppender" name="CONSOLE">
10
layout
输出格式定义项
<layout class="org.apache.log4j.PatternLayout">

 

 
4.2.3   详细说明(只针对Log4j常用的,用户可以自定义)Appender

  Appender继承关系

  Appender基本种类

  org.apache.log4j.ConsoleAppender(控制台)
  org.apache.log4j.FileAppender(文件)
  org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
  org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
  org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

  · ConsoleAppender选项

  Threshold=WARN:指定日志消息的输出最低层次。
  ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
  Target=System.err:默认情况下是:System.out,指定输出控制台

  · FileAppender 选项

  Threshold=WARN:指定日志消息的输出最低层次。
  ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
  File=mylog.txt:指定消息输出到mylog.txt文件。
  Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。

  · DailyRollingFileAppender 选项

  Threshold=WARN:指定日志消息的输出最低层次。
  ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
  File=mylog.txt:指定消息输出到mylog.txt文件。
  Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
  DatePattern='.'yyyy-ww:每周滚动一次文件,即每周产生一个新的文件。当然也可以指定按月、周、天、时和分。即对应的格式如下:
  1)'.'yyyy-MM: 每月
  2)'.'yyyy-ww: 每周
  3)'.'yyyy-MM-dd: 每天
  4)'.'yyyy-MM-dd-a: 每天两次
  5)'.'yyyy-MM-dd-HH: 每小时
  6)'.'yyyy-MM-dd-HH-mm: 每分钟
  n RollingFileAppender 选项
  Threshold=WARN:指定日志消息的输出最低层次。
  ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
  File=mylog.txt:指定消息输出到mylog.txt文件。
  Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
  MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件。
  MaxBackupIndex=2:指定可以产生的滚动文件的最大数。

4.2.4   详细说明(只针对Log4j,用户可以自定义)Layout

  Log4j的Layout基本种类

  org.apache.log4j.HTMLLayout(以HTML表格形式布局),
  org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
  org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
  org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

  · HTMLLayout选项

  LocationInfo=true:默认值是false,输出java文件名称和行号
  Title=my app file: 默认值是 Log4J Log Messages.      
  n PatternLayout 选项
  log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n
  这里需要说明的就是日志信息格式中几个符号所代表的含义:
   %X: 信息输出时左对齐;
  %p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
  %d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
  %r: 输出自应用启动到输出该log信息耗费的毫秒数
  %c: 输出日志信息所属的类目,通常就是所在类的全名
  %t: 输出产生该日志事件的线程名
  %l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
  %x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
  %%: 输出一个"%"字符
  %F: 输出日志消息产生时所在的文件名称
  %L: 输出代码中的行号
  %m: 输出代码中指定的消息,产生的日志具体信息
  %n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行,可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如:
  1)%20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。
  2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。
  3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。
  4)%20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符, 就从左边交远销出的字符截掉。

  · XMLLayout 选项

  LocationInfo=true:默认值是false,输出java文件和行号

4.3   日志配置文件内容范例

4.3.1   log4j.properties

log4j.rootLogger=DEBUG, CONSOLE
#DEBUG, CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE

log4j.logger.org.apache=INFO, FILE
log4j.additivity.org.apache=false

###################
# Console Appender
###################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d [%p] - %m%n


#####################
# File Appender
#####################
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d [%p] - %m%n


########################
# Rolling File
########################
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=%d [%p] - %m%n


####################
# Socket Appender
####################
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=%d [%p] - %m%n


########################
# Log Factor 5 Appender
########################
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000


########################
# SMTP Appender
#######################
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=yourname@domain.com
log4j.appender.MAIL.SMTPHost=mail.primeton.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=test@domain.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=%d [%p] - %m%n


########################
# JDBC Appender
#######################
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES (%d [%p] - %m%n)
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=%d [%p] - %m%n


log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

###################
#自定义Appender
###################
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender

log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = yourname@domain.com

log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =%d [%p] - %m%n

  #注意:在属性配置文件中,属性值的第一个一定是级别,输出端可有可无,以逗号分割。(而xml文件格式没有这种限制)

4.3.2   log4j.xml

< xml version="1.0" encoding="UTF-8" >
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false" threshold="null">


<appender class="org.apache.log4j.ConsoleAppender" name="CONSOLE">
<param name="Target" value="System.out"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%p] - %m%n "/>
</layout>
<filter class="org.apache.log4j.varia.DenyAllFilter"/>
<errorHandler class="org.apache.log4j.varia. FallbackErrorHandler"/>
</appender>

<appender class="org.apache.log4j.FileAppender" name="FILE">
<param name="File" value="file.log"/>
<param name="Append" value="false"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%p] - %m%n "/>
</layout>
</appender>

<appender class="org.apache.log4j.RollingFileAppender" name="ROLLING_FILE">
<param name="Threshold" value="INFO"/>
<param name="File" value="rolling.log"/>
<param name="Append" value="false"/>
<param name="MaxFileSize" value="10KB"/>
<param name="MaxBackupIndex" value="1"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%p] - %m%n "/>
</layout>
</appender>

<logger additivity="false" name="com.eos">
<level value="info"/>
<appender-ref ref="CONSOLE"/>
</logger>

<category additivity="true" name="com.eos.log">
<priority value="warn"/>
</category>

<root>
<priority value="info"/>
<appender-ref ref="CONSOLE"/>
</root>
</log4j:configuration>

 

 

查看更多精彩图片

查看更多精彩图片

查看更多精彩图片
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
全书一共被压缩为5个rar,这是第二个!!!! 其他的请看ID:ljtt123(本人分享) 本博客提供的所有教程的资源原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该文献之人无任何关系。谢谢合作 本书共分4部分,从xml、servlet、jsp和应用的角度向读者展示了java web开发中各种技术的应用,循序渐进地引导读者快速掌握java web开发。.   本书内容全面,涵盖了从事java web开发所应掌握的所有知识。在知识的讲解上,本书采用理论与实践相结合的方式,从程序运行的内部机制进行分析讲解,并通过大量的实例和实验来验证并运用本书的知识。.. 本书语言生动、通俗易懂、讲解细致,大部分章节都提供了多个例子,而且很多例子都是目前web开发中经常使用的功能,具有相当的实用价值。本书不仅可以作为java web开发的学习用书,还可以作为从事java web开发的程序员的参考用书和必备手册。此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml与dtd 2 1.1 xml的产生 2 1.2 w3c介绍 2 1.3 关于xml的几个问题 3 1.4 xml与html的比较 4 1.4.1 xml将数据与显示分开 5 1.4.2 xml对文档的格式要求更加严格 6 1.4.3 xml有且只能有一个根元素 6 1.5 xml的编辑工具 7 1.6 xml文档 8 1.6.1 xml声明 9 1.6.2 文档类型声明 10 1.6.3 元素 11 1.6.4 注释 15 1.6.5 处理指令 15 1.6.6 空白处理 16 1.6.7 行尾处理 16 1.6.8 语言标识 16 1.7 格式良好的xml 17 .1.8 dtd 18 1.8.1 在xml文档中引入dtd 18 1.8.2 dtd的结构 21 1.9 有效的xml 35 1.10 xml处理器/解析器 35 1.11 小结 36 第2章 xml名称空间 38 2.1 声明名称空间 38 2.2 名称空间在元素和属性中的运用 39 2.2.1 名称空间在元素中的运用 39 2.2.2 默认名称空间 41 2.2.3 名称空间在属性中的运用 42 2.3 名称空间和dtd 43 2.4 小结 45 第3章 对xml文档进行分析 46 3.1 dom、sax和jaxp 46 3.2 使用dom解析xml文档 47 3.2.1 dom结构模型 47 3.2.2 dom解析器工厂 50 3.2.3 jaxp的错误类和异常类 52 3.2.4 用dom解析xml文档实例 53 3.3 使用sax解析xml文档 65 3.3.1 sax的处理机制 66 3.3.2 配置sax解析器 69 3.3.3 sax解析器工厂 70 3.3.4 sax的异常类 71 3.3.5 errorhandler接口 73 3.3.6 使用sax解析xml文档实例 74 3.4 jdom 83 3.4.1 下载并配置jdom 83 3.4.2 jdom api介绍 84 3.5 dom4j 88 3.5.1 下载并配置dom4j 88 3.5.2 dom4j api介绍 88 3.5.3 第一个实例 92 3.5.4 第二个实例 94 3.6 解析名称空间 96 3.6.1 dom和名称空间 96 3.6.2 sax和名称空间 97 3.6.3 jdom和名称空间 98 3.6.4 dom4j和名称空间 98 3.7 小结 99 第4章 xsl转换 101 4.1 xslt概述 101 4.2 xalan处理器 105 4.3 模板规则 106 4.4 [xsl:apply-templates]元素 107 4.5 [xsl:value-of]元素 108 4.6 [xsl:for-each]元素 110 4.7 匹配节点的模式 111 4.8 mode属性 113 4.9 内置的模板规则 114 4.10 对空白的处理 115 4.11 xpath语言 116 4.11.1 xpath上下文 116 4.11.2 位置路径 117 4.11.3 表达式 121 4.11.4 核心函数库 123 4.12 创建结果树 126 4.12.1 创建元素和属性 127 4.12.2 创建文本 131 4.12.3 创建处理指令 133 4.12.4 创建注释 133 4.12.5 复制节点 134 4.12.6 输出格式化的数字 135 4.13 条件处理 144 4.13.1 [xsl:if] 144 4.13.2 [xsl:choose] 145 4.14 排序 146 4.15 变量和参数 150 4.15.1 变量 150 4.15.2 参数 152 4.16 命名模板 153 4.17 合并样式表 154 4.17.1 导入样式表 154 4.17.2 包含样式表 155 4.18 模板规则冲突的解决 156 4.19 [xsl:output]元素 157 4.19.1 指定输出文档的格式 158 4.19.2 输出xml声明 158 4.19.3 输出文档类型定义 159 4.19.4 输出cdata段 160 4.19.5 指定文档缩进 161 4.19.6 指定媒体类型 161 4.20 xslt中的函数 162 4.21 数字格式化 162 4.22 查询和分组 164 4.23 处理多个输入文档 172 4.24 jaxp中的xslt api 175 4.24.1 转换器工厂 175 4.24.2 transformer和templates 176 4.24.3 一个例子 178 4.25 小结 179 第2部分 servlet篇 第5章 servlet与tomcat 182 5.1 servlet与servlet容器 182 5.2 servlet容器的分类 183 5.3 servlet和其他技术的比较 183 5.4 tomcat介绍 183 5.5 tomcat的安装与配置 184 5.5.1 安装tomcat 185 5.5.2 运行tomcat 186 5.5.3 tomcat启动分析 189 5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 6.1.1 servlet接口 196 6.1.2 servlet相关接口与实现类 197 6.2 几个实例 205 6.2.1 实例一:simplehello 205 6.2.2 实例二:welcomeyou 210 6.2.3 实例三:outputinfo 216 6.2.4 实例四:loginservlet 220 6.3 servlet异常 223 6.3.1 servletexception类 224 6.3.2 unavailableexception类 224 6.4 servlet生命周期 224 6.5 servlet上下文 226 6.5.1 servletcontext接口 226 6.5.2 页面访问量统计实例 228 6.6 请求转发 231 6.6.1 requestdispatcher接口 232 6.6.2 得到requestdispatcher对象 232 6.6.3 请求转发的实例 233 6.6.4 sendredirect()和forward()方法的区别 238 6.7 小结 239 第7章 web应用程序的部署 240 7.1 配置任意目录下的web应用程序 240 7.2 war文件 242 7.3 tomcat中servlet的另一种运行方式 244 7.4 与servlet配置相关的元素 247 7.4.1 [servlet]元素及其子元素 247 7.4.2 [servlet-mapping]元素及其子元素 249 7.5 一个实例 250 7.6 小结 253 第8章 数据库访问 254 8.1 驱动程序的类型 254 8.1.1 jdbc-odbc桥 254 8.1.2 部分本地api java驱动程序 255 8.1.3 jdbc网络纯java驱动程序 255 8.1.4 本地协议的纯java驱动程序 256 8.2 安装数据库 256 8.3 jdbc api 260 8.3.1 加载并注册数据库驱动 261 8.3.2 建立到数据库的连接 263 8.3.3 访问数据库 264 8.3.4 事务处理 289 8.3.5 可滚动和可更新的结果集 296 8.4 jdbc数据源和连接池 299 8.5 mysql对中文的处理 302 8.6 小结 302 第9章 会话跟踪 303 9.1 用于会话跟踪的技术 303 9.1.1 ssl会话 304 9.1.2 cookies 304 9.1.3 url重写 305 9.2 java servlet api的会话跟踪 306 9.2.1 httpsession接口 306 9.2.2 session的生命周期 307 9.2.3 cookie的应用 319 9.2.4 httpsessionbindinglistener接口 328 9.2.5 在线人数统计程序 329 9.3 小结 335 第10章 servlet的异常处理机制 337 10.1 声明式异常处理 338 10.1.1 http错误代码的处理 338 10.1.2 java异常的处理 341 10.2 程序式异常处理 343 10.2.1 在try-catch语句中处理异常 343 10.2.2 使用requestdispatcher来处理异常 346 10.3 小结 349 第11章 开发线程安全的servlet 350 11.1 多线程的servlet模型 350 11.2 线程安全的servlet 351 11.2.1 变量的线程安全 351 11.2.2 属性的线程安全 360 11.3 singlethreadmodel接口 362 11.4 小结 363 11.5 思考题 363 第3部分 jsp篇 第12章 jsp技术 366 12.1 jsp简介 366 12.2 jsp的运行机制 366 12.3 jsp的语法 371 12.3.1 指令元素(directive elements) 371 12.3.2 脚本元素(scripting elements) 374 12.3.3 动作元素(action elements) 376 12.3.4 注释 383 12.4 jsp的隐含对象 383 12.4.1 pagecontext 384 12.4.2 out 385 12.4.3 page 385 12.4.4 exception 386 12.5 对象和范围 387 12.6 留言板程序 389 12.7 留言板管理程序 397 12.8 jsp文档 402 12.8.1 jsp文档的标识 404 12.8.2 jsp文档中的元素语法 404 12.9 小结 407 第13章 jsp与javabean 409 13.1 javabean简介 409 13.1.1 属性的命名 409 13.1.2 属性的类型 411 13.2 在jsp中使用javabean 412 13.2.1 [jsp:usebean] 412 13.2.2 [jsp:setproperty] 413 13.2.3 [jsp:getproperty] 414 13.2.4 示例 414 13.3 网上书店程序 418 13.4 小结 440 第14章 jsp开发的两种模型 441 14.1 模型1 441 14.2 模型2 445 14.3 小结 449 第15章 标签库(tag library) 450 15.1 标签库api 450 15.1.1 标签的形式 451 15.1.2 tag接口 451 15.1.3 iterationtag接口 453 15.1.4 bodytag接口 454 15.2 标签库描述符 455 15.2.1 [taglib]元素 456 15.2.2 [validator]元素 457 15.2.3 [listener]元素 457 15.2.4 [tag]元素 458 15.2.5 [tag-file]元素 460 15.2.6 [function]元素 461 15.3 传统标签的开发 462 15.3.1 实例一:[hello]标签 462 15.3.2 实例二:[max]标签 465 15.3.3 实例三:[greet]标签 467 15.3.4 实例四:[switch]标签 469 15.3.5 实例五:[iterate]标签 473 15.4 简单标签的开发 479 15.4.1 simpletag接口 479 15.4.2 实例一:[welcome]标签 480 15.4.3 实例二:[max_ex]标签 481 15.5 小结 483 第16章 表达式语言(el) 484 16.1 语法 484 16.1.1 “[ ]”和“.”操作符 484 16.1.2 算术操作符 484 16.1.3 关系操作符 485 16.1.4 逻辑操作符 485 16.1.5 empty操作符 485 16.1.6 条件操作符 485 16.1.7 圆括号 486 16.1.8 操作符的优先级 486 16.2 隐含对象 486 16.3 命名变量 487 16.4 保留的关键字 488 16.5 函数 488 16.6 小结 489 第17章 jsp标准标签库(jstl) 490 17.1 jstl简介 490 17.2 配置jstl 491 17.3 core标签库 491 17.3.1 一般用途的标签 492 17.3.2 条件标签 496 17.3.3 迭代标签 498 17.3.4 url相关的标签 501 17.4 i18n标签库 506 17.4.1 国际化标签 506 17.4.2 格式化标签 511 17.5 sql标签库 520 17.5.1 [sql:setdatasource] 520 17.5.2 [sql:query] 521 17.5.3 [sql:param] 524 17.5.4 [sql:dateparam] 525 17.5.5 [sql:update] 526 17.5.6 [sql:transaction] 527 17.6 xml标签库 529 17.6.1 核心操作 529 17.6.2 流程控制 532 17.6.3 转换操作 536 17.7 functions标签库 539 17.7.1 fn:contains 539 17.7.2 fn:containsignorecase 539 17.7.3 fn:startswith 540 17.7.4 fn:endswith 541 17.7.5 fn:indexof 541 17.7.6 fn:replace 542 17.7.7 fn:substring 543 17.7.8 fn:substringbefore 544 17.7.9 fn:substringafter 544 17.7.10 fn:split 545 17.7.11 fn:join 546 17.7.12 fn:tolowercase 547 17.7.13 fn:touppercase 547 17.7.14 fn:trim 548 17.7.15 fn:escapexml 548 17.7.16 fn:length 549 17.8 小结 549 第18章 标签文件(tag files) 551 18.1 标签文件的语法 551 18.2 一个简单的标签文件 551 18.3 标签文件的隐含对象 554 18.4 标签文件的指令 555 18.4.1 tag指令 555 18.4.2 attribute指令 556 18.4.3 variable指令 557 18.5 标签文件实例讲解 558 18.5.1 实例一:[welcome]标签 558 18.5.2 实例二:[tohtml]标签 559 18.6 [jsp:invoke]动作元素 561 18.7 [jsp:dobody]动作元素 562 18.8 小结 562 第4部分 应用篇 第19章 使用log4j进行日志操作 564 19.1 log4j介绍 564 19.1.1 logger组件 564 19.1.2 appender组件 566 19.1.3 layout组件 567 19.2 使用log4j 568 19.3 log4j使用实例 572 19.4 ndc和mdc 585 19.5 小结 587 第20章 filter在web开发中的应用 588 20.1 过滤器概述 588 20.2 filter api 589 20.2.1 filter接口 589 20.2.2 filterconfig接口 590 20.2.3 filterchain接口 590 20.3 过滤器的部署 591 20.4 过滤器的开发 592 20.5 对用户进行统一验证的过滤器 594 20.6 对请求和响应数据进行替换的 20.6 过滤器 600 20.7 小结 609 第21章 中文乱码问题与国际化 610 21.1 中文乱码问题产生的由来 610 21.1.1 常用字符集 610 21.1.2 对乱码产生过程的分析 612 21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化与本地化 621 21.5.1 locale 621.. 21.5.2 资源包 623 21.5.3 编写国际化的web应用程序 625 21.6 小结 629 第22章 使用jbuilder2005开发web 第22章 应用程序 630 22.1 jbuilder2005简介 630 22.2 集成开发环境介绍 631 22.2.1 菜单栏 631 22.2.2 主工具栏 632 22.2.3 工程工具栏和工程窗口 632 22.2.4 结构窗口 633 22.2.5 文件标签和内容窗口 634 22.2.6 文件视图标签 634 22.2.7 消息窗口 637 22.3 jbuilder2005的基本配置 638 22.3.1 配置jdk 638 22.3.2 配置web服务器 640 22.4 文件的上传和下载 642 22.4.1 基于表单的文件上传 642 22.4.2 文件上传格式分析 643 22.4.3 commons-fileupload组件 644 22.4.4 文件上传实例 646 22.4.5 文件下载实例 656 22.5 给图片添加水印和文字 664 22.6 小结 667 第23章 开发安全的web应用程序 668 23.1 概述 668 23.2 理解验证机制 669 23.2.1 http basic authentication 669 23.2.2 http digest authentication 670 23.2.3 https client authentication 670 23.2.4 form based authentication 671 23.3 声明式安全 671 23.3.1 [security-constraint]元素 671 23.3.2 [login-config]元素 673 23.3.3 基本验证的实现 674 23.3.4 基于表单验证的实现 676 23.3.5 使用数据库保存用户名和密码 678 23.4 程序式安全 682 23.5 sql注入攻击的防范 685 23.6 小结 687 第24章 web应用程序开发实例 688 24.1 图像的缩放 688 24.2 如何动态生成验证码 692 24.3 如何避免表单的重复提交 696 24.3.1 在客户端避免表单的重复提交 697 24.3.2 在服务器端避免表单的重复 24.3.2 提交 700 24.4 小结 706 第25章 使用ant辅助web应用程序 第25章 开发 707 25.1 ant介绍 707 25.2 安装并配置ant 708 25.2.1 下载并安装ant 708 25.2.2 设置ant的运行环境 708 25.3 编写ant的构建文件 709 25.3.1 准备工作 709 25.3.2 工程([project]) 712 25.3.3 目标([target]) 713 25.3.4 任务 714 25.3.5 path-like structures 728 25.3.6 引用(references) 729 25.4 部署到tomcat 730 25.5 运行ant 732 25.6 小结 732 第26章 xml和xslt在web开发中的 第26章 应用 733 26.1 功能概述 733 26.2 程序设计 733 26.2.1 软件架构 733 26.2.2 页面设计 735 26.2.3 数据库设计 747 26.3 程序实现 749 26.3.1 org.sunxin.guestbook 749 26.3.2 org.sunxin.guestbook.beans 750 26.3.3 org.sunxin.guestbook.util 758 26.3.4 org.sunxin.guestbook.parser 762 26.3.5 org.sunxin.guestbook.controller 765 26.3.6 org.sunxin.guestbook.view 787 26.3.7 page.xsl 791 26.3.8 web.xml 797 26.3.9 context.xml 798 26.4 小结 798 附录a 快速掌握html 799 附录b 解析http 820 附录c server.xml文件 833 附录d web.xml文件 840 索引 852...
log4j-over-slf4j是一个用于将log4j日志框架转换为SLF4J日志框架的桥接器。它的作用是将log4j接口输出的日志通过log4j-over-slf4j路由到SLF4J上,从而实现日志的集中输出。\[1\]在java的日志框架结构中,slf4j和jcl作为日志的门面存在于最上层,而log4j、jul、logback等则是这些门面的不同实现。为了使log4j也能符合slf4j规范,就出现了slf4j-log4j12这个桥接器,它的作用是将log4j适配为slf4j的接口实现。\[2\]而log4j-over-slf4j的作用则是将引入的jar包中的log4j替换为log4j-over-slf4j,从而统一项目中的日志框架,避免冗余和复杂性。具体来说,log4j-over-slf4j会将使用log4j打印日志的地方转换为slf4j打印日志,而slf4j实际调用的是logback来具体实现日志的打印。\[2\]这样就可以实现项目中日志框架的统一。 #### 引用[.reference_title] - *1* [log4j-over-slf4j工作原理详解](https://blog.csdn.net/john1337/article/details/76152906)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [slf4j logback log4j slf4j-log412 log4j-over-slf4j 关系详解](https://blog.csdn.net/asdasd3418/article/details/82840607)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [log4j-over-slf4j的jar包适配原理解析](https://blog.csdn.net/qq_43750656/article/details/125714607)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值