使用時間類型?這誰不會
不就是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(
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(erator();
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方法
呵呵
弄了半天
這幫人原來都是代理
這個方法還是代理嗎?計算了一下它有
行的代碼
這麼長應該是個實干家了吧
錯!千萬不要被有些人的外表欺騙了!有些人一天上班
個小時
可夠敬業的
可有
小時在打CS
這個類就是
一上來
多行都在一個if (log
isTraceEnabled()){}裡面
log在這說明一下
Struts中使用的是Jakarta Commons Logging的包
它使用的優先級是
Log
j(
念four好像比較有意義
大概是Logger For Java的意思
我聽有的人年Log si J
感覺很別扭
呵呵)
Java
Logging API
Simple Logging
功能是依次減弱
建議在寫Action 的execute()或被execute()調用的業務方法中使用Commons Logging 來代替System
out
println()--當要你把成百上千的System
out
println()去掉的時候你就會覺得Commons Logging是個多好的東東了
它的用法是
import mons
logging
Log;
import mons
logging
LogFactory;
private/protected static Log log = LogFactory
getLog(DispatchAction
class);
如果你用的是DispatchAction
那你就不要自己定義Log的實例了
因為它已經有一個protected的Log實例
直接使用即可
使用方法是
if (log
isInfoEnabled()) {
log
Info(
some information
);
}
Logging把消息分為
種級別
debug
error
fatal
info
trace
warn
比如
你想記錄一條消息
它只是為了給用戶一個警告
則可以使用warn
為什麼在每個log
Info()前做一次判斷呢?難道如果log級別不允許Info
log
Info()仍然能Info嗎?當然不是
它的作用是提高效率
比如有個消息是計算前一萬個自然數的和(這種消息可能少見)
用直接log
Info()
int sum=
;
for(int i=
;i<
;i++){
sum+=i;
}
log
Info(
the sum of form
to
is :
_sum);
如果log
Info是不允許的
那求
個數的和就白求的
當然如果你的計算機很快或和高斯一樣聰明
直接log
Info()也每什麼問題
閒話少說
回到
多行的BeanUtils
setProperty()方法
這個方法先是處理nested屬性
也就是xxx
xxx的請求參數
我們只看看處理簡單屬性的必須過程
下面這端代碼有點長
但它只做了一件事
將字符串的請求參數轉成ActionForm的類型
比如
你在ActionForm裡有個Integer userAge
然後HTTP請求參數裡可能會有
傳人的是字符串
目標是專程Integer
首先它當然會根據userAge這個字符串查找相應的ActionForm
如果這個ActionForm有個屬性也叫userAge
然後就會把這個userAge的類型存到type裡
type的定義是
Class type = null; 得到type的代碼很長
這是因為要它考慮很多情況
例如DynaActionForm
// Convert the specified value to the required type
Object newValue = null;
if (type
isArray() && (index <
)) { // Scalar value into array
if (value == null) {
String values[] = new String[
];
values[
] = (String) value;
newValue = nvert((String[]) values
type);
} else if (value instanceof String) {
String values[] = new String[
];
values[
] = (String) value;
newValue = nvert((String[]) values
type);
} else if (value instanceof String[]) {
newValue = nvert((String[]) value
type);
} else {
newValue = value;
}
} else if (type
isArray()) { // Indexed value into array
if (value instanceof String) {
newValue = nvert((String) value
type
getComponentType());
} else if (value instanceof String[]) {
newValue = nvert(((String[]) value)[
]
type
getComponentType());
} else {
newValue = value;
}
} else { // Value into scalar
if ((value instanceof String) || (value == null)) {
newValue = nvert((String) value
type);
} else if (value instanceof String[]) {
newValue = nvert(((String[]) value)[
]
type);
} else if (ConvertUtils
lookup(value
getClass()) != null) {
newValue = nvert(value
toString()
type);// Here is my program
s break point
} else {
newValue = value;
}
}
最後是
調用PropertyUtils的一些方法設置值
下面代碼的第一種情況是有索引的
即你在請求參數裡傳了field[
]=
之類的參數
第二種是Map類型的
傳的是map(key)=value之類的參數
最一般的就是調用第三個方法
if (index >=
) {
PropertyUtils
setIndexedProperty(target
propName
index
newValue);
} else if (key != null) {
PropertyUtils
setMappedProperty(target
propName
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28836.html