|
使用时间类型,这谁不会,不就是java.util下的几个类吗,再加上java.sql和java.text下的几个类,这会有什么问题吗?Struts要是连时间都处理不了,那还能干嘛?
在实际应用中,我就发现Struts确实连有些简单的时间都处理不了(不知是我使用的方法不对还是Struts确实没有考虑到)。顺便你也能了解Struts是怎么把form里的请求参数populate到ActionForm里面的。
今天下午同事告诉我把有java.util.Date类型属性的类存入数据库时出错,把这个属性删除就没有问题了。当时我就想到是RequestProcessor在processPopulate()时出错了,因此在它的这个方法设了断点并跟踪了进去。
当然,它最先要调用ActionForm的reset()方法,然后调用实际处理populate(将请求参数传给ActionForm)的RequestUtils.populate()方法。RequestUtils的这个静态方法最先是处理Multipart的(即文件上传等多部分)的方法,然后将所有的请求都放在叫properties的HashMap里并循环处理它:
names = request.getParameterNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String stripped = name;
if (prefix != null)
{
if (!stripped.startsWith(prefix))
{
continue;
}
stripped = stripped.substring
(prefix.length());
}
if (suffix != null)
{
if (!stripped.endsWith(suffix))
{
continue;
}
stripped = stripped.substring
(0, stripped.length()
- suffix.length());
}
if (isMultipart)
{
properties.put(stripped,
multipartParameters.get(name));
}
else
{
properties.put
(stripped, request.getParameterValues(name));
}
}
|
实际处理它们的是下面的:BeanUtils.populate(bean, properties);其中bean就是接受数据的ActionForm,而properties里面则是所有的请求的键-值对(键和值都是字符串,http协议的特点)。
再看看BeanUtils的静态(类)方法populate是怎么处理的:
// Loop through the property
name/value pairs to be set
Iterator names =
properties.keySet().iterator();
while (names.hasNext())
{
// Identify the property name
and value(s) to be assigned
String name = (String) names.next();
if (name == null)
{
continue;
}
Object value = properties.get(name);
// Perform the assignment for this property
setProperty(bean, name, value);
}
|
它是循环所有的请求参数,把实际的工作又交给了setProperty方法。这个类就是:一上来20多行都在一个if (log.isTraceEnabled()){}里面。建议在写Action 的execute()或被execute()调用的业务方法中使用Commons Logging 来代替System.out.println()——当要你把成百上千的System.out.println()去掉的时候你就会觉得Commons Logging有多好用了。它的用法是:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private/protected static Log log =
LogFactory.getLog(DispatchAction.class);
|
如果你用的是DispatchAction,那你就不要自己定义Log的实例了,因为它已经有一个protected的Log实例,直接使用即可。使用方法是:
if (log.isInfoEnabled())
{
log.Info("some information.");
}
|
Logging把消息分为6种级别,debug,error,fatal,info,trace,warn。比如,你想记录一条消息,它只是为了给用户一个警告,则可以使用warn。为什么在每个log.Info()前做一次判断呢?难道如果log级别不允许Info,log.Info()仍然能Info吗?当然不是。它的作用是提高效率。
比如有个消息是计算前一万个自然数的和(这种消息可能少见)。用直接log.Info()
int sum=0;
for(int i=0;i<10000;i++)
{
sum+=i;
}
log.Info("the sum of form 1 to 10000 is : "_sum);
|
如果log.Info是不允许的,那求10000个数的和就白求的。当然如果你的计算机很快或和高斯一样聪明,直接log.Info()也每什么问题。
1
2
下一页>>
|