2009年6月17日

Dom4j 如何新增 standalone?


在Java中處理xml檔案的套件有很多,
如:DOM(JAXP Crimson解析器)、SAX 、JDOM和 Dom4j
其詳細介紹和大致的比較可見:Java中四種操作xml方式的比較
其中因為 Dom4j 在效能上比其他的好,所以我就用了Dom4j。

然而好景不常,才一開始便遇到了問題,
翻遍了 Dom4j 1.6.1API文件 也找不到如何在 xml 中新增 standalone="yes" 的字樣,
最後搜尋了網路發現是 Dom4j 1.6.1 還不支援這樣做,
如果還是要使用 Dom4j 1.6.1 ,那只能自己再寫一個新的 class 了。

以下是新的 class 的程式碼,分別參考自 DOM4j 学习笔记
[dom4j-user] How do I get standalone='yes' in the header
  1. import java.io.FileOutputStream;
  2. import java.io.FileWriter;
  3. import java.io.IOException;
  4. import java.io.UnsupportedEncodingException;

  5. import org.dom4j.io.OutputFormat;
  6. import org.dom4j.io.XMLWriter;

  7. public class StandaloneWriter extends XMLWriter {

  8. public StandaloneWriter(FileOutputStream fileOutputStream, OutputFormat format)
  9. throws UnsupportedEncodingException {
  10. super(fileOutputStream, format);
  11. }

  12. public StandaloneWriter(FileWriter fileWriter, OutputFormat format)
  13. throws UnsupportedEncodingException {
  14. super(fileWriter, format);
  15. }

  16. @Override
  17. protected void writeDeclaration() throws IOException {
  18. OutputFormat format = getOutputFormat();

  19. String encoding = format.getEncoding();

  20. if (!format.isSuppressDeclaration()) {
  21. if (encoding.equals("UTF8")) {
  22. writer.write("<?xml version=\"1.0\"");

  23. if (!format.isOmitEncoding()) {
  24. writer.write(" encoding=\"UTF-8\"");
  25. }

  26. writer.write(" standalone=\"yes\"");
  27. writer.write("?>");
  28. } else {
  29. writer.write("<?xml version=\"1.0\"");

  30. if (!format.isOmitEncoding()) {
  31. writer.write(" encoding=\"" + encoding + "\"");
  32. }

  33. writer.write(" standalone=\"yes\"");
  34. writer.write("?>");
  35. }

  36. if (format.isNewLineAfterDeclaration()) {
  37. println();
  38. }
  39. }
  40. }
  41. }
而有了上面新的 class 之後我們可以用類似以下的程式碼來建立一個 xml 檔,
其中的程式碼大多是 dom4j 官網中的 Quick Start 的範例
  1. import java.io.FileWriter;

  2. import org.dom4j.Document;
  3. import org.dom4j.DocumentHelper;
  4. import org.dom4j.Element;
  5. import org.dom4j.io.OutputFormat;
  6. import org.dom4j.io.XMLWriter;

  7. public class StandaloneWriterDemo {

  8. public static void main(String[] args) {

  9. Document document = DocumentHelper.createDocument();

  10. Element root = document.addElement( "root" );

  11. root.addElement( "author" )
  12. .addAttribute( "name", "James" )
  13. .addAttribute( "location", "UK" )
  14. .addText( "James Strachan" );

  15. root.addElement( "author" )
  16. .addAttribute( "name", "Bob" )
  17. .addAttribute( "location", "US" )
  18. .addText( "Bob McWhirter" );

  19. XMLWriter writer;
  20. OutputFormat format = OutputFormat.createPrettyPrint();
  21. try {
  22. writer = new StandaloneWriter( new FileWriter( "output.xml" ), format);
  23. writer.write( document );
  24. writer.close();
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }
執行完後就可以產生 xml 檔如下:
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

  2. <root>
  3. <author name="James" location="UK">James Strachan</author>
  4. <author name="Bob" location="US">Bob McWhirter</author>
  5. </root>

關鍵字:Java, Dom4j, standalone, 問題, 如何
參考資料:
1. Java中四種操作xml方式的比較
2. Dom4j 1.6.1
3. DOM4j 学习笔记
4. [dom4j-user] How do I get standalone='yes' in the header
5. Quick Start 的範例

2009年6月16日

Java:程式執行時間計算


在程式執行時我們常需要注意程式的效能,
而其中比較而易計算的就是程式的執行時間。

以下的程式碼是列出 doSomething() doAnotherthing() 各執行了多少秒。

  1. class ExcutingTime{
  2. public static void main(String[] args) {
  3. long time1, time2, time3;
  4. time1 = System.currentTimeMillis();
  5. // doSomething()
  6. time2 = System.currentTimeMillis();
  7. // doAnotherthing()
  8. time3 = System.currentTimeMillis();
  9. System.out.println("doSomething()花了:" + (time2-time1)/1000 + "秒");
  10. System.out.println("doAnotherthing()花了:" + (time3-time2)/1000 + "秒");
  11. }
  12. }
關鍵字:Java效能, Java程式執行時間, 計算
參考資料:
1. Java計算執行時間

2009年6月11日

form在onsubmit檢查後還是直接submit了?


我們常在網頁中使用form表單來傳遞資料,
然而在傳送之前我們必定要檢查每個欄位的資料,
看看是不是必填的都填了、資料格式是否正確等等。

通常我們會使用Javascript裡的 onsubmit來檢查,如:
<form onsubmit="checkForm(this);">
......
......
</form>
但後來卻常常發現就算在 checkForm() 中沒有呼叫 form.submit(),
form還是會自己忍不住就被丟出去了 orz,
這究竟是怎麼一回事呢?

後來在網路上查到了解決方法,
只要在 onsubmit="checkForm(this);" 加上 return
也就是變成這樣:onsubmit="return checkForm(this);"
然後不想送出 form時在 checkForm() 裡面 return false就好。

更多細節可以看原始連結:
onSubmit after checking return false and still submit

關鍵字:Javascript, form, 表單, submit, check, 送出, 檢查, 不要送出
參考資料:
1. onSubmit after checking return false and still submit

2009年6月9日

System.getProperty的參數用法


在寫java程式時我們常需要用到使用者系統的資訊,
而這可以使用System.getProperty來取得我們所需,
但是究竟要下什麼參數才能得到我們想要的呢?


以下的參數用法是取自於:
Java 技術文件正體中文版JDK_API_1_6_zh_TW_2008122501.chm
若是想看最新的英文版本也可以到 Java System.getProperties() 查看。

java.version Java 執行期環境版本
java.vendor Java 執行期環境供應商
java.vendor.url Java 供應商的 URL
java.home Java 安裝目錄
java.vm.specification.version Java 虛擬機規範版本
java.vm.specification.vendor Java 虛擬機規範供應商
java.vm.specification.name Java 虛擬機規範名稱
java.vm.version Java 虛擬機實現版本
java.vm.vendor Java 虛擬機實現供應商
java.vm.name Java 虛擬機實現名稱
java.specification.version Java 執行期環境規範版本
java.specification.vendor Java 執行期環境規範供應商
java.specification.name Java 執行期環境規範名稱
java.class.version Java 類別格式版本號
java.class.path Java 類別路徑
java.library.path 加載庫時搜索的路徑串列(linked-list)
java.io.tmpdir 預設的暫時檔路徑
java.compiler 要使用的 JIT 編譯器的名稱
java.ext.dirs 一個或多個擴展目錄的路徑
os.name 作業系統 的名稱
os.arch 作業系統 的架構
os.version 作業系統 的版本
file.separator 檔分隔設定(在 UNIX 系統中是“/”)
path.separator 路徑分隔設定(在 UNIX 系統中是“:”)
line.separator 行分隔設定(在 UNIX 系統中是“/n”)
user.name 用戶的賬戶名稱
user.home 用戶的主目錄
user.dir 用戶的當前工作目錄

關鍵字:System.getProperty, 參數, 用法
參考資料:
1. Java 技術文件正體中文版
2. JDK_API_1_6_zh_TW_2008122501.chm
3. Java System.getProperties()

StringBuilder和StringBuffer的差別及清空內容方式


在Java中常用到字串的處理,
但String本身是固定長度不能改變內容的,
我們常用+來連結附加字串其實相當耗費資源,
在大量處理字串的情況下我們有更好的選擇。

Java在J2SE5.0之後提供了StringBuilder類別,
他有許多好用的操作字串的方法如:
insert()、reverse()、replace()、append()等,
更多詳細的API可見:java.lang.StringBuilder 的API說明。

而很多人會有這樣的疑問(我也是一直弄不清楚才來寫這篇的XD),
StringBuilder和StringBuffer有什麼差別呢?
他們兩個提供了相同的介面,
然而在不需考量多執行緒同步的時候我們使用StringBuilder來獲得最佳的效率
要考慮多執行緒的情況下使用StringBuffer來讓類別自動處理同步的問題

另外這兩個類別雖然相當好用,
但似乎許多人都會找不到如何清空他,
這大概是因為單純看 method 時沒有看到叫做 clear() 之類的 method,
但其實我們還是可以透過 delete(int start, int end) 這個 method 來達成目的。
用法就像這樣:stringBuffer.delete(0, stringBuffer.length());

關鍵字:StringBuilder, StringBuffer, String, 字串處理, 不同, 清空, 內容, 如何
參考資料:
  1. java.lang.StringBuilder
  2. Java Gossip: StringBuilder 類別
  3. StringBuffer 类型如何清空呢!!!!