Digester
学习日记
Digester是apache的一个开源项目,他可以根据解析的XML生成对应的对象,可以很方便的从工作流的定义中生成JAVA实列。
举列我们有个定义工作流的XML
<
workflow
>
<
activites
>
<
start
name
=
"start"
id
=
"0001"
nextid
=
"0002,0003"
>
</
start
>
<
task
name
=
"test1"
id
=
"0002"
nextid
=
"0004"
>
</
task
>
<
task
name
=
"test2"
id
=
"0003"
nextid
=
"0004"
>
</
task
>
<
join
name
=
"join"
id
=
"0004"
nextid
=
"0005"
>
</
join
>
<
end
name
=
"end"
id
=
"0005"
>
</
end
>
</
activites
>
</
workflow
>
从这个
XML
中我们可以很容易的看出各接点之间的关系(这个是一个工作流定义)。
现在
digester
可以根据我们定义的
XML
生成
JAVA
是实列。首先要定义一个
digester
解释规则的
xml.
<?xml version="1.0"?>
<digester-rules>
<pattern value="workflow">
<object-create-rule
classname="com.maomao.workflow.model.WorkFlow"/>
<!--set-properties-rule /-->
<set-next-rule methodname="setWorkFlow" />
<pattern value="activites/start">
<object-create-rule
classname="com.maomao.workflow.model.Start"/>
<set-properties-rule />
<set-next-rule methodname="addActivity" />
</pattern>
<pattern value="activites/task">
<object-create-rule
classname="com.maomao.workflow.model.Task"/>
<set-properties-rule />
<set-next-rule methodname="addActivity" />
</pattern>
<pattern value="activites/join">
<object-create-rule
classname="com.maomao.workflow.model.Join"/>
<set-properties-rule />
<set-next-rule methodname="addActivity" />
</pattern>
<pattern value="activites/end">
<object-create-rule
classname="com.maomao.workflow.model.End"/>
<set-properties-rule />
<set-next-rule methodname="addActivity" />
</pattern>
</pattern>
</digester-rules>
Digester解析原XML会按照这个定义规则解释。这个规则有几个地方需要说下
<object-create-rule
>
这个标签是创建一个
java
实列
<set-properties-rule />
会根据解析文件的属性调用生成类的
setXXX
方法,列如要解析的
XML
中有
name,id,nextid,
那么生成的类里如果有这些属性将会被调用他们的
set
方法。
<set-next-rule methodname="addActivity" />
栈顶元素的下面一个元素(对象)的方法。
注意:
digester
解析
XML
和他们大部分解析技术都一样,都用堆栈。当
digester
遇到一个
<
他会把这个元素压入堆栈,遇到
/>
就会把元素弹出堆栈。
所以上面的
xml
解析完以后就等于
WorkFlow flow = new WorkFlow();
flow.addActivity(start);
flow.addActivity(task1);
flow.addActivity(task2);
flow.addActivity(join);
flow.addActivity(end);
然后调用
digester
解析即可
:
java.net.URL rulesURL = this.getClass().getClassLoader().getResource("com/maomao/workflow/parser/rules.xml");
Digester d = DigesterLoader.createDigester(rulesURL);
d.push(this);
d.parse(new StringReader(xml));
buildRelation();
以上代码和本人的工程有点关系,看不明白属于正常。嘿嘿
Log4j
学习日记
如何配置
Log4j
- 用BasicConfigurator 对Log4j 进行配置,入门级的配置方式:
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
......
public class Log4jTest {
private static Logger logger = Logger.getLogger(Log4jTest.class.getName());
......
public static void main(String[] args) {
BasicConfigurator.configure();
logger.info("log4j has been configurated with BasicConfigurator.configuration successfully!");
}
}
import org.apache.log4j.Logger;
......
public class Log4jTest {
private static Logger logger = Logger.getLogger(Log4jTest.class.getName());
......
public static void main(String[] args) {
BasicConfigurator.configure();
logger.info("log4j has been configurated with BasicConfigurator.configuration successfully!");
}
}
运行后可以得到类似于下面的结果:
0 [main] INFO Log4jTest - log4j has been configed with BasicConfigurator.configure() successfully!
- 用配置文件对Log4j 进行配置,非常灵活的一种方式:
# For the general syntax of property based configuration files see the
# documenation of org.apache.log4j.PropertyConfigurator.
# The root category uses the appender called A1. Since no priority is
# specified, the root category assumes the default priority for root
# which is DEBUG in log4j. The root category is the only category that
# has a default priority. All other categories need not be assigned a
# priority in which case they inherit their priority from the
# hierarchy.
log4j.rootCategory=INFO, A1, A2
# A1 is set to be a FileAppender which outputs to the file
# "factor.log". Start the server NumberCruncherServer and two
# NumberCruncherClients, and ask to factor two numbers
# near-simultaneously. Notice that the log output from these two
# requests are logged in the file factor.log. Nevertheless, the logs
# of these requests can still be distinguished given their distinct
# nested diagnostic contexts.
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=WEB-INF/logs/portal.log
log4j.appender.A1.DatePattern='.'yyyy-MM-dd
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A2=org.apache.log4j.ConsoleAppender
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
# Note the %x conversion specifier for NDC printing.
# %d date time
# %-5p debug level
# %m messages
# %l class with method and line number (slowly! dubug only, on release use %c{2} in release version)
# %n /n or /r/n
#debug version
log4j.appender.A1.layout.ConversionPattern=%d [%-5p] %l - %m%n
log4j.appender.A2.layout.ConversionPattern=%d [%-5p] %l - %m%n
#release version
# log4j.appender.A1.layout.ConversionPattern=%d [%-5p] %c{2} - %m%n
# documenation of org.apache.log4j.PropertyConfigurator.
# The root category uses the appender called A1. Since no priority is
# specified, the root category assumes the default priority for root
# which is DEBUG in log4j. The root category is the only category that
# has a default priority. All other categories need not be assigned a
# priority in which case they inherit their priority from the
# hierarchy.
log4j.rootCategory=INFO, A1, A2
# A1 is set to be a FileAppender which outputs to the file
# "factor.log". Start the server NumberCruncherServer and two
# NumberCruncherClients, and ask to factor two numbers
# near-simultaneously. Notice that the log output from these two
# requests are logged in the file factor.log. Nevertheless, the logs
# of these requests can still be distinguished given their distinct
# nested diagnostic contexts.
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=WEB-INF/logs/portal.log
log4j.appender.A1.DatePattern='.'yyyy-MM-dd
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A2=org.apache.log4j.ConsoleAppender
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
# Note the %x conversion specifier for NDC printing.
# %d date time
# %-5p debug level
# %m messages
# %l class with method and line number (slowly! dubug only, on release use %c{2} in release version)
# %n /n or /r/n
#debug version
log4j.appender.A1.layout.ConversionPattern=%d [%-5p] %l - %m%n
log4j.appender.A2.layout.ConversionPattern=%d [%-5p] %l - %m%n
#release version
# log4j.appender.A1.layout.ConversionPattern=%d [%-5p] %c{2} - %m%n
有了上面的配置文件后,可以通过以下任意一种方式对其进行装载:
- 让Log4j自动装载配置文件
将上面的文件命名为log4j.properties,并保存到WEB-INF/classes/ 目录下,这样当第一次调用Logger.getLogger(SomeClass.class.getName()); 时,Log4j 就会自动装载该配置文件对log 系统进行初始化。 - 用系统变量指定配置文件的位置
如果不想把配置文件放到WEB-INF/clases/ 目录下,或者不想把配置文件命名为log4j.properties 那么就可以通过系统变量log4j.configuration来对其进行自定义,例如:
-Dlog4j.configuration=file:/D:/projects/someproject/WEB-INF/log4j.properties
用指定位置的文件进行配置
-Dlog4j.configuration=foo.txt
用WEB-INF/classes/目录下的foo.txt 进行配置 - 用PropertyConfigurator 读取配置文件
- 让Log4j自动装载配置文件
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Logger;
......
public class Log4jTestServlet {
private static Logger logger = Logger.getLogger(Log4jTestServlet.class.getName());
......
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
String file = getRealPath(getInitParameter("log4j-init-file"));
PropertyConfigurator.configure(file);
/*
*PropertyConfigurator.configure(Properties);
*PropertyConfigurator.configure(URL);
*PropertyConfigurator.configureAndWatch(file, 30); //delay 30 second
*/
logger.info("log4j has been configurated with PropertyConfigurator.configuration successfully!");
}
}
import org.apache.log4j.Logger;
......
public class Log4jTestServlet {
private static Logger logger = Logger.getLogger(Log4jTestServlet.class.getName());
......
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
String file = getRealPath(getInitParameter("log4j-init-file"));
PropertyConfigurator.configure(file);
/*
*PropertyConfigurator.configure(Properties);
*PropertyConfigurator.configure(URL);
*PropertyConfigurator.configureAndWatch(file, 30); //delay 30 second
*/
logger.info("log4j has been configurated with PropertyConfigurator.configuration successfully!");
}
}
参考文档
学习总结
今天主要学习怎么从xml解析数据对象。用到了digester,这个工具解析工作流中的流程定义非常方便,值得一学。今天对Log4j有了更一步的了解。