BeanUtils.copyProperties 與 PropertyUtils.copyProperties 用法及區別
一、簡介:
BeanUtils提供對 Java反射和自省API的包裝。其主要目的是利用反射機制對JavaBean的屬性進行處理。我們知道,一個JavaBean通常包含了大量的屬性,很 多情況下,對JavaBean的處理導致大量get/set代碼堆積,增加了代碼長度和閱讀代碼的難度。
二、用法:
BeanUtils是這個包里比較常用的一個工具類,這里只介紹它的copyProperties()方法。該方法定義如下:
public static void copyProperties(java.lang.Object dest,java.lang.Object orig)
throws java.lang.IllegalAccessException,
java.lang.reflect.InvocationTargetException
如 果你有兩個具有很多相同屬性的JavaBean,一個很常見的情況就是Struts里的PO對象(持久對象)和對應的ActionForm,例如 Teacher和TeacherForm。我們一般會在Action里從ActionForm構造一個PO對象,傳統的方式是使用類似下面的語句對屬性逐 個賦值:
//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//構造Teacher對象
Teacher teacher=new Teacher();
//賦值
teacher.setName(teacherForm.getName());
teacher.setAge(teacherForm.getAge());
teacher.setGender(teacherForm.getGender());
teacher.setMajor(teacherForm.getMajor());
teacher.setDepartment(teacherForm.getDepartment());
//持久化Teacher對象到數據庫
HibernateDAO=;
HibernateDAO.save(teacher);
而使用BeanUtils后,代碼就大大改觀了,如下所示:
//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//構造Teacher對象
Teacher teacher=new Teacher();
//賦值
BeanUtils.copyProperties(teacher,teacherForm);
//持久化Teacher對象到數據庫
HibernateDAO=;
HibernateDAO.save(teacher);
如 果Teacher和TeacherForm間存在名稱不相同的屬性,則BeanUtils不對這些屬性進行處理,需要程序員手動處理。例如 Teacher包含modifyDate(該屬性記錄最后修改日期,不需要用戶在界面中輸入)屬性而TeacherForm無此屬性,那么在上面代碼的 copyProperties()后還要加上一句:
teacher.setModifyDate(new Date());
怎 么樣,很方便吧!除BeanUtils外還有一個名為PropertyUtils的工具類,它也提供copyProperties()方法,作用與 BeanUtils的同名方法十分相似,主要的區別在于后者提供類型轉換功能,即發現兩個JavaBean的同名屬性為不同類型時,在支持的數據類型范圍 內進行轉換,而前者不支持這個功能,但是速度會更快一些。BeanUtils支持的轉換類型如下:
* java.lang.BigDecimal
* java.lang.BigInteger
* boolean and java.lang.Boolean
* byte and java.lang.Byte
* char and java.lang.Character
* java.lang.Class
* double and java.lang.Double
* float and java.lang.Float
* int and java.lang.Integer
* long and java.lang.Long
* short and java.lang.Short
* java.lang.String
* java.sql.Date
* java.sql.Time
* java.sql.Timestamp
這里要注意一點,java.util.Date是不被支持的,而它的子類java.sql.Date是被支持的。因此如果對象包含時間類型的屬性,且希望被轉換的時候,一定要使用java.sql.Date類型。否則在轉換時會提示argument mistype異常。
三、優缺點:
Apache Jakarta Commons項目非常有用。我曾在許多不同的項目上或直接或間接地使用各種流行的commons組件。其中的一個強大的組件就是BeanUtils。我 將說明如何使用BeanUtils將local實體bean轉換為對應的value 對象:
BeanUtils.copyProperties(aValue, aLocal)
上 面的代碼從aLocal對象復制屬性到aValue對象。它相當簡單!它不管local(或對應的value)對象有多少個屬性,只管進行復制。我們假設 local對象有100個屬性。上面的代碼使我們可以無需鍵入至少100行的冗長、容易出錯和反復的get和set方法調用。這太棒了!太強大了!太有用 了!
現在,還有一個壞消息:使用BeanUtils的成本驚人地昂貴!我做了一個簡單的測試,BeanUtils所花費的時間要超過取數 據、將其復制到對應的 value對象(通過手動調用get和set方法),以及通過串行化將其返回到遠程的客戶機的時間總和。所以要小心使用這種威力!
posted @
2009-11-29 21:17 junly 閱讀(271) |
評論 (0) |
編輯 收藏
在我們應用Freemarker過程中,經常會操作例如字符串,數字,集合等,卻不清楚Freemrker有沒有類似于Java一樣有相關的類及方法。在本文當中,我將向大家詳細的介紹Freemarke的內置函數及用法,以便能幫助大家更熟練的應用Freemarker完成項目開發。
一、 Sequence的內置函數
1. sequence?first 返回sequence的第一個值。
2. sequence?last 返回sequence的最后一個值。
3. sequence?reverse 將sequence的現有順序反轉,即倒序排序
4. sequence?size 返回sequence的大小
5. sequence?sort 將sequence中的對象轉化為字符串后順序排序
6. sequence?sort_by(value) 按sequence中對象的屬性value進行排序
注意:Sequence不能為null。以上方法在我的另一篇博客Freemarker中如何遍歷List有詳細的應用,感興趣的朋友可以參考。
二、 Hash的內置函數
1. hash?keys 返回hash里的所有key,返回結果為sequence
2. hash?values 返回hash里的所有value,返回結果為sequence
例如:
<#assign user={“name”:“hailang”, “sex”:“man”}>
<#assign keys=user?keys>
<#list keys as key>
${key}=${user[key]}
</#list>
三、 操作字符串函數
1. substring(start,end)從一個字符串中截取子串
start:截取子串開始的索引,start必須大于等于0,小于等于end
end: 截取子串的長度,end必須大于等于0,小于等于字符串長度,如果省略該參數,默認為字符串長度。
例子:
${‘str’?substring(0)}à結果為str
${‘str’?substring(1)}à結果為tr
${‘str’?substring(2)}à結果為r
${‘str’?substring(3)}à結果為
${‘str’?substring(0,0)}à結果為
${‘str’?substring(0,1)}à結果為s
${‘str’?substring(0,2)}à結果為st
${‘str’?substring(0,3)}à結果為str
2. cap_first 將字符串中的第一個單詞的首字母變為大寫。
${‘str’?cap_first}à結果為Str
3. uncap_first將字符串中的第一個單詞的首字母變為小寫。
${‘Str’?cap_first}à結果為str
4. capitalize將字符串中的所有單詞的首字母變為大寫
${‘str’? capitalize}à結果為STR
5. date,time,datetime將字符串轉換為日期
例如:
<#assign date1=”2009-10-12”?date(“yyyy-MM-dd”)>
<#assign date2=”9:28:20”?time(“HH:mm:ss”)>
<#assign date3=” 2009-10-12 9:28:20”?time(“HH:mm:ss”)>
${date1}à結果為2009-10-12
${date2}à結果為9:28:20
${date3}à結果為2009-10-12 9:28:20
注意:如果指定的字符串格式不正確將引發錯誤。
6. ends_with 判斷某個字符串是否由某個子串結尾,返回布爾值。
${“string”?ends_with(“ing”)?string} 返回結果為true
注意:布爾值必須轉換為字符串才能輸出
7. html 用于將字符串中的<、>、&和“替換為對應得<>":&
8. index_of(substring,start)在字符串中查找某個子串,返回找到子串的第一個字符的索引,如果沒有找到子串,則返回-1。
Start參數用于指定從字符串的那個索引處開始搜索,start為數字值。
如果start大于字符串長度,則start取值等于字符串長度,如果start小于0, 則start取值為0。
${“string”?index_of(“in”) à結果為3
${“string”?index_of(“ab”) à結果為-1
9. length返回字符串的長度 ${“string”?length}à結果為6
10. lower_case將字符串轉為小寫
${“STRING”?lower_case}à結果為string
11. upper_case將字符串轉為大寫
${“string”?upper_case}à結果為STRING
12. contains 判斷字符中是否包含某個子串。返回布爾值
${“string”?contains(“ing”)?string} à結果為true
注意:布爾值必須轉換為字符串才能輸出
13. number將字符串轉換為數字
${“111.11”?number}à結果為111.11
14. replace用于將字符串中的一部分從左到右替換為另外的字符串。
${“strabg”?replace(“ab”,”in”)} à結果為string
15. split使用指定的分隔符將一個字符串拆分為一組字符串
<#list “This|is|split”?split(“|”) as s>
${s}
</#list>
結果為:
This
is
split
16. trim 刪除字符串首尾空格 ${“ String ”?trim} à結果為String
四、 操作數字
1. c 用于將數字轉換為字符串
${123?c} à結果為123
2. string用于將數字轉換為字符串
Freemarker中預訂義了三種數字格式:number,currency(貨幣)和percent(百分比)其中number為默認的數字格式轉換
例如:
<#assign tempNum=20>
${tempNum}
${tempNum?string.number}或${tempNum?string(“number”)} à結果為20
${tempNum?string.currency}或${tempNum?string(“currency”)} à結果為¥20.00
${tempNum?string. percent}或${tempNum?string(“percent”)} à結果為2,000%
五、 操作布爾值
string 用于將布爾值轉換為字符串輸出
true轉為“true”,false轉換為“false”
foo?string(“yes”,”no”)如果布爾值是true,那么返回“yes”,否則返回no
通過上面對開發中常用的Freemarker內置函數及用法的介紹,相信您已經對這些函數的有了一定的了解,希望本文能對您的開發有所幫助。由于時間倉促,有不足之處請您批評指正。
posted @
2009-11-25 11:21 junly 閱讀(1585) |
評論 (0) |
編輯 收藏
集合
集合以方括號包括,各集合元素之間以英文逗號","分隔,看如下的例子:
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x>
${x}
</#list>
輸出結果是:
星期一
星期二
星期三
星期四
星期五
星期六
星期天
除此之外,集合元素也可以是表達式,例子如下:
[2 + 2, [1, 2, 3, 4], "whatnot"]
還可以使用數字范圍定義數字集合,如2..5等同于[2, 3, 4, 5],但是更有效率.注意,使用數字范圍來定義集合時無需使用方括號,數字范圍也支持反遞增的數字范圍,如5..2
Map對象
Map對象使用花括號包括,Map中的key-value對之間以英文冒號":"分隔,多組key-value對之間以英文逗號","分隔.下面是一個例子:
{"語文":78, "數學":80}
Map對象的key和value都是表達式,但是key必須是字符串
輸出變量值
FreeMarker的表達式輸出變量時,這些變量可以是頂層變量,也可以是Map對象中的變量,還可以是集合中的變量,并可以使用點(.)語法來訪問Java對象的屬性.下面分別討論這些情況
1,頂層變量
所謂頂層變量就是直接放在數據模型中的值,例如有如下數據模型:
Map root = new HashMap(); //創建數據模型
root.put("name","annlee"); //name是一個頂層變量
對于頂層變量,直接使用${variableName}來輸出變量值,變量名只能是字母,數字,下劃線,$,@和#的組合,且不能以數字開頭號.為了輸出上面的name的值,可以使用如下語法:
${name}
2,輸出集合元素
如果需要輸出集合元素,則可以根據集合元素的索引來輸出集合元素,集合元素的索引以方括號指定.假設有索引:
["星期一","星期二","星期三","星期四","星期五","星期六","星期天"].該索引名為week,如果需要輸出星期三,則可以使用如下語法:
${week[2]} //輸出第三個集合元素
此外,FreeMarker還支持返回集合的子集合,如果需要返回集合的子集合,則可以使用如下語法:
week[3..5] //返回week集合的子集合,子集合中的元素是week集合中的第4-6個元素
3,輸出Map元素
這里的Map對象可以是直接HashMap的實例,甚至包括JavaBean實例,對于JavaBean實例而言,我們一樣可以把其當成屬性為key,屬性值為value的Map實例.為了輸出Map元素的值,可以使用點語法或方括號語法.假如有下面的數據模型:
Map root = new HashMap();
Book book = new Book();
Author author = new Author();
author.setName("annlee");
author.setAddress("gz");
book.setName("struts2");
book.setAuthor(author);
root.put("info","struts");
root.put("book", book);
為了訪問數據模型中名為struts2的書的作者的名字,可以使用如下語法:
book.author.name //全部使用點語法
book["author"].name
book.author["name"] //混合使用點語法和方括號語法
book["author"]["name"] //全部使用方括號語法
使用點語法時,變量名字有頂層變量一樣的限制,但方括號語法沒有該限制,因為名字可以是任意表達式的結果.
集合連接運算符
這里所說的集合運算符是將兩個集合連接成一個新的集合,連接集合的運算符是+,看如下的例子:
<#list ["星期一","星期二","星期三"] + ["星期四","星期五","星期六","星期天"] as x>
${x}
</#list>
輸出結果是:星期一 星期二 星期三 星期四 星期五 星期六 星期天
Map連接運算符
Map對象的連接運算符也是將兩個Map對象連接成一個新的Map對象,Map對象的連接運算符是+,如果兩個Map對象具有相同的key,則右邊的值替代左邊的值.看如下的例子:
<#assign scores = {"語文":86,"數學":78} + {"數學":87,"Java":93}>
語文成績是${scores.語文}
數學成績是${scores.數學}
Java成績是${scores.Java}
輸出結果是:
語文成績是86
數學成績是87
Java成績是93
posted @
2009-11-25 10:06 junly 閱讀(2595) |
評論 (0) |
編輯 收藏
Messages: No result defined for action com.xxx.action.SomeAction and result input
---------------------------------------------------------------------------------------------------------------------------
癥狀: action中無法正常進行跳轉.
原因: 驗證值時驗證報錯.
解決辦法:
1) 給 Action 加入 input 的結果;
2) 去除所有證驗相關的攔截器,包括默認的validation
調試方法:在 input 中加入調試
<s:fielderror/>
<s:debug />
<a href="javascript:void(0);" onclick="toggleDebug('debug');return false;">[調試信息]</a>
可顯示下列信息:
Invalid field value for field "attachment".
fieldErrors {attachment=[Invalid field value for field "attachment".]}
3) Action 不再繼承自 ActionSupport(里面有 ValidationAware 接口), 而轉而只實現 Action 接口即可.
posted @
2009-11-20 16:57 junly 閱讀(3012) |
評論 (0) |
編輯 收藏
轉:
版本號: Eclipse SDK Version: 3.2.0
現象:啟動或者import新的project時,Eclipse會自動進行building workspace...這個操作,然后一直持續這個狀態不再響應其他事件操作。有時也會在10幾分鐘后完成這個操作,但是費時嚴重。
解決方法:查了很多資料,最后在一個BBS上查到可能是啟動參數設置的問題
(http://www.myeclipseide.com/PNphpBB2+file-viewtopic-t-8253.html)
解決方法:
方法1.如帖子中添加啟動參數參數:-vmargs -Xmx256m(效果并不明顯)
方法2.關閉自動構建工作區: project -> build Auto….. (效果并不明顯)
在Eclipse啟動時加入參數:
-vmargs -Xmx512M (效果明顯)
重啟,building workspace...在短時間內結束,一切正常,具體原因可參考上面網址中的回答,可以給人很多提示,呵呵,看來還是多查資料有好處。寫出來希望有相同現象的同仁可以參考解決。
原因詳見:http://www.myeclipseide.com/PNphpBB2+file-viewtopic-t-8253.html
關閉其自動Build,然后增大你的內存為512M以上,Eclipse開始內存損耗比JBuilder小,后來同樣厲害,注意開大Eclipse內存,這里有一個辦法防止outofmemeory:
http://forum.java.sun.com/thread.jspa?threadID=587273&tstart=0
posted @
2009-11-12 15:15 junly 閱讀(1414) |
評論 (0) |
編輯 收藏
1 Freemarker網站靜態化的實現(轉)
首頁:
1.<body>
2.<div id="wrap">
3. <!--頭部開始-->
4. <jsp:include page="/html/top.html" flush="true"></jsp:include>
5. <!--頭部結束-->
6. <!--導航開始-->
7. <jsp:include page="/html/channel.html" flush="true"></jsp:include>
8. <!--導航結束-->
9. <jsp:include page="/html/center.html" flush="true"></jsp:include>
10. <!--友情連接開始-->
11. <jsp:include page="/html/index_link.html" flush="true"></jsp:include>
12. <!--友情結束-->
13. <!--底部開始-->
14. <jsp:include page="/html/bottom.html" flush="true"></jsp:include>
15. <!--底部結束-->
16.</div>
17.</body>
整個網站首頁的基本結構是通過jsp的include標簽將所有通過freemarker生成的靜態頁面組織起來。后臺控制各個部分的靜態頁生成。這樣做將首頁進行了拆分,便于了靜態頁面的維護,當我們需要生成“友情鏈接”部分的時候就只生成友情鏈接部分,而不需要將整個頁面都從新生成一次。
以下是我生成靜態頁最核心的方法,使用freemarker。

/** *//**
* 生成靜態頁面主方法
* @param context ServletContext
* @param data 一個Map的數據結果集
* @param templatePath ftl模版路徑
* @param targetHtmlPath 生成靜態頁面的路徑
*/

public static void crateHTML(ServletContext context,Map<String,Object> data,String templatePath,String targetHtmlPath)
{
Configuration freemarkerCfg = new Configuration();
//加載模版
freemarkerCfg.setServletContextForTemplateLoading(context, "/");
freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");

try
{
//指定模版路徑
Template template = freemarkerCfg.getTemplate(templatePath,"UTF-8");
template.setEncoding("UTF-8");
//靜態頁面路徑
String htmlPath = context.getRealPath("/html")+"/"+targetHtmlPath;
File htmlFile = new File(htmlPath);
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
//處理模版
template.process(data, out);
out.flush();
out.close();

} catch (Exception e)
{
e.printStackTrace();
}
其實很簡單,只要Google一下就有很多這方面的代碼。我也是Google的代碼然后自己再根據實際情況修改。簡單說明一下參數:
ServletContext :這個不用說了吧。做java web的應該都知道,只不過struts2中這樣獲取ServletActionContext.getServletContext()
Map<String,Object> data : 模版的數據來源。freemarker通過一個Map給ftl模版送數據。
現在已友情鏈接為列子詳細介紹靜態頁面如何生成。其他模塊以此類推。
String templatePath : ftl所在的路徑。我這里相對于網站的一個相對路徑然后通過ServerContext獲取絕對路徑。
String targetHtmlPath : 最后生成靜態頁的路徑:我這里相對于網站的一個相對路徑然后通過ServerContext獲取絕對路徑。
友情鏈接根據這段代碼<jsp:include page="/html/index_link.html" flush="true"></jsp:include>我們需要freemarker生成一個index_link.html文件。友情鏈接數據來源通過數據庫查詢獲取。
然后再寫一個方法專門生成友情鏈接靜態頁面:

/** *//**
* 生成友情鏈接的靜態頁index_link.html
* @param context
* @param data
*/

public static void createIndexFriendLink(ServletContext context,Map<String,Object> data)
{
crateHTML(context,data,"index_link.ftl","index_link.html");
此方法調用上面的createHTML方法。
然后根據以上方法我們就可以再Struts2的action里面從數據庫查詢數據放入map調用createIndexFriendLink()方法生成靜態頁了。
這是action中的一個方法:

/** *//**
* 生成友情鏈接靜態頁index_link.html
* @return
*/

public String createLink()
{
//權限驗證
if(! this.isAccess())
return "error";

try
{
//得到友情鏈接
List links = friendLinkDAO.findAll();
//準備數據
HashMap<String,Object> data = new HashMap<String,Object>();
data.put("links", links);
//調用靜態頁面方法
HTML.createIndexFriendLink(ServletActionContext.getServletContext(), data);
addActionMessage("靜態頁面生成成功!");
return "message";

}catch(Exception e)
{
e.printStackTrace();
return "failure";
}
}
List links = friendLinkDAO.findAll();通過spring注入action的hiberate DAO獲取數據給list然后通過以下代碼
HashMap<String,Object> data = new HashMap<String,Object>();
data.put("links", links);
準備數據調用createIndexFriendLink()方法。
以下是:ftl模版源碼:
<#if links?size != 0>
<div class="link">
<strong>友情鏈接:</strong>
<#list links as link>
<a href="${link.linkUrl}" target="_blank" title="${link.linkName}">${link.linkName}</a>
</#list>
</div>
<#else>
<div class="link"></div>
</#if>
這樣友情鏈接靜態頁就生成了。然后其他靜態頁依此葫蘆畫瓢。
posted @
2009-11-06 17:52 junly 閱讀(1112) |
評論 (2) |
編輯 收藏
import java.io.*;

public class ReadMAC
{
public static String physicalAddress = "read MAC error!";

public ReadMAC()
{
}

public static String checkPhysicalAddress()
{

try
{
String line;
Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

while ( (line=bufferedReader.readLine()) != null)
{

if(line.indexOf("Physical Address. . . . . . . . . :") != -1)
{

if(line.indexOf(":") != -1)
{
physicalAddress = line.substring(line.indexOf(":")+2);
break; //找到MAC,推出循環
}
}
}
process.waitFor();

}catch(Exception e)
{
e.printStackTrace();
}
return physicalAddress;
}

public static void main(String[] args)
{
System.out.println("本機的MAC地址是: "+ ReadMAC.checkPhysicalAddress());
}
}
1 引言
用Java編寫的程序,可以很方便地運行在各種平臺的環境。但在實際的開發過程中,有時不得不涉及一些底層的編程。比如為了防止軟件盜用,我們希望軟件只能在指定計算機上運行,所以需要程序讀取該機區分于其它計算機的硬件特征,如MAC地址等。作為一種跨平臺語言,給Java語言提出了挑戰。本文正是針對該問題,提出一種直接用純Java語言,讀去MAC地址的編程方法。
我們知道,在每一個Java應用程序中都存在著一個與其運行環境相聯系的Runtime對象。該對象可執行外部命令、查可用內存等。而多數操作系統都提供有查詢該機MAC地址的命令。如在Microsoft的操作系統中,命令IPCONFIG等。本文的思路是在程序中運行一個外部命令,將該命令的運行結果作為一個流(Stream),讀取并分析之,進而實現獲取MAC地址的目的。
2 Runtime類
在每一個Java 應用程序里面,都有惟一的一個Runtime 對象。通過這個Runtime 對象,應用程序可以與其運行環境發生相互作用。
一般不實例化一個Runtime對象。但是可以通過調用靜態方法Runtime.getRuntime( )而獲得對當前Runtime對象的引用。Runtime 類的大多數方法是實例方法。
Runtime 對象的作用主要有:執行外部命令;返回空閑內存;運行垃圾回收器;加載動態庫等。
Applets和其他不可信賴的程序由于沒有引起一個安全異常(SecurityException)而不能調用任何的Runtime方法。
下面的例子演示了怎樣使用Runtime 對象運行一個外部命令。
以下是引用片段:
:
Process process = Runtime.getRuntime().exec("cmd.exe /c dir");
process.waitFor(); |
Runtime.getRuntime()返回當前應用程序的Runtime對象,該對象的exec()方法指示Java虛擬機創建一個子進程執行指定的可執行程序,并返回與該子進程對應的Process對象實例。通過Process可以控制該子進程的執行或獲取該子進程的信息。第二條語句的目的是等待子進程完成后再往下執行。
上面的程序在運行時會執行dir命令。如果在Windows95/98下,命令格式可以寫成"command.exe /c dir"。開關/C指明后面跟隨的字符串是命令,并在執行命令后關閉DOS 窗口。
方法exec還可以打開一個不可執行的程序,但該文件存在關聯的應用程序。以打開一個word文檔Mydoc.doc文件為例,Java中可以有以下兩種寫法:
以下是引用片段:
exec(""cmd /E:ON /c start MyDoc.doc"");
exec(" c:Program FilesMicrosoft Officeofficewinword.exe .mydoc.doc"); |
在第一種方式中,被執行的命令是start Mydoc.doc,開關E:ON 指定DOS 命令處理器允許命令擴展,而start 命令會開啟一個單獨的窗口執行所提供的命令。
執行一個有標準輸出的DOS命令,程序執行完后往往不會自動關閉,從而導致Java應用程序阻塞在waitfor( )。導致該現象的原因可能是該命令的輸出比較多,而運行窗口的輸出緩沖區不夠大。解決的辦法是,利用Java的Process類提供的方法讓Java虛擬機截獲DOS運行的標準輸出,在waitfor()命令之前讀出該緩沖區的內容。以運行命令dir為例,典型的程序如下:
以下是引用片段:
:
String line;
Process process = Runtime.getRuntime().exec("cmd /c dir");
BufferedReader bufferedReader = new BufferedReader ( new InputStreamReader(process.getInputStream()));
while ( (line = bufferedReader.readLine()) != -1) System. out.println(line);
process.waitFor( );
:3 Process |
Runtime.exec方法創建一個本機進程,并返回 Process 子類的一個實例,該實例可用來控制進程并獲取相關信息。
抽象類Process封裝了一個進程(process),一個正在執行的程序。它主要被當作由Runtime類中的exec( )方法所創建的對象的類型的超類。在抽象類Process中,主要包含了如下一些抽象方法。
InputStream getInputStream( ):返回一個從進程的out輸出流中讀輸入的輸入流。
OutputStream getOutputStream( ):返回一個從進程的in輸入流中寫輸出的輸出流。
int waitFor( ) throws InterruptedException:返回由進程返回的退出碼。這個方法直到調用它的進程中止,才會返回。
4 程序編寫
我們先來分析ipconfig/all的輸出格式:
從圖1中我們看到MAC地址包含的行為:“ Physical Address. . . . . . . . . : 00-10-DC-A9-0B-2C”。為了找到MAC地址,我們一行一行讀取字符,只要找到字符串“ Physical Address. . . . . . . . . :”,就可以找到MAC地址了。下面是實現的程序片段:
以下是引用片段:
:
Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all");
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader (process.getInputStream()));
while ( (line=bufferedReader.readLine()) != null){
if(line.indexOf("Physical Address. . . . . . . . . :") != -1){
if(line.indexOf(":") != -1){
physicalAddress = line.substring(line.indexOf(":")+2);
: |
在上面的程序中,為了讀取命令輸出的字符,利用子進程process生成了一個數據流緩沖區。
5 結束語
作為一個跨平臺語言,編寫的JAVA程序一般都與硬件無關,因而能運行在不同的操作系統環境。但這給編寫底層相關的程序時帶來不便。
Java的應用程序都存在著一個與其運行環境相聯系的Runtime對象,利用該對象可執行外部命令,在WindowsXP/NT/2000環境中的命令IPCONFIG的輸出包含有MAC地址。本文編寫的Java程序,執行外部命令IPCONFIG,并通過分析該命令的輸入流而獲得本機的MAC地址。由于IPCONFIG命令是操作系統命令,所以該方法既方便又可靠。
以上討論的程序適合于Windows XP/NT/2000操作系統,因為它是基于該操作系統的命令IPCONFIG格式的。由于不同操作系統讀取MAC地址的命令、以及命令輸出格式的不同,所以該程序不能直接運用到其它系統。要移植到其它系統只需針對命令的輸出格式稍作修改。
posted @
2009-11-06 17:21 junly 閱讀(460) |
評論 (0) |
編輯 收藏
1.解壓struts2-core-X.X.X.jar文件,把在META-INF文件夾下面的struts-tags.tld文件復制到WEB-INF文件夾下。
將freemark的jar導入到工程中
2.在web.xml文件中配置freemark同時啟動JSPSupportServlet.代碼如下:
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>
freemarker.ext.servlet.FreemarkerServlet
</servlet-class>
<!--下面的配置freemarke的ftl文件的位置 -->
<init-param>
<param-name>TemplatePath</param-name>
<param-value>/</param-value>
</init-param>
<!-- 是否和服務器(tommcat)一起啟動。0為不。1為是-->
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>


<servlet>
<!-- define a JspSupportServlet Object -->
<servlet-name>JspSupportServlet</servlet-name>
<servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
<!-- setting JspSupportServlet auto start -->
<load-on-startup>1</load-on-startup>
</servlet>
3.在FreeMarker模板中使用assign指令導入標簽庫。代碼如下
<#assign s=JspTaglibs["/WEB-INF/struts-tags.tld"] /> 注:這里我把struts-tags.tld放在WEB-INF下面
4.現在我們可以在FreeMarker模板中使用標簽了
示例代碼如下:
<#assign s=JspTaglibs["/WEB-INF/struts-tags.tld"] />
<@s.form action="login">
<@s.textfield name="username" label="username"/>
<@s.submit value="login" />
/@s.form
<!-- login.ftl代碼如下 -->

<#assign s=JspTaglibs["/WEB-INF/struts-tags.tld"] />
<html>
<head>
<title>Login Form</title>
</head>
<body>
please input username and password login<br>
<@s.form action="Login.action">
<@s.textfield name="username" label="username"/>
<@s.password name="password" label="password" />
<@s.submit value="submit" />
</@s.form>
</body>
</html>


<!-- welcome.ftl代碼如下: -->

<html>
<head>
<title>Success</title>
</haed>
<body>
WelCome,${username},you logined!<br>
<a href="ShowInfo.action">Show Information</a>
</body>
</html>


<!-- showinfo.ftl代碼如下: -->

<html>
<head>
<title>User Information</title>
<body>
<table border="1" width="360">
<caption>User Information</caption>

<tr>
<td>username:</td>
<td>${username}</td>
</tr>
<tr>
<td>sex:</td>
<td>${sex}</td>
</tr>
<tr>
<td>age:</td>
<td>${age}</td>
</tr>
</table>
</body>
</html>


posted @
2009-11-05 15:00 junly 閱讀(1233) |
評論 (0) |
編輯 收藏
摘要: 讀取配置文件有很多種方法,現就最常用的方法作以下總結:(其他會慢慢更新)
configuration/ConfigurationFactory用法(pache.commons包下)
本文:org.apache.commons.configuration.configuration
其它:com.opensymphony.xwork2.config.configuration
&nb...
閱讀全文
posted @
2009-11-04 17:14 junly 閱讀(2515) |
評論 (0) |
編輯 收藏
js讀寫cookie可以提高效率,現對代碼作仔細說明,以備用:
//寫cookies函數
function SetCookie(name,value)//兩個參數,一個是cookie的名子,一個是值


{
var Days = 30; //此 cookie 將被保存 30 天
var exp = new Date(); //new Date("December 31, 9998");
exp.setTime(exp.getTime() + Days*24*60*60*1000);
//將 cookie 內容寫入客戶端,其中 expires 是系統使用的,表示 cookie 的失效日期(也可以省略),
//expires 不可讀。escape 是對 cookie 值進行編碼,這是為了處理中文、空格等而設立的。
document.cookie = name.toLowerCase() + "="+ escape (value) + ";expires=" + exp.toGMTString();
}
//讀取cookies函數
function getCookie(name)


{
//取 cookie 字符串,由于 expires 不可讀,所以 expires 將不會出現在 cookieStr 中。
var arr = document.cookie.match(new RegExp("(^| )"+name.toLowerCase()+"=([^;]*)(;|$)"));
if(arr != null) return unescape(arr[2]); return null;

}
//刪除cookie
function delCookie(name)


{
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval=getCookie(name);
if(cval!=null) document.cookie= name.toLowerCase() + "="+cval+";expires="+exp.toGMTString();
}


//簡單例子
SetCookie ("name", www.buslfy.cn)
alert(getCookie(name));

//寫入名稱為 cv 的 cookie
SetCookie ("cv", "test123", null);

//寫入名稱為 Ab,帶失效日期的 cookie
var expires = new Date("December 11, 2010");
SetCookie ("Ab", "test234", expires);
1. Cookie的兼容性問題
Cookie的格式有2個不同的版本,第一個版本,我們稱為Cookie Version 0,是最初由Netscape公司制定的,也被幾乎所有的瀏覽器支持。而較新的版本,Cookie Version 1,則是根據RFC 2109文檔制定的。為了確保兼容性,JAVA規定,前面所提到的涉及Cookie的操作都是針對舊版本的Cookie進行的。而新版本的Cookie目前還不被Javax.servlet.http.Cookie包所支持。
2. Cookie的內容
同樣的Cookie的內容的字符限制針對不同的Cookie版本也有不同。在Cookie Version 0中,某些特殊的字符,例如:空格,方括號,圓括號,等于號(=),逗號,雙引號,斜杠,問號,@符號,冒號,分號都不能作為Cookie的內容。這也就是為什么我們在例子中設定Cookie的內容為"Test_Content"的原因。
雖然在Cookie Version 1規定中放寬了限制,可以使用這些字符,但是考慮到新版本的Cookie規范目前仍然沒有為所有的瀏覽器所支持,因而為保險起見,我們應該在Cookie的內容中盡量避免使用這些字符
posted @
2009-11-04 15:42 junly 閱讀(294) |
評論 (0) |
編輯 收藏