为了保存通讯时候产生的保温往来流水记录,使用log4j将流水保存到数据库。
1、数据库表设计如下:
create table COMMUNICATIONLOG (
ID VARCHAR2(32) not null,
SEQCODE VARCHAR2(8) not null,
COMMDATE VARCHAR2(10),
COMMTIME VARCHAR2(10),
TRANCODE VARCHAR2(6),
TYPE CHAR(1),
BITMAP VARCHAR2(100),
CONTENT VARCHAR2(2000),
MAPCONTENT VARCHAR2(2000),
constraint PK_COMMUNICATIONLOG primary key (ID)
);
comment on table COMMUNICATIONLOG is
'通讯报文日志流水表';
comment on column COMMUNICATIONLOG.ID is
'ID';
comment on column COMMUNICATIONLOG.SEQCODE is
'流水号';
comment on column COMMUNICATIONLOG.COMMDATE is
'通讯日期';
comment on column COMMUNICATIONLOG.COMMTIME is
'通讯时间';
comment on column COMMUNICATIONLOG.TRANCODE is
'当期交易号';
comment on column COMMUNICATIONLOG.TYPE is
'报文类型(R:来帐;S:往帐)';
comment on column COMMUNICATIONLOG.BITMAP is
'位元图内容';
comment on column COMMUNICATIONLOG.CONTENT is
'报文内容';
comment on column COMMUNICATIONLOG.MAPCONTENT is
'MAP内容';
2、log4j.properties文件中的配置定义如下:
log4j.logger.com.jbsoft.communication=DEBUG, LOGDB2 log4j.appender.LOGDB2=org.apache.log4j.jdbc.JDBCAppender log4j.appender.LOGDB2.Driver=oracle.jdbc.driver.OracleDriver log4j.appender.LOGDB2.URL=jdbc:oracle:thin:@localhost:1521:orcl log4j.appender.LOGDB2.user=jsloan log4j.appender.LOGDB2.password=jadebird log4j.appender.LOGDB2.sql=insert into COMMUNICATIONLOG (ID,SEQCODE,COMMTIME,TRANCODE,COMMDATE,CONTENT,BITMAP,TYPE,MAPCONTENT) values (S_COMMUNICATIONLOG.Nextval,'%X{seqcode}','%d{HH:mm:ss}','%X{trancode}','%d{yyyy-MM-dd}','%X{content}','%X{bitMap}','%X{type}','%X{map}') log4j.appender.LOGDB2.layout=org.apache.log4j.PatternLayout
3、使用AOP方式的程序使用
package com.jbsoft.communication.proxy.impl;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.MDC;
import com.jbsoft.communication.entity.message.BuildData;
import com.jbsoft.communication.entity.message.Message8583;
import com.jbsoft.communication.proxy.AbstractInterceptor;
import com.jbsoft.communication.util.EncodingUtils;
/**
* 创建拦截器实现类
* <p></p>
* @author liubing
* Date 2010-1-22
*/
public class BuilderInterceptorImpl extends AbstractInterceptor {
public BuilderInterceptorImpl() {
super( BuilderInterceptorImpl.class );
}
@Override
public Object invoke( MethodInvocation invocation ) throws Throwable {
System.out.println( "****" + Thread.currentThread().getId() );
StringBuffer buffer = new StringBuffer( "\r\n" );
buffer.append( "=======================================================\r\n" );
Object[] args = invocation.getArguments();
BuildData buildData = ( BuildData ) args[ 0 ];
String seqCode = buildData.getMap().get( "seqcode" );
buffer.append( "当前需要进行报文转换的Map对象内容为:"
+ buildData.getMap().toString() );
buffer.append( "\r\n==================================================\r\n" );
Message8583 result = ( Message8583 ) invocation.proceed();
buffer.append( "当前往帐报文元位图为:" + ArrayUtils.toString( result.getBitmap() ) );
buffer.append( "\r\n当前往帐报文内容为:" + EncodingUtils.exchangeGB2312( result.getContent() ) );
buffer.append( "\r\n==================================================\r\n" );
MDC.put( "trancode", buildData.getTranCode() );
MDC.put( "seqcode", seqCode );
MDC.put( "content", EncodingUtils.exchangeGB2312( result.getContent() ) );
MDC.put( "bitMap", ArrayUtils.toString( result.getBitmap() ) );
MDC.put( "type", "S" );
MDC.put( "map", buildData.getMap().toString() );
getLog().debug( buffer.toString() );
return result;
}
}
MDC是apache.log4j提供的,用于保存日志信息的上下文参数,其实现相当于一个MAP。保存在MDC中的内容在log4j.properties中的使用方式为:
%X{Key}
例如:
%X{trancode}
就是获取MDC中key为trancode的值。
注意:由于这里定义了使用数据库方式处理日志,因此每次调用Logger的debug/info/warn/error/fatal方法时,都会记录到数据库,为了保证不记录多余的信息,这里只调用一次getLog().debug()方法。环绕通知的实现,请参阅Spring文档。