??xml version="1.0" encoding="utf-8" standalone="yes"?>
准备好了吗?让我们开始下一?/p>
W一步:写一个简单的EJB。写EJB最好用的还是JBuilderQ毕竟够ȝ化。当然作Z业h士,eclipse搭配MyEclipse是最佳选择Q不q作为初学者,采用JBuilder。以下是本文试所用到的EJB?/p>
remote接口Q?/p>
package testhello;
import javax.ejb.EJBObject;
public interface SayHello extends EJBObject {
public String sayHello(String name) throws java.rmi.RemoteException;
}
home接口Q?/p>
package testhello;
import javax.ejb.EJBHome;
import javax.ejb.CreateException;
import java.rmi.RemoteException;
public interface SayHelloHome extends EJBHome {
public SayHello create() throws CreateException, RemoteException;
}
beanc:
package testhello;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.CreateException;
public class SayHelloBean implements SessionBean {
SessionContext sessionContext;
public void ejbCreate() throws CreateException {
}
public void ejbRemove() {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}
public String sayHello(String name) {
return "Hello "+name;
}
}
如果你是采用上面两种工具来写的话Q配|文件就不必考虑?/p>
W二步:利用JBuilder或eclipse这个EJB工程~译q打包,会得C个jar(如果你的工程名叫testhelloQ那么这个jar文g是testhello.jar)文g。如果你的EJB容器Qweblogic或JBossQ是在本ZQ那么在JBuilder或eclipse中就可以直接鼠标叛_EJB工程Q来部vEJB。如果需要部|到q程服务器上Q只需要通过EJB容器的控制台testhello.jar上传到远E端Q然后在EJB Modler里面按提C部|好EJB。最后,别忘了在JNDI Tree里面察看你的EJB工程的JNDI名,本例的JNDI名叫SayHello
W三步:remote接口和home接口打包成jar文gQcopyC要远E调用EJB的struts工程下的lib目录Q例如:helloapp ->WEB-INF ->libQ?/p>
W四步:weblogic的weblogic.jarQ在weblogic的安装目录->weblogic81Q?gt;serverQ?gt;lib文g夹中Qcopy到tomcat安装目录下的Q?gt;sharedQ?gt;lib文g夹中Q其实这里我们需要用到的只是weblogic.jar里的几个class文g而已Q不q对于初学者而言Q先不必LI到底只需要那几个class?/p>
W五步:~写一个简单的struts工程Q其实这些都可以用工L成)Q一下是调用EJB的HelloAction的源代码(特别要注意的是,记得要将之前W三步生成的jar包导入编辑器中,否则下面的代码编译通不q。如果你不知道导入jar包,把那个jar包多copy一份到你的jdk安装目录 -> jre-> lib-> ext文g夹下)
package logging.actions;
import logging.Constants;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;
import org.apache.struts.validator.DynaValidatorForm;
public final class HelloAction extends Action{
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception{
InitialContext ctx=this.getInitialContext();
//查找JNDI名ؓSayHello的EJBlg
Object obj=ctx.lookup("SayHello");
//获得q程EJBlg的home接口的引?br /> testhello.SayHelloHome home=(testhello.SayHelloHome)PortableRemoteObject.narrow(obj,testhello.SayHelloHome.class);
//获得q程EJBlg的remote接口的引?br /> testhello.SayHello hello=home.create();
String name="飘然随风";
String sayString=hello.sayHello(name);
request.setAttribute("userName",name);
request.setAttribute("passWord",sayString);
request.removeAttribute(mapping.getAttribute());
return mapping.findForward("loginSuccess");
}
/*以下Ҏ是作用是Q通过传递环境属性选择JNDI驱动和服务器的网l位|,
q连接到q接到JNDI树?br /> q是采用weblogic做EJB容器Ӟq程调用EJB的固定初始化模式Q初学者可以死C?br />*/
private InitialContext getInitialContext() throws Exception {
//EJB容器的地址
String url = "t3://image:7001";
String user = null;
String password = null;
Properties properties;
properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL, url);
if (user != null) {
properties.put(Context.SECURITY_PRINCIPAL, user);
properties.put(Context.SECURITY_CREDENTIALS,
password == null ? "" : password);
}
return new javax.naming.InitialContext(properties);
}
}
W六步:如果你严格按照上面的步骤做了Q那么剩下的是同时启动weblogic和tomcat来测试了?/p>
我用的filter是Craig McClanahan写的Q这位仁兄大名鼎鼎,他是Struts框架的主要体p设计师和开发者,Tomcat4的主设计师和Java Web Services Developer Pack实现包的主设计师Q领导着Sun的JavaServer Faces规范开发,同时也是Java EEq_的Web Layer Archiecture。filter的代码附在文后?/p>
web.xml中的配置如下Q?/p>
<!-- GBK Encodinbg Filter definition -->
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<!-- GBK Encoding Filter mapping -->
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.~写L口程?/font>
在文本编辑器中编?font color="#ff0000">HelloHome.java文gQƈ保存在C:\work\hello目录下,其代码ؓQ?br /> //本接口需要引入的cL接口
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
//定义L口,必须l承EJBHome
public interface HelloHome extends EJBHome {
//定义EJB创徏Ҏ
Hello create() throws CreateException, RemoteException;
}
2.~写q程接口E序
在文本编辑器中编?font color="#ff0000">Hello.java文gQƈ保存在C:\work\hello目录下。Hello.java文g的代码ؓQ?br /> //本接口需要引入的cL接口
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
//定义q程接口Q必ȝ承EJBObject
public interface Hello extends EJBObject {
//定义业务逻辑Ҏ
public String sayHello()
throws RemoteException;
}
3.~写Beancd现程?/strong>
在文件编辑器中编?font color="#ff0000">HelloBean.java文gQƈ保存在C:\work\hello目录下。HellloBean.java文g的代码ؓQ?br /> //本类需要引入的cL接口
import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
//实现业务逻辑Q必d现SessionBean接口
public class HelloBean implements SessionBean {
//q是个会话EJBQ声明会话上下文
private SessionContext ctx;
//声明字符?br /> private String words;
//接口SessionBean中定义的ҎQ必d?br /> public void setSessionContext(SessionContext ctx) {
this.ctx = ctx;
}
//接口SessionBean中定义的ҎQ必d?br /> public void ejbActivate() {
}
//接口SessionBean中定义的ҎQ必d?br /> public void ejbPassivate() {
}
//接口SessionBean中定义的ҎQ必d?br /> public void ejbRemove() {
}
//和主接口定义对应的方法,必须实现
public void ejbCreate() throws CreateException {
words = "Hello World";
}
//供客L调用的业务逻辑ҎQ这里只单的打印字符Ԍq把字符串返回到客户?br /> public String sayHello()
{
System.out.println("I am in an EJB of Server ."+words);
return words;
} }
Q?Q?EJB代码~译
首先打开命oH口Q进入C:\work\hello目录Q运行环境变量脚本程序:
c:\work\hello>c:\work\setEnv
建立build目录Q?br /> c:\work\hello>md build
执行~译命oQ?br /> c:\work\hello>java -d build Hello.java HelloHome.java HelloBean.java
其中Q?d build 表示~译生成的class文g攑֜build目录中?br />Q?QEJB部v文g~写
部v文g是EJB的重要组成部分。简单地_部v文g是EJB的说明文Ӟq个文g由服务器容器使用Q服务器Ҏ部v文g的说明来理EJB?br /> EJB部v文g是标准的XML文gQ必遵守XML的语法规则。此外,q要遵守相关的DTD规则?br /> 部v文g到少有两个文件ejb-jar.xml和weblogic-ejb-jar.xml。前者ؓEJB自n的一些特征,如名U、组成等Q后者是和EJB部v相关的描q?br /> ~写部v文gQ?br /> (1)在文件编辑器中编辑ejb-jar.xml文gQƈ保存在C:\work\hello目录下。ejb-jar.xml文g的内容ؓQ?br /><?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<!--EJB说明文g-->
<ejb-jar>
<small-icon>images/green-cube.gif</small-icon>
<enterprise-beans>
<!--定义会话EJB-->
<session>
<small-icon>images/orange-cube.gif</small-icon>
<!--定义会话EJB?->
<ejb-name>MyFirstEJB</ejb-name>
<!--定义会话EJBL口名-->
<home>HelloHome</home>
<!--定义会话EJBq程接口?->
<remote>Hello</remote>
<!--定义会话EJB实现cd-->
<ejb-class>HelloBean</ejb-class>
<!--定义会话EJBcd-->
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<!--定义会话EJB装配描述-->
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>MyFirstEJB</ejb-name>
<method-intf>Remote</method-intf>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
(2)在文件编辑器中编辑weblogic-ejb-jar.xml文gQƈ保存在C:\work\hello目录下。weblogic-ejb-jar.xml文g的内容ؓQ?br /><?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN' 'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
<!--EJB部v说明文g-->
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<!--EJB?->
<ejb-name>MyFirstEJB</ejb-name>
<!--定义EJB最大缓冲池-->
<caching-descriptor>
<max-beans-in-free-pool>100</max-beans-in-free-pool>
</caching-descriptor>
<!--定义EJB jndi名称-->
<jndi-name>HelloHome</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
Q?Q?打包
把上面开发的所有文件打成jar文g包。这些文件包括一三个cLӞHello.class、HelloHome.class、HelloBean.class和部|文Ӟejb-jar.xml,weblogic-ejb-jar.xml。打包时Q文件放|的位置是严D求的。具体ؓQ?.class文g攑֜当前目录(即C:\work\hello\build目录?Q部|文件必d在下一U目录Meta-inf?即C:\work\hello\build\Meta-inf目录?。如果EJB包含囑փ文gQ则囑փ文g必须在build目录的下一U目录images?即C:\work\hello\build\images目录??br /> 具体操作步骤为:
(1)在build目录中创建Meta-inf目录Q当前\径ؓC:\work\helloQ执行:
c:\work\hello>md build\Meta-inf
(2)把部|文件拷贝到hello\Meta-inf目录下:
c:\work\hello>copy *.xml build\Meta-inf
(3)执行Q?br /> c:\work\hello>md build\images
c:\work\hello>copy *.gif build\images
当然Q本例中没有使用囑փ文gQ所以可以免L步骤?br /> (4)用jar命o在build目录下打包。当前\径是c:\work\helloQ运行:
c:\work\hello>cd build
c:\work\hello\bulid>jar cv0f std_myfirstejb_hello.jar META-INF *.class images
c:\work\hello\build>cd..
其中Qjar是Jdk中的打包命oQcv0f是命令参敎ͼstd_myfirstejb_hello.jar是生成的文g名,qh定?br /> 命o执行完后Q在目录build中应该生成文件std_myfirstejb_hello.jar?br /> xQ打包完成?
Q?Q编译生成窗口代?/strong>
Weblogic Server提供了编译生成容器代码的工具Q它是一个javaE序weblogic.ejbc。在命o行窗口中执行Q?br /> c:\work\hello>java weblogic.ejbc -compiler javac build\std_myfirstejb_hello.jar build\myfirstejb_hello.jar
可以看出ejbc把std_myfirstejb_hello.jar文g~译成myfirstejb_hello.jarQ它包括了Weblogic Serverq_可以识别的ejb容器代码?br /> 如果q行成功Q则在build目录下生myfirstejb_hello.jar文g?/p>
(1)安装破解Weblogic 8.3.1? www.9iv.com )Q运行Configuration WizardQ?/font>
(2)选择Create a new Weblogic configuraionQ?/font>
(3)Select a Configuration Template中选择Basic Weblogic Server DomainQ?/font>
(4)Chose Express or Custom Configuration中我选择的是Express(如果寚w|很熟悉q是选择Custom比较好些)Q?/font>
(5)在Configure Administrative Username and Password中设|用户名和密码;
(6)在Configure Server Start Mode and Java SDK中我选择了Development ModeQ在JDK中选择了BEA默认安装的Sun JDK 1.4.2_04Q?/font>
(7)在下一步部|中输入需要的Congfiguration Name可以Create了?/font>
W二步在MyEclipse配置WeblogicQ?/font>
(1)选择菜单Window->Preferences->MyEclipse->Application Servers->Weblogic 8Q配|项目如下:
BEA home directory: 选择Bea的安装目?/font>
Weblogic installation directory:现在BEA下面的weblogic81目录
Admin username:输入上面在配|过E中讄用户?/font>
Admin password:输入刚才讄密码
Execution domain root:选择BEA下user_projects\domains目录下上面第一步创建的目录
Execution domain name:输入上面那个目录的名U?/font>
Execution server name:输入上一步的那个Congfiguration Name
Hostname:PortNumber:输入IP地址和监听的端口
Security policy file:输入BEA安装目录下的\weblogic81\server\lib\weblogic.policy
(2)在Weblogic 8下面配置JDKQ在WLS JDK name那里选择新徏Q弹出的对话框中选择BEA下面的JDK安装路径Q输入一个名字确定就可以Q在Optional Java VM arguments对话框里面输?ms64m -mx64m -Djava.library.path="D:/BEA/weblogic81/server/bin" -Dweblogic.management.discover=false -Dweblogic.ProductionModeEnabled=false
(3在Weblogic 8下面配置PathsQ加入BEA安装路径?weblogic81/server/lib中的webservices.jar和weblogic.jar两个包。如果需要其他的包,也在q里加入?/font>
单的?span lang="EN-US" twffan="done">log4j是帮助开发h员进行日志输出管理的APIcd。它最重要的特点就
可以
配置文g灉|的设|?/span>
日志信息的优先、日志信息的输出目的C及日志信息的输出格式?span lang="EN-US" twffan="done">
Log4j除了可以记录E序q行日志信息外还有一重要的功能就是用?/span> 昄调试信息。程序员l常会遇到脱?span lang="EN-US" twffan="done">java ide环境调试E序的情况,q时大多Ch会选择使用System.out.println语句输出某个变量值的Ҏq行调试。这样会带来一个非帔R烦的问题Q一旦哪天程序员军_不要昄q些System.out.println的东西了只能一行行的把q些垃圾语句注释掉。若哪天又需调试变量|则只能再一行行Lq些注释恢复System.out.println语句。用log4j可以很好的处理类似情c?o:p>
log4j使用Ҏ
下面介绍的是log4j一些理论方面的知识Q读者觉得枯燥的话可以蟩q本节直接阅ȝ三节实例部分?o:p>
1、定义配|文?o:p>
首先使用配置文g我们的应用程序更加灵z配|log日志输出方式包括输出优先U、输出目的地、输出格式。Log4j支持两种配置文g格式Q一U是XML格式的文Ӟ一U是JavaҎ文件log4j.propertiesQ键=|。下面将介绍使用log4j.properties文g作ؓ配置文g的方法:
?/span>
配置根LoggerQ其语法为:0
log4j.rootLogger = [ level ] , appenderName, appenderName, ?
其中Q?span lang="EN-US" twffan="done">level 是日志记录的优先U,分ؓOFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的别。Log4j只用四个别,优先U从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的U别Q您可以控制到应用程序中相应U别的日志信息的开兟뀂比如在q里定义了INFOU别Q则应用E序中所有DEBUGU别的日志信息将不被打印出来?appenderName是指定日志信息输出到哪个地斏V可同时指定多个输出目的地?
?/span>
配置日志信息输出目的地AppenderQ其语法为:
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
?
log4j.appender.appenderName.option = valueN
其中Q?/font>
Log4j提供的appender有以下几U:
org.apache.log4j.ConsoleAppenderQ控制台Q,
org.apache.log4j.FileAppenderQ文ӞQ?
org.apache.log4j.DailyRollingFileAppenderQ每天生一个日志文ӞQ?br /> org.apache.log4j.RollingFileAppenderQ文件大到达指定尺寸的时候生一个新的文ӞQ?
org.apache.log4j.WriterAppenderQ将日志信息以流格式发送到L指定的地方)
?/span> 配置日志信息的格式(布局Q,其语法ؓQ?o:p>
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
?
log4j.appender.appenderName.layout.option = valueN
其中Q?/font>
Log4j提供的layout有以下几U:
org.apache.log4j.HTMLLayoutQ以HTML表格形式布局Q,
org.apache.log4j.PatternLayoutQ可以灵zd指定布局模式Q,
org.apache.log4j.SimpleLayoutQ包含日志信息的U别和信息字W串Q,
org.apache.log4j.TTCCLayoutQ包含日志生的旉、线E、类别等{信息)
Log4J采用cMC语言中的printf函数的打印格式格式化日志信息Q打印参数如下: %m 输出代码中指定的消息
%p 输出优先U,即DEBUGQINFOQWARNQERRORQFATAL
%r 输出自应用启动到输出该log信息耗费的毫U数
%c 输出所属的cȝQ通常是所在类的全?
%t 输出产生该日志事件的U程?
%n 输出一个回车换行符QWindowsq_为“\r\n”,Unixq_为“\n?
%d 输出日志旉点的日期或时_默认格式为ISO8601Q也可以在其后指定格式,比如Q?d{yyy MMM dd HH:mm:ss,SSS}Q输出类|
%l 输出日志事g的发生位|,包括cȝ名、发生的U程Q以及在代码中的行数。D例:Testlog4.main(TestLog4.java:10)
2、在代码中用Log4j
?/span> 得到记录?o:p>
使用Log4jQ第一步就是获取日志记录器Q这个记录器负责控制日志信息。其语法为:
public static Logger getLogger( String name)
通过指定的名字获得记录器Q如果必要的话,则ؓq个名字创徏一个新的记录器?span lang="EN-US" twffan="done">Name一般取本类的名字,比如Q?
static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )
?/span>
d配置文g
当获得了日志记录器之后,W二步将配置Log4j环境Q其语法为:
BasicConfigurator.configure ()Q?自动快速地使用~省Log4j环境?br /> PropertyConfigurator.configure ( String configFilename) Q读取用Java的特性文件编写的配置文g?o:p>
例:PropertyConfigurator.configure
(".\\src\\log4j.properties")
DOMConfigurator.configure ( String filename ) Q读取XML形式的配|文件?o:p>
?/span> 插入记录信息Q格式化日志信息Q?o:p>
当上两个必要步骤执行完毕Q就可轻村֜使用不同优先U别的日志记录语句插入到您想记录日志的Q何地方,其语法如下:
Logger.debug ( Object message ) ;
Logger.info ( Object message ) ;
Logger.warn ( Object message ) ;
Logger.error ( Object message ) ;
log4j范例E序
下面用一个最单的范例E序来进一步说?span lang="EN-US" twffan="done">log4j的用方法。程序代码如下:
import org.apache.log4j.*;
public class
LogTest
{
static
Logger logger = Logger.getLogger(LogTest.class.getName());
public
static
void
main(String[] args)
{
PropertyConfigurator.configure ( ?\\src\
log4j.properties
?
Q?/span>
logger.debug(
"Debug ..."
);
logger.info(
"Info ..."
);
logger.warn(
"Warn ..."
);
logger.error(
"Error ..."
);
}
}
E序说明Q?span lang="EN-US" twffan="done">
?/span>
static Logger logger = Logger.getLogger(LogTest.class.getName());
是创徏一个属?/span>
LogTest
cȝ
Logger
对象Q创建时要告?/span>
Logger
你当前的
Class
是什么?/span>
?/span>
PropertyConfigurator.configure ( ?/span>
log4j.properties
?
是说用当前工E目录下?/span>
src
文g夹中?/span>
log4j.properties
文g作ؓ配置文g。若?/span>
log4j.properties
攑֜工程根目录下也可不写此句Q程序会自动扑ֈ配置文g?/span>
?/span>
logger.debug
是输出
debug
的信息,
logger.info
是输出提示信息Q?/span>
logger.warn
是昄警告信息Q?/span>
logger.error
是昄错误信息?/span>
下面是配|文?/span>
log4j.properties
的内容:
log4j.rootCategory=DEBUG, stdout
Q?/span>
R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=log.txt
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d
{
yyyy MMM dd HH:mm:ss
}
%-5p %c - %m%n
E序说明Q?span lang="EN-US" twffan="done">
?/span>
log4j.rootCategory=DEBUG, stdout
Q?/span>
R
是说我要显C所有优先权{於和高?/span>
Debug的信息?br />"stdout"Q?/span>
”R?/span>
表示我定义了两个输出?/span>
(
随便什么名字都?/span>
)
?/span>
?/span>
下面的三行说
stdout
输出端其实是标准输出
Console
Q也是屏幕。输出的格式?/span>
Pattern
Layout
。{换方式是
%5p (%F:%L) - %m%n
Q即前五格用来显CZ先权Q再昄当前的文件名Q加当前的行数。最后是
logger.debug()
?/span>
logger.info()
?/span>
logger.warn()
?/span>
logger.error()
里的信息?/span>
%n
表示回RI?/span>
?/span>
再加上下面六行则
log
信息不光昄在屏q上Q而且被保存在一个叫
"log.txt"
的文仉Q文件最大ؓ
100KB
。如果文件大超q?/span>
100KB
Q文件会被备份成
"log.txt.1"
Q新?/span>
"log.txt"
l箋记录
log
信息?/span>
接下来我们可以改?/span>
log4j.properties
Q而不需重新~译可以控?/span>
log
信息是否昄?/span>
log
信息的输出端cd、输出方式、输出格式,{等。D例如下:
?/span>
?/span>
log4j.properties
文g里把
"log4j.rootCategory=DEBUG,stdout,R"
改写?/span>
"log4j.rootCategory=OFF, stdout,R"
Q这h有的
log信息都不会显CZQ解决了本文开始提出的问题?br />?/span>
?/span>
log4j.properties
文g里把
"log4j.rootCategory=DEBUG,stdout,R"
改写?/span>
"log4j.rootCategory=INFO, stdout,R"
Q这样只昄
INFO, WARN, ERROR
?/span>
log
信息Q?/span>
DEBUG
信息不会被显C;
?span lang="EN-US" twffan="done">webE序中用log4j注意问题
1?span style="FONT: 7pt 'Times New Roman'" twffan="done">
׃jsp或servlet在执行状态时没有当前路径概念Q所有?/span>
PropertyConfigurator.configure
Q?/span>
String
Q语句找
log4j.properties
文g时要l出相对于当?/span>
jsp
?/span>
servlet
的\径{化成Z个绝对的文gpȝ路径。方法是使用
servletcontext.getrealpath(string)
语句。例Q?/span>
//得到当前jsp路径
String prefix = getServletContext().getRealPath(
"/");
//d
log4j.properties
PropertyConfigurator.configure(prefix+
"\\WEB-INF\\log4j.properties");
2、相应的log4j.properties讄某个属性时也要在程序中讄l对路径。例Q?o:p>
log4j.appender.R.File属性设|日志文件存放位|。我们可以用d.properties配置文g的方法进行灵z设|?/span>
Parameter | Description |
---|---|
username | The connection username to be passed to our JDBC driver to establish a connection. |
password | The connection password to be passed to our JDBC driver to establish a connection. |
url | The connection URL to be passed to our JDBC driver to establish a connection. |
driverClassName | The fully qualified Java class name of the JDBC driver to be used. |
connectionProperties | The connection properties that will be sent to our JDBC driver when establishing new connections. Format of the string must be [propertyName=property;]* NOTE - The "user" and "password" properties will be passed explicitly, so they do not need to be included here. |
Parameter | Default | Description |
---|---|---|
defaultAutoCommit | true | The default auto-commit state of connections created by this pool. |
defaultReadOnly | driver default | The default read-only state of connections created by this pool. If not set then the setReadOnly method will not be called. (Some drivers don't support read only mode, ex: Informix) |
defaultTransactionIsolation | driver default | The default TransactionIsolation state of connections created by this pool. One of the following: (see javadoc)
|
defaultCatalog | The default catalog of connections created by this pool. |
Parameter | Default | Description |
---|---|---|
initialSize | 0 | The initial number of connections that are created when the pool is started. Since: 1.2 |
maxActive | 8 | The maximum number of active connections that can be allocated from this pool at the same time, or zero for no limit. |
maxIdle | 8 | The maximum number of active connections that can remain idle in the pool, without extra ones being released, or zero for no limit. |
minIdle | 0 | The minimum number of active connections that can remain idle in the pool, without extra ones being created, or zero to create none. |
maxWait | indefinitely | The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception, or -1 to wait indefinitely. |
Parameter | Default | Description |
---|---|---|
validationQuery | The SQL query that will be used to validate connections from this pool before returning them to the caller. If specified, this query MUST be an SQL SELECT statement that returns at least one row. | |
testOnBorrow | true | The indication of whether objects will be validated before being borrowed from the pool. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another. NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string. |
testOnReturn | false | The indication of whether objects will be validated before being returned to the pool. NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string. |
testWhileIdle | false | The indication of whether objects will be validated by the idle object evictor (if any). If an object fails to validate, it will be dropped from the pool. NOTE - for a true value to have any effect, the validationQuery parameter must be set to a non-null string. |
timeBetweenEvictionRunsMillis | -1 | The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle object evictor thread will be run. |
numTestsPerEvictionRun | 3 | The number of objects to examine during each run of the idle object evictor thread (if any). |
minEvictableIdleTimeMillis | 1000 * 60 * 30 | The minimum amount of time an object may sit idle in the pool before it is eligable for eviction by the idle object evictor (if any). |
Parameter | Default | Description |
---|---|---|
poolPreparedStatements | false | Enable prepared statement pooling for this pool. |
maxOpenPreparedStatements | unlimited | The maximum number of open statements that can be allocated from the statement pool at the same time, or zero for no limit. |
This component has also the ability to pool PreparedStatements. When enabled a statement pool will be created for each Connection and PreparedStatements created by one of the following methods will be pooled:
NOTE - Make sure your connection has some resources left for the other statements.
Parameter | Default | Description |
---|---|---|
accessToUnderlyingConnectionAllowed | false | Controls if the PoolGuard allows access to the underlying connection. |
When allowed you can access the underlying connection using the following construct:
Connection conn = ds.getConnection(); Connection dconn = ((DelegatingConnection) conn).getInnermostDelegate(); ... conn.close()
Default is false, it is a potential dangerous operation and misbehaving programs can do harmfull things. (closing the underlying or continue using it when the guarded connection is already closed) Be carefull and only use when you need direct access to driver specific extentions.
NOTE: Do not close the underlying connection, only the original one.
Parameter | Default | Description |
---|---|---|
removeAbandoned | false | Flag to remove abandoned connections if they exceed the removeAbandonedTimout. If set to true a connection is considered abandoned and eligible for removal if it has been idle longer than the removeAbandonedTimeout. Setting this to true can recover db connections from poorly written applications which fail to close a connection. |
removeAbandonedTimeout | 300 | Timeout in seconds before an abandoned connection can be removed. |
logAbandoned | false | Flag to log stack traces for application code which abandoned a Statement or Connection. Logging of abandoned Statements and Connections adds overhead for every Connection open or new Statement because a stack trace has to be generated. |
If you have enabled "removeAbandoned" then it is possible that a connection is reclaimed by the pool because it is considered to be abandoned. This mechanism is triggered when (getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)
For example maxActive=20 and 18 active connections and 1 idle connection would trigger the "removeAbandoned". But only the active connections that aren't used for more then "removeAbandonedTimeout" seconds are removed, default (300 sec). Traversing a resultset doesn't count as being used.
conf/web.xml文g:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
需要3个包Q别忘了数据库驱动包Q?/p>
commons-collections-3.1.jar
commons-dbcp-1.2.1.jar
commons-pool-1.2.jar
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception
{
DataSource dataSource;
Connection cnn;
try
{
dataSource = getDataSource(request);
cnn = dataSource.getConnection();
// 数据q接已经建立了,你可以做你想做的事情?br /> }
catch (SQLException e)
{
getServlet().log("处理数据库连?, e);
}
finally
{
// 在finally块里包含q些代码
// 用以保证q接最后会被关?br /> try
{
cnn.close();
}
catch (SQLException e)
{
getServlet().log("关闭数据库连?, e);
}
}
}
注意Q如果你使用公共的BasicDataSourceQ你提供lpingQuery属性的查询语句Q如果你讄了话Q必至要能返回一行记录?br />
例子QSELECT COUNT(*) FROM VALIDTABLE
你可以把VALIDTABLE替换成你的数据库中包含的M有效的表?br />
数据库连接字W串
SQLServer2000:
driverClassName:com.microsoft.jdbc.sqlserver.SQLServerDriver
url: jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=databasename
MySql:
driverClassName:com.mysql.jdbc.Driver
url: jdbc:mysql://localhost/databasename
QM用多个数据源Q?/strong>
如果你需要在模块QModuleQ中使用多于一个的数据源,你可以在配置文g?lt;data-source>元素里包含一个key属性?br />
<data-source>
<data-source key="A" type="org.apache.commons.dbcp.BasicDataSource">
…属性配|略, 同上?br /> </data-source>
<data-source key="B" type="org.apache.commons.dbcp.BasicDataSource">
…属性配|略, 同上?br /> </data-source>
</data-source>
你代码里Q你可以通过q些key获得不同的数据源。代码如下:
?br />try
{
dataSourceA = getDataSource(request, "A");
dataSourceB = getDataSource(request, "B");
?br />
你可以根据需要ؓ每一个模块设|多个数据源。但同一模块里每个数据源的key属性必d一Q因为Struts模块pȝ是以每一个模块ؓ单位理命名I间的?/p>
]]>
常用log4j配置 [转]
常用log4j配置Q一般可以采用两U方式,.properties?xml,下面举两个简单的例子Q?/p>
一、log4j.properties
### 讄com.unmi域对应的U别INFO,DEBUG,WARN,ERROR和输出地A1QA2 ##
log4j.category.com.unmi=ERROR,A1
log4j.category.com.unmi=INFO,A2
### 一般把上面两行写如下方式,l一控制日志输出,再用log4j.logger讄包独立的输出U别 ##
log4j.rootLogger=DEBUG,A1
log4j.logger.com.unmi.special = ERROR
### 讄输出地A1QؓConsoleAppender(控制? ##
log4j.appender.A1=org.apache.log4j.ConsoleAppender
### 讄A1的输出布局格式PatterLayout,(可以灉|地指定布局模式Q?#
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
### 配置日志输出的格?#
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
### 讄输出地A2到文Ӟ文g大小到达指定寸的时候生一个新的文Ӟ##
log4j.appender.A2=org.apache.log4j.RollingFileAppender
### 文g位置##
log4j.appender.A2.File=E:/study/log4j/zhuwei.html
### 文g大小##
log4j.appender.A2.MaxFileSize=500KB
log4j.appender.A2.MaxBackupIndex=1
##指定采用html方式输出
log4j.appender.A2.layout=org.apache.log4j.HTMLLayout
二、log4j.xml
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="
<appender name="com.unmi.all" class="org.apache.log4j.RollingFileAppender"> </log4j:configuration>
对于properties文gQ一般都不用手工d载,由Log4jW一ơ初始化时自动就加蝲?/p>
import org.apache.log4j.Logger; public class Log4jApp { Logger log=Logger.getLogger("com.unmi.test"); 四、项目用log4j 在web应用中,可以配|文件的加蝲攑֜一个单独的servlet中,q在web.xml中配|该servlet在应用启动时候加载。对于在多h目中,可以l每一个h讄一个输出通道Q这样在每个人在构徏LoggerӞ用自q域名Uͼ让调试信息输出到自己的log文g中?/p>
# -X?X信息输出时左寚wQ?br /># %p:日志信息U别 关于Log4j比较全面的配|?br />LOG4J的配|之单它遍及于来多的应用中了:Log4J配置文g实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签{全套功能。择其一二用就够用了, log4j.rootLogger=DEBUG,CONSOLE,A1,im # 应用于控制台 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.FILE=org.apache.log4j.FileAppender # 应用于文件回? log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
# 发送日志给邮g log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender # 用于数据?
log4j.logger.NTlog=FATAL, A8
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender log4j.appender.im.host = mail.cybercorlin.net log4j.appender.im.layout=org.apache.log4j.PatternLayout
<!-- 讄通道ID:com.unmi.all和输出方式:org.apache.log4j.RollingFileAppender -->
<param name="File" value="E:/study/log4j/all.output.log" /><!-- 讄File参数Q日志输出文件名 -->
<param name="Append" value="false" /><!-- 讄是否在重新启动服务时Q在原有日志的基d新日?-->
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" /><!-- 讄输出文g目和格?-->
</layout>
</appender>
<appender name="com.unmi.zcw" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="E:/study/log4j/unmi.output.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="10240" /> <!-- 讄文g大小 -->
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
</layout>
</appender>
<logger name="unmi.log"> <!-- 讄域名限制Q即zcw.log域及以下的日志均输出C面对应的通道?-->
<level value="debug" /><!-- 讄U别 -->
<appender-ref ref="com.unmi.zcw" /><!-- 与前面的通道id相对?-->
</logger>
<root> <!-- 讄接收所有输出的通道 -->
<appender-ref ref="com.unmi.all" /><!-- 与前面的通道id相对?-->
</root>
三、配|文件加载方法:
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
public static void main(String[] args) {
DOMConfigurator.configure("E:/study/log4j/log4j.xml");//加蝲.xml文g
//PropertyConfigurator.configure("E:/study/log4j/log4j.properties");//加蝲.properties文g
log.info("试");
}
}
五、常用输出格?/p>
# %d{}:日志信息产生旉
# %c:日志信息所在地Q类名)
# %m:产生的日志具体信?br /># %n:输出日志信息换行
log4j.addivity.org.apache=true
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
#应用于文?
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis
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=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#应用于socket
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=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=xxx@www.xxx.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=xxx@www.xxx.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
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 ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %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
输出?000NT日志
把Log4j压羃包里的NTEventLogAppender.dll拷到WINNT\SYSTEM32目录?/p>
# APPENDER A8
log4j.appender.A8=org.apache.log4j.nt.NTEventLogAppender
log4j.appender.A8.Source=JavaTest
log4j.appender.A8.layout=org.apache.log4j.PatternLayout
log4j.appender.A8.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
#自定义Appender
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = xxx@xxx.net
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
]]>