Java自定义Exception和log4j的使用

4 篇文章 0 订阅


本次实验的项目结构如下:



定义处理日志工具类,在构造函数LogUtil(String logName)中调用org.apache.log4j.Logger的getLogger(logName)方法生成Logger对象。

LogUtil.java

package com.zhuomuniao.myapp.commons.utils;

import java.util.Date;

import org.apache.log4j.Logger;

import com.zhuomuniao.myapp.commons.BusinessException;

/**
 * ClassName:LogUtil.java
 * Description: 处理日志工具类
 **/
public class LogUtil {

	private static final String BLANK = " ";
	private Logger logger;

	public LogUtil(String logName) {
		try {
			logger = Logger.getLogger(logName);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void debug(String para) {
		logger.debug(para);
	}

	public void info(String className, String method, String ip, String userId) {
		try {
			StringBuffer buf = new StringBuffer();
			buf.append("className=[").append(className).append("]").append(BLANK);
			buf.append("method=[").append(method).append("]").append(BLANK);
			buf.append("ip=[").append(ip).append("]").append(BLANK);
			buf.append("userId=[").append(userId).append("]").append(BLANK);
			buf.append("opDate=[").append(new Date()).append("]").append(BLANK);
			this.logger.info(buf.toString());
		} catch (Exception e) {
			//todo 
		}
	}

	public void infoEx(Throwable para) {
		try {
			StringBuffer buf = new StringBuffer();
			para = getErrorLog(para, buf);
			logger.error(buf, para);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Throwable getErrorLog(Throwable para, StringBuffer buf) {
		try {
			BusinessException bisE;

			if (para.getClass().getName().endsWith("BusinessException")) {
				bisE = (BusinessException) para;
				String errorMessage = bisE.getErrorMessage();
				buf.append(errorMessage);
				para = bisE.getEx();
			} else {
				buf.append(para.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return para;
	}

}


BaseHttpServlet类继承HttpServlet类,其他所有action都继承此BaseHttpServlet类。

在BaseHttpServlet类中的init方法中创建两个LogUtil对象appLog和errLog,这两个对象分别通过传进去的实参"appLogger"和"errLogger",创建两个org.apache.log4j.Logger对象。

BaseHttpServlet.java

package com.zhuomuniao.myapp.commons;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import com.zhuomuniao.myapp.commons.utils.LogUtil;

/**
 * ClassName:BaseHttpServlet.java 
 * Description: 基础Servlet调用类
 */
public class BaseHttpServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;
  public LogUtil appLog;
  public LogUtil errLog;

  /**
   * 系统Servlet启动
   */
  public void init(ServletConfig config) throws ServletException {
    this.appLog = new LogUtil("appLogger");
    this.errLog = new LogUtil("errLogger");
    super.init();
  }

  /**
   * 系统Servlet销毁
   */
  public void destroy() {
    super.destroy();
  }

}


log4j的配置文件,此配置文件放在类路径下。

1.本配置文件先对根Logger(即Root)做配置:输出Log信息级别为DEBUG,目的地为 stdout  和 file。 接下来对 stdout 和 file 进行具体的配置。

2.然后本配置文件对上面创建的名为"appLogger"和"errLogger"的两个org.apache.log4j.Logger对象分别配置,

   appLogger 输出Log信息级别为DEBUG,目的地为 stdout  和 appFile, 接下来对 appFile 进行具体的配置,stdout  就直接用配置根Logger时使用的。

   errLogger 输出Log信息级别为DEBUG,目的地为 stdout  和 errFile, 接下来对 errFile 进行具体的配置,stdout  就直接用配置根Logger时使用的。

log4j.properties文件内容如下:

#设置级别和目的地,级别:'FATAL'、 'ERROR'、'WARN'、'INFO'、'DEBUG'
log4j.rootLogger = DEBUG, stdout, file

#配置输出到控制台的信息格式
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
#输出DEBUG级别以上的日志
log4j.appender.stdout.Threshold=DEBUG
#设置输出样式
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#自定义样式
log4j.appender.stdout.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}] %5p - %m%n
#直接输出,不进行缓存
log4j.appender.stdout.ImmediateFlush = true

#配置输出到file的文件格式
# org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生新文件)
log4j.appender.file=org.apache.log4j.RollingFileAppender
#设置文件输出路径    
log4j.appender.file.File=C:\\logs/Log4JDemo.log
#将消息增加到指定文件中
log4j.appender.file.Append=true
#输出DEBUG级别以上的日志
log4j.appender.file.Threshold=DEBUG 
#输出消息编码  
log4j.appender.file.encoding=UTF-8
#在日志文件到达该大小时,将会自动滚动,即将原来的内容移到xxx.log.1文件
log4j.appender.file.MaxFileSize=5000KB 
#指定可以产生的滚动文件的最大数 
log4j.appender.file.MaxBackupIndex=10
#设置输出样式
log4j.appender.file.layout=org.apache.log4j.PatternLayout
#自定义样式
log4j.appender.file.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}] %5p %l - %m%n
#直接输出,不进行缓存
log4j.appender.file.ImmediateFlush = true


log4j.logger.appLogger= DEBUG, stdout, appFile 
#用来设置是否同时输出到log4j.rootLogger所配置的日志中,默认为true,这里改为false
log4j.additivity.appLogger = false 

log4j.logger.errLogger= DEBUG, stdout, errFile 
#用来设置是否同时输出到log4j.rootLogger所配置的日志中,默认为true,这里改为false
log4j.additivity.errLogger = false 

#配置输出到appFile的文件格式
# org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生新文件)
log4j.appender.appFile=org.apache.log4j.RollingFileAppender
#设置文件输出路径    
log4j.appender.appFile.File=C:\\logs/appFile.log
#将消息增加到指定文件中
log4j.appender.appFile.Append=true
#输出DEBUG级别以上的日志
log4j.appender.appFile.Threshold=DEBUG 
#输出消息编码  
log4j.appender.appFile.encoding=UTF-8
#在日志文件到达该大小时,将会自动滚动,即将原来的内容移到xxx.log.1文件
log4j.appender.appFile.MaxFileSize=5000KB 
#指定可以产生的滚动文件的最大数 
log4j.appender.appFile.MaxBackupIndex=10
#设置输出样式
log4j.appender.appFile.layout=org.apache.log4j.PatternLayout
#自定义样式
log4j.appender.appFile.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}] %5p - %m%n
#直接输出,不进行缓存
log4j.appender.appFile.ImmediateFlush = true

#配置输出到errFile的文件格式
# org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生新文件)
log4j.appender.errFile=org.apache.log4j.RollingFileAppender
#设置文件输出路径    
log4j.appender.errFile.File=C:\\logs/errFile.log
#将消息增加到指定文件中
log4j.appender.errFile.Append=true
#输出DEBUG级别以上的日志
log4j.appender.errFile.Threshold=DEBUG 
#输出消息编码  
log4j.appender.errFile.encoding=UTF-8
#在日志文件到达该大小时,将会自动滚动,即将原来的内容移到xxx.log.1文件
log4j.appender.errFile.MaxFileSize=5000KB 
#指定可以产生的滚动文件的最大数 
log4j.appender.errFile.MaxBackupIndex=10
#设置输出样式
log4j.appender.errFile.layout=org.apache.log4j.PatternLayout
#自定义样式
log4j.appender.errFile.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss,SSS}] %5p - %m%n
#直接输出,不进行缓存
log4j.appender.errFile.ImmediateFlush = true

数据库连接池

ConnectionPoolManager.java

package com.zhuomuniao.myapp.commons;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * ClassName:ConnectionPoolManager.java
 * Description: 连接池
 */
public class ConnectionPoolManager {

	private static ConnectionPoolManager instance;				// 唯一实例

	static synchronized public ConnectionPoolManager getInstance() {
		if (instance == null) {
			instance = new ConnectionPoolManager();
		}
		return instance;
	}

	private ConnectionPoolManager() {
		try {
			// 装载驱动包类
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			System.out.println("装载数据库驱动包出现异常!");
			e.printStackTrace();
		}
	}

	public Connection getConnection() throws SQLException {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","s2sh","1234asdf");
		} catch (SQLException e) {
			System.out.println("链接数据库发生异常!");
			e.printStackTrace();
		}
		return conn;
	}
}


自定义异常

BusinessException.java

package com.zhuomuniao.myapp.commons;

/**
 * ClassName:BusinessException.java
 * Description:自定义异常类
 **/
public class BusinessException extends Exception {	//继承了Exception这个父类

	private static final long serialVersionUID = 1L;
	private String methodName;
	private String sqlString;
	private String sqlErrorCode;
	private Exception ex;
	
	public void setMethodName(String methodName) {
	  this.methodName = methodName;
	}
	public Exception getEx() {
	  return ex;
	}
	public void setSqlString(String sqlString) {
	  this.sqlString = sqlString;
	}
	public void setSqlErrorCode(String sqlErrorCode) {
	  this.sqlErrorCode = sqlErrorCode;
	}
	public void setEx(Exception ex) {
	  this.ex = ex;
	}
	
	public String getErrorMessage() {
		StringBuilder buf = new StringBuilder();
		String kaigyo = System.getProperty("line.separator"); //获取系统换行符

		if (methodName != null) {
			buf.append("Exception happened on ");
			buf.append(methodName);
		}
		
		if (ex != null) {
			buf.append(kaigyo);
			buf.append(ex.toString());
		}

		if (sqlString != null) {
			buf.append(kaigyo);
			buf.append("SQL = ");
			buf.append(sqlString);
		}
		
		if (sqlErrorCode != null) {
			buf.append(kaigyo);
			buf.append("ErrorCode = ");
			buf.append(sqlErrorCode);
		}
		
		return buf.toString();
	}
}



在DAO中,当捕获到SQLException时,生成一个上面的自定义异常类的对象,并调用相应的set方法赋值,随后抛出自定义异常。

StudentDao.java

package com.zhuomuniao.myapp.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.zhuomuniao.myapp.commons.BusinessException;
import com.zhuomuniao.myapp.commons.ConnectionPoolManager;

public class StudentDao {

	public boolean addStu() throws Exception {

		boolean result = true;
		Connection conn = null;
		PreparedStatement pstmt = null;

		StringBuilder sql = new StringBuilder();
		sql.append("INSERT INTO TEST (ID, NAME, AGE)   ").append("\n");
		sql.append("VALUES ( '1','zhuomuniao','27')			");

		try {
			conn = ConnectionPoolManager.getInstance().getConnection();
			conn.setAutoCommit(false);
			pstmt = conn.prepareStatement(sql.toString());
			pstmt.execute(); 	//执行数据库更新操作
			conn.commit(); 		//提交事务    
		} catch (SQLException sqle) {
			result = false;
			BusinessException bisE = new BusinessException();
			bisE.setSqlString(sql.toString());
			bisE.setSqlErrorCode(String.valueOf(sqle.getErrorCode()));
			bisE.setEx(sqle);
			bisE.setMethodName(this.getClass().getName().toString()+" addStu()");
			throw bisE;
		} finally {
			if (pstmt != null) {
				pstmt.close();
				pstmt = null;
			}
			if (conn != null) {
				conn.close();
				conn = null;
			}
		}
		return result;
	}
}


StudentService.java

package com.zhuomuniao.myapp.service;

import com.zhuomuniao.myapp.dao.StudentDao;

public class StudentService  {
  private StudentDao studentDao=new StudentDao();

  public void addStu() throws Exception {
    studentDao.addStu();
  } 
}



在action中捕获到DAO中抛出的自定义异常后,通过调用此类的父类BaseHttpServlet中定义的处理日志工具类LogUtil对象errLog的infoEx方法记录到日志中。

当然,如果DAO正常执行,没有异常,则在action中调用此类的父类BaseHttpServlet中定义的处理日志工具类LogUtil对象appLog的info方法记录到日志中。

StudentAction.java

package com.zhuomuniao.myapp.action;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zhuomuniao.myapp.commons.BaseHttpServlet;
import com.zhuomuniao.myapp.commons.BusinessException;
import com.zhuomuniao.myapp.service.StudentService;

@SuppressWarnings("serial")
public class StudentAction extends BaseHttpServlet {

	private StudentService studentService  = new StudentService (); 

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  	String action = request.getParameter("action");
  	if("addStu".equals(action))
  		doAddStu(request, response);
  }
  
  public void doAddStu(HttpServletRequest request, HttpServletResponse response){
  	try {
			studentService.addStu();
			super.appLog.info(
					this.getClass().getName(),
					"doAddStu(HttpServletRequest request, HttpServletResponse response)",
          request.getRemoteAddr(), 
          "userId");
		} catch (BusinessException be) {
      super.errLog.infoEx(be);
    } catch (Exception e) {
      super.errLog.infoEx(e);
    }
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(req, resp);
  }
}



实验结果截图:

1. 利用log4j输出用户自定义异常信息到控制台。


2. 利用log4j输出用户自定义异常信息到日志文件errFile.log。


3. 利用log4j输出信息到控制台。


4. 利用log4j输出信息到日志文件appFile.log。


log4j产生的日志文件目录


下载地址: http://download.csdn.net/detail/chuzhenbin/4159298


==============以上================


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值