2009年12月30日

Java:呼叫function後更新畫面的問題


本篇還沒有很完整而只是簡單的筆記,
之後如果有比較好的例子再寫出完整的code給大家參考。

先說明一下我遇到的問題:
我寫了 server 和 client 的架構,他們彼此會以 socket 溝通,
而我想把他們互相傳送的內容顯示在視窗上,
但是當我按下「啟動」的按鈕後傳送的內容並不會馬上更新,
而是一直等到所有的傳送都結束了才會顯示。

後來我去查到了這篇:事件处理中UI的刷新问题(笔记体小品文)
大家可以仔細看看,他指出要用另外一個 thread 去執行啟動的 function,
這樣畫面才能同步更新。

關鍵字:更新, 畫面, 同步, 卡住
參考資料:
  1. 事件处理中UI的刷新问题(笔记体小品文)

Java:以javamail寄送附件圖檔與html格式email教學


在看這篇教學前,你應該要先將 javamail 相關設定完成,
下載點在:http://java.sun.com/products/javamail/downloads/index.html
API 文件:http://java.sun.com/products/javamail/javadocs/index.html
若你需要 source code 可見:http://kenai.com/projects/javamail/downloads

使用 java 寄信時我們常用 javamail,
然而很多人都只會寄純文字信件或單純的 html郵件,
如果你想先知道要怎麼寄純文字的信件的話,
這個連結有很詳細的 code :Send email with JavaMail

學會了寄純文字和html,但是要怎麼把附件的圖顯示在 html中呢?
直接看下面的程式就可以明白了,超簡單的!
  1. import java.util.Properties;

  2. import javax.activation.DataHandler;
  3. import javax.activation.FileDataSource;
  4. import javax.mail.*;
  5. import javax.mail.internet.*;

  6. public class SendMailDemo {

  7. /**
  8. * Java:以javamail寄送附件圖檔與html格式email教學
  9. *
  10. * @author werdna at http://werdna1222coldcodes.blogspot.com/
  11. */
  12. public static void main(String[] args) {

  13. try {

  14. // 初始設定,username 和 password 非必要
  15. Properties props = new Properties();
  16. props.setProperty("mail.transport.protocol", "smtp");
  17. props.setProperty("mail.host", "yourmailserver.location.or.ip");
  18. //props.setProperty("mail.user", "ifUserNameNeeded");
  19. //props.setProperty("mail.password", "ifPasswordNeeded");

  20. Session mailSession = Session.getDefaultInstance(props, null);
  21. Transport transport = mailSession.getTransport();

  22. // 產生整封 email 的主體 message
  23. MimeMessage message = new MimeMessage(mailSession);

  24. // 設定主旨
  25. message.setSubject("Javamail with picture attachment and html contents.");

  26. // 文字部份,注意 img src 部份要用 cid:接下面附檔的header
  27. MimeBodyPart textPart = new MimeBodyPart();
  28. StringBuffer html = new StringBuffer();
  29. html.append("<h2>這是第一行</h2><br>");
  30. html.append("<h3>這是第二行,下面會是圖</h3><br>");
  31. html.append("<img src='cid:image'/><br>");
  32. textPart.setContent(html.toString(), "text/html; charset=UTF-8");

  33. // 圖檔部份,注意 html 用 cid:image,則header要設<image>
  34. MimeBodyPart picturePart = new MimeBodyPart();
  35. FileDataSource fds = new FileDataSource("YourPictureFile.jpg");
  36. picturePart.setDataHandler(new DataHandler(fds));
  37. picturePart.setFileName(fds.getName());
  38. picturePart.setHeader("Content-ID", "<image>");

  39. Multipart email = new MimeMultipart();
  40. email.addBodyPart(textPart);
  41. email.addBodyPart(picturePart);

  42. message.setContent(email);
  43. message.addRecipient(Message.RecipientType.TO, new InternetAddress(
  44. "youremail@address"));
  45. transport.connect();
  46. transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO))
  47. ;
  48. transport.close();
  49. } catch (AddressException e) {
  50. e.printStackTrace();
  51. } catch (NoSuchProviderException e) {
  52. e.printStackTrace();
  53. } catch (MessagingException e) {
  54. e.printStackTrace();
  55. }
  56. }
  57. }
執行完後的結果會像這樣,是不是超簡單的呢?



關鍵字:mail, email, picture, image, 附檔, 附件, html, javamail, 程式, 教學, 範例
參考資料:
  1. Javamail
  2. Send email with JavaMail
  3. mail寄送附件圖檔與html format的疑問 [精華]

2009年12月27日

Java:計算 MD5, SHA, WHIRLPOOL等雜湊碼 hash code的程式教學


在開發程式期間我們常需要確認檔案的正確性,
無論是在網路傳送中有沒有被更改,或是檔案是不是同一個等等,
這時我們會需要 hash(雜湊) 或 digest(摘要) 來幫忙。
同樣的內容或檔案經過相同的 hash 演算法後會得到相同的結果,
這樣就可以確認我們得到的是正確的檔案,
上面的用法就是我們常聽到的 HMAC(Hash-based Message Authentication Code)。

在 Java 中已內建有一些 hash 演算法如:MD5
想知道該怎麼用最基本的 hash 可見 Java 官方的教學:Java:HMAC-MD5 Example
然而我們總是會需要用到用更多種的演算法,
因此今天要介紹的就是一個支援多種 hash code 的套件:gnu-crypto
這個套件的官網連結為:GNU Crypto - GNU Project - Free Software Foundation (FSF)
其支援的 hash 有:WhirlpoolSHA-160, SHA-256, SHA-384, and SHA-512MD5等,
更詳細的內容可見:
http://www.gnu.org/software/gnu-crypto/algorithms.html中的Message digest (hash)。

以下就是簡單的程式範例,其 hash 結果已經放在註解中:
  1. package demo.digest;

  2. import java.security.MessageDigest;
  3. import java.security.Security;

  4. /**
  5. * Java:計算 MD5, SHA, WHIRLPOOL等雜湊碼 hash code的程式教學
  6. *
  7. * @author werdna at http://werdna1222coldcodes.blogspot.com/
  8. */

  9. public class DigestDemo {

  10. // 本文應用的套件為:gnu-crypto-2.0.1
  11. // GNU Crypto - GNU Project - Free Software Foundation (FSF)
  12. // http://www.gnu.org/software/gnu-crypto/
  13. // 支授的演算法可見:http://www.gnu.org/software/gnu-crypto/algorithms.html
  14. public static void main(String[] args) {

  15. // 程式執行前須先將 Provider 加入
  16. Security.addProvider(new gnu.crypto.jce.GnuCrypto());

  17. // 初始化測試資料
  18. String stringToDigest = "這是要被hash(或稱雜湊、摘要)的字串";
  19. byte[] bytesToDigest = stringToDigest.getBytes();

  20. // Hash 範例:MD5
  21. // 要用 SHA, WHIRLPOOL 的話只要把 "MD5" 改為 "SHA"、"WHIRLPOOL"
  22. try {
  23. // 設定 Hash 演算法
  24. MessageDigest messageDigest = MessageDigest.getInstance("MD5");
  25. messageDigest.update(bytesToDigest);
  26. byte[] digest = messageDigest.digest();

  27. // 輸出 MD5 Hash:18:50:1F:84:0C:FE:2A:10:CE:89:B0:94:8E:FA:A0:42
  28. System.out.println(bytesToHex(digest));
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. }

  32. // Hash 範例:WHIRLPOOL
  33. // 更多 Hash 演算法可見:http://www.gnu.org/software/gnu-crypto/algorithms.
  34. html
  35. try {
  36. // 設定 Hash 演算法
  37. MessageDigest messageDigest = MessageDigest.getInstance("WHIRLPOOL");
  38. messageDigest.update(bytesToDigest);
  39. byte[] digest = messageDigest.digest();

  40. // 輸出 WHIRLPOOL Hash:
  41. // 2D:2E:C0:FE:70:71:23:51:7C:FD:E0:1C:9D:D0:CC:00:72:D7:42:38:1D:BD:
  42. // 10:7E:26:AC:DA:7B:D5:5A:03:7C:A9:17:B2:9C:29:EE:E7:88:7E:B4:DA:90:
  43. // DF:64:9B:F2:13:D6:FF:75:88:8C:05:E9:46:C5:94:B5:BB:BA:36:CE
  44. System.out.println(bytesToHex(digest));
  45. } catch (Exception e) {
  46. e.printStackTrace();
  47. }
  48. }

  49. // byte array 轉 hex 字串
  50. public static String bytesToHex(byte[] b) {

  51. StringBuffer sb = new StringBuffer();
  52. String stmp = "";
  53. for (int n = 0; n < b.length; n++) {
  54. stmp = (Integer.toHexString(b[n] & 0XFF));
  55. if (stmp.length() == 1) {
  56. sb.append("0").append(stmp);
  57. } else {
  58. sb.append(stmp);
  59. }
  60. if (n < b.length - 1) {
  61. sb.append(":");
  62. }
  63. }
  64. return sb.toString().toUpperCase();
  65. }
  66. }
關鍵字:hash, digest, mac, hmac, md5, sha, whirlpool, 雜湊, 摘要, 演算法, 程式, 教學, 範例
參考資料:
  1. Java:HMAC-MD5 Example
  2. GNU Crypto - GNU Project - Free Software Foundation (FSF)
  3. gnu-crypto
  4. http://www.gnu.org/software/gnu-crypto/algorithms.html
  5. Whirlpool (cryptography) @ wikipedia

2009年12月20日

HTML Purifier in Java:HTMLInputFilter


在製作 web services 的時候,我們常需要防範不當使用者的惡意攻擊,
而在這些攻擊之中,最著名的就是XSS (Cross Site Scripting),
其運作方式和常用的攻擊手法可見下列連結:
而在眾多的 web services 程式語法中,以 PHP 對 xss 攻擊的防範最完全,
因為 PHP 有個套件名為 HTML Purifier ,如官網的小標題,這個套件的目的是:
Standards-Compliant HTML Filtering ,也就是除了過濾也還有將語法標準化的功能。
HTML Purifier 經由多方的努力已有成效,他可抵擋的攻擊可見 xssAttacks

然而針對其他程式語言的使用者,看著 PHP 套件如此強大卻沒辦法使用,
在網路上詢問也只能得到像這個網站的解答:HTML Purifier in Java
這篇的結論是在 Java 中使用 Resin Quercus (a PHP interpreter for the JVM) ,
但實際上也沒有人測過到底會不會 work.... ,而且這種繞了大彎的方法真的很麻煩,
於是我後來找到的解法是:HTMLInputFilter,雖然功能可能沒有 HTML Purifier 強,
但至少基本的功能都有了,也算是可行的解決之道。

以下就是 HTMLInputFilter 的使用範例:
  1. import java.util.ArrayList;
  2. import com.josephoconnell.html.HTMLInputFilter;

  3. /**
  4. * 使用 HTMLInputFilter 達成過濾 xss 等惡意字串攻擊的範例
  5. *
  6. * @author werdna at http://werdna1222coldcodes.blogspot.com/
  7. */

  8. public class HTMLInputFilterDemo {

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

  10. // For use of HTMLInputFilter, go to the followed website first.
  11. // http://josephoconnell.com/java/xss-html-filter/

  12. // 設定要過濾字串的 List
  13. // 常見的 xss 攻擊語法可見:http://htmlpurifier.org/live/smoketests/xssAttacks.php
  14. ArrayList<String> xssList = new ArrayList<String>();
  15. xssList.add("<script>alert(document.cookie)</script>");
  16. xssList.add("<script>alert('XSS')</script>");
  17. xssList.add("<img src=\"javascript:alert('XSS')\"> ");
  18. xssList.add("<BR SIZE=\"&{alert('XSS')}\">");
  19. xssList.add("<LINK REL=\"stylesheet\" HREF=\"javascript:alert('XSS');\">");

  20. // 取得 HTMLInputFilter 物件
  21. HTMLInputFilter htmlInpuFilter = new HTMLInputFilter();
  22. String purifiedHtml;

  23. for (String xss : xssList) {
  24. // 過濾 xss 字串
  25. purifiedHtml = htmlInpuFilter.filter(xss);
  26. System.out.println("原始 xss:" + xss + "\t\t過濾後:" +purifiedHtml);
  27. }
  28. }
  29. }
輸出的結果會像下面,其中4, 5兩行過濾後輸出是空的:
  1. 原始 xss:<script>alert(document.cookie)</script> 過濾後:alert(document.cookie)
  2. 原始 xss:<script>alert('XSS')</script> 過濾後:alert('XSS')
  3. 原始 xss:<img src="javascript:alert('XSS')"> 過濾後:<img src="#alert('XSS')" />
  4. 原始 xss:<BR SIZE="&{alert('XSS')}"> 過濾後:
  5. 原始 xss:<LINK REL="stylesheet" HREF="javascript:alert('XSS');">過濾後:
由以上可知,介由 HTMLInputFilter 的確可過濾 xss 的攻擊,
如果不想浪費時間在 java 中呼叫 php 的功能,HTMLInputFilter 的確是個好選擇。

關鍵字:HTML, Purifier, HTMLInputFilter, xss, filter, purify, cross site scripting
參考資料:
  1. wikipedia:Cross-site scripting
  2. 浅析XSS(Cross Site Script)漏洞原理
  3. XSS (Cross Site Scripting) Cheat Sheet
  4. HTML Purifier
  5. HTML Purifier in Java
  6. HTMLInputFilter

2009年12月19日

StringEscapeUtils.escapeHtml、unescapeHtml:處理html中的編碼問題


先前在幾篇文章中提到了網址編碼和文字轉碼的問題,
如 Javascript 就有以下 1, 2兩篇, Java 部份則是第3篇:
  1. 用Javascript替中文轉碼:escape, encodeURI, encodeURIComponent 的比較
  2. Online UrlEncoder:線上轉換中文網址為UTF-8編碼
  3. 用Java替中文轉碼:URLEncoder
然而最近使用 Java 處理網頁資料時卻遇上了一個問題,
即從網頁原始碼得到的資料會有類似下面這種編碼。
&amp;&lt;&gt;&quot;
這在我們一看就知道是為了在 html 正確顯示的code,
然而如果不是熟悉 html 的人會以為是亂碼,
而且就算我們知道是 html 的 code,
平常不使用的話也不容易知道到底哪個碼對應哪個字。
因此今天就是要介紹在 Java 中能將 html 編碼正確轉換的套件,
org.apache.commons.lang.StringEscapeUtils
另外若想知道在 java中如何處理 xss 的攻擊可見:
HTML Purifier in Java:HTMLInputFilter

StringEscapeUtils有許多好用的功能,之後有用到的話會再來介紹,
今天主要先介紹:escapeHtml unescapeHtml
更多的功能可見 StringEscapeUtils 的 API

要使用 StringEscapeUtils 要先到這個網址去下載相關的 jar 檔並匯入,
http://commons.apache.org/downloads/download_lang.cgi
接著便可以依下面的程式碼測試是否可以正確 escape 和 unescape html了。
程式中共有兩個測試,一個測試純文字的轉換,另一個則是針對上面所提的奇怪符號作測試:
  1. package demo.stringEscapeUtils;

  2. import org.apache.commons.lang.StringEscapeUtils;

  3. public class StringEscapeUtilsDemo {

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

  5. // 測試純文字的 escape 和 unescape
  6. String normalWords = "測試文字";
  7. System.out.println("測試純文字的 escape 和 unescape");
  8. String escapedWords = StringEscapeUtils.escapeHtml(normalWords);
  9. System.out.println("escape " + normalWords +" 的結果是: " + escapedWords);
  10. String unescapedWords = StringEscapeUtils.unescapeHtml(escapedWords);
  11. System.out.println("unescape 回來的結果是: " + unescapedWords);
  12. System.out.println();

  13. // 測試 html 特殊符號的 escape 和 unescape
  14. // 輸入的符號為:& < > "
  15. String htmlCodes = "&<>\"";
  16. System.out.println("測試 html 特殊符號的 escape 和 unescape");
  17. String escapedhtmlCodes = StringEscapeUtils.escapeHtml(htmlCodes);
  18. System.out.println("escape " + htmlCodes +" 的結果是: " + escapedhtmlCodes);
  19. String unescapedhtmlCodes = StringEscapeUtils.unescapeHtml(escapedhtmlCodes);
  20. System.out.println("unescape 回來的結果是: " + unescapedhtmlCodes);
  21. }
  22. }
其輸出結果為:
  1. 測試純文字的 escape 和 unescape
  2. escape 測試文字 的結果是: &#28204;&#35430;&#25991;&#23383;
  3. unescape 回來的結果是: 測試文字

  4. 測試 html 特殊符號的 escape 和 unescape
  5. escape &<>" 的結果是: &amp;&lt;&gt;&quot;
  6. unescape 回來的結果是: &<>"
由以上知我們可以用 StringEscapeUtils 輕易轉換 html 的碼,
而且 StringEscapeUtils 也還有針對其他格式的轉換,如 xml、javascript、java、csv。
詳細的說明可見:StringEscapeUtils 的 API
或是等我之後有用到再來寫說明囉。

關鍵字:StringEscapeUtils, Apache, html, escape, unescape
參考資料:
  1. http://commons.apache.org/lang/
  2. StringEscapeUtils
  3. StringEscapeUtils 的 API
  4. 編碼 - Java
  5. HTML Purifier in Java:HTMLInputFilter

2009年12月3日

Windows Live Sync:資料夾同步的好幫手


隨著現在電腦越來越便宜,
每個人在日常生活中都有可能同時接觸到很多台電腦,
如學生可能有一台桌機、一台筆電,再加上研究室的電腦等等。

然而擁有這麼多台電腦也相當令人苦惱,
因為有時是改了這台電腦的資料得自己更新到其他的電腦,
有些時候則是想要的資料不在手上而在其他電腦,
總而言之就是資料同步的問題。

 Windows Live Sync 是微軟所推出免費的資料夾同步軟體,
其目的就是在不同的電腦同步處理檔案,讓檔案永遠保持最新狀態。
在官方網站上提到有三項主要的功能:
  1. 同步處理檔案:永遠保持所有電腦上的重要檔案為最新狀態,不論使用的是 PC 或 MAC (MAC 僅支援英文版)。
  2. 共享工作:使用共用資料夾,與好友或同事同步處理檔案。 
  3. 存取不受限:登入 Sync 網站,即可遠端存取任何安裝 Sync 的電腦。
簡而言之若是你常需要在不同電腦工作想將檔案同步,想跟其他人分享檔案、協同作業,
或是常在外面上網,需要取得遠端電腦中的檔案但又不想讓家中電腦一直開機。
只要符合上面任何一項條件,那麼  Windows Live Sync 絕對是最適合你的選擇。

關於 Windows Live Sync 的一些基本資料和使用限制如下:
至於安裝和設定其實 Windows Live Sync 官網 已說明得很清楚了,
只要照著步驟做很快就能上手並完成所需的設定。
若是官網的說明不過詳細也可以參考另外兩篇很完整的說明:
關鍵字:Sync、同步、資料夾、資料、軟體
參考資料:
  1. Windows Live Sync 官網
  2. Windows Live Sync教學
  3. 微軟的免費Live Sync服務,讓你輕鬆同步多台電腦的檔案!

Eclipse 好用套件:Regular Expression Tester


在先前的文章中我們曾經提到正規式(regular expression)的使用,
也寫了一篇教學在:java.util.regex正規式的應用:Pattern和Matcher
然而如果要透過程式才能測試寫出來的 regular expression 正不正確,
那對我們這些不太常使用 regular expression 的人是很麻煩的。

(100.09.29) 更新:
這邊更新介紹線上的測試網站,以及一個新的 Eclipse 套件。
  1. Online Regular Expression Tester:線上正規式測試驗證工具網站
  2. Eclipse 的 plugin,http://myregexp.com/eclipsePlugin.html
因此今天要在這裡介紹一個 Eclipse 的好用套件:Regular Expression Tester
透過他我們就能快速測試我們所寫的 regular expression 和待測的文字是不是有 match,
如此就能在寫程式前修正語法,免除 debug 的痛苦。

首先要安裝可依以下步驟:
  • In Eclipse, choose Help > Install New Software
  • 在 work with 中填上:http://brosinski.com/regex/update,勾選安裝
  • In Eclipse, choose Window > Show View > Other > RegEx Tester
  • Configure it in Window > Preferences > RegEx Tester
或者依據 Regular Expression Tester官網 的教學:
即先下載套件的 zip 檔,解壓縮至 eclipse 的目錄,然後重啟 eclipse,
最後照著上面的指示設定選項即可。
如果上面的說明還是看不太懂,你也可以看下面這篇圖示說明來設定。
http://wiki.cheyingwu.tw/Eclipse/Regular_Expression_Tester

附上官網的套件使用圖:
關鍵字:Eclipse、Regular Expression、RegEx Tester、RegEx、示範、範例、設定
參考資料:
  1. Regular Expression Tester官網
  2. java.util.regex正規式的應用:Pattern和Matcher
  3. http://wiki.cheyingwu.tw/Eclipse/Regular_Expression_Tester
  4. Online Regular Expression Tester:線上正規式測試驗證工具網站
  5. http://myregexp.com/eclipsePlugin.html

2009年11月30日

Apache HttpClient 4.x 使用 GET, POST 範例


先前我曾經發了一篇介紹如何抓取網頁的教學:
利用Jakarta.Commons.HttpClient抓取網頁、網站(Parser),不過當時用的是 HttpClient 3.1。
經過時間的演進 Apache 已經在 14 August 2009 發佈HttpComponents HttpClient 4.0 (GA)
由 3.1 到 4.0 因為底層幾乎全部重新改寫,所以也使有些舊的程式無法使用。
這篇就是我自己寫的一個簡單範例。

在看範例之前先把一些重要連結整理給大家:
想知道這次到底更動了哪些東西可以看:Apache HttpClient 首頁
官方的 Tutorial 在:Apache HttpClient Tutorial
而 API DOC、說明文件則在:Apache HttpClient apidocs

相關的程式碼、jar 檔在:HttpComponents HttpClient 4.0 (GA)
注意,在寫程式前必需先將四個 jar 檔正確匯入,最後兩個(*)是選用,
請參考:http://hc.apache.org/httpcomponents-client/quickstart.html
  • commons-logging-x.x.x.jar
  • commons-codec-x.x.x.jar
  • httpcore-x.x.x.jar
  • httpclient-x.x.x.jar
  • apache-mime4j-x.x.x.jar (*)
  • httpmime-x.x.x.jar (*)
說了這麼多,以下是程式的範例,
第一個是傳回在 google 查詢 httpclient 的結果。
第二則是傳回台大圖書館查詢 Head First Java 的結果。

 1 package demo.httpclient;
 2 
 3 import java.io.IOException;
 4 import java.util.ArrayList;
 5 
 6 import org.apache.commons.httpclient.HttpStatus;
 7 import org.apache.http.HttpResponse;
 8 import org.apache.http.NameValuePair;
 9 import org.apache.http.client.methods.HttpGet;
10 import org.apache.http.client.methods.HttpPost;
11 import org.apache.http.client.utils.URLEncodedUtils;
12 import org.apache.http.entity.StringEntity;
13 import org.apache.http.impl.client.DefaultHttpClient;
14 import org.apache.http.message.BasicNameValuePair;
15 import org.apache.http.util.EntityUtils;
16 
17 /**
18 * Apache HttpClient 4.x 使用 GET, POST 查詢網頁的範例
19 *
20 * @author werdna at http://werdna1222coldcodes.blogspot.com/
21 */
22 
23 public class HttpClientDemo extends DefaultHttpClient {
24 
25     public static void main(String[] args) throws IOException {
26 
27         DefaultHttpClient demo = new DefaultHttpClient();
28         demo.getParams().setParameter("http.protocol.content-charset", "UTF-8");
29 
30         // Get Request Example,取得 google 查詢 httpclient 的結果
31         HttpGet httpGet = new HttpGet("http://www.google.com.tw/search?q=httpclinet");
32         HttpResponse response = demo.execute(httpGet);
33         String responseString = EntityUtils.toString(response.getEntity());
34         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
35             // 如果回傳是 200 OK 的話才輸出
36             System.out.println(responseString);
37         } else {
38             System.out.println(response.getStatusLine());
39         }
40 
41         // Post Request Example,查詢台大圖書館書籍
42         ArrayList<NameValuePair> pairList = new ArrayList<NameValuePair>();
43         pairList.add(new BasicNameValuePair("searchtype", "t"));
44         pairList.add(new BasicNameValuePair("searchscope", "keyword"));
45         pairList.add(new BasicNameValuePair("searcharg", "Head First Java"));
46         pairList.add(new BasicNameValuePair("SORT", "D"));
47 
48         HttpPost httpPost = new HttpPost("http://tulips.ntu.edu.tw:1081/search*cht/a?");
49         StringEntity entity = new StringEntity(URLEncodedUtils.format(pairList, "UTF-8"));
50         httpPost.setEntity(entity);
51         response = demo.execute(httpPost);
52         responseString = EntityUtils.toString(response.getEntity());
53         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
54             // 如果回傳是 200 OK 的話才輸出
55             System.out.println(responseString);
56         } else {
57             System.out.println(response.getStatusLine());
58         }
59     }
60 }

更多的程式範例可以參考其教學: 
HttpClient 4 HTTP request 
HttpClient 4 使用POST方式提交普通表单数据的例子

關鍵字:Apache、HttpClient、4、教學、示範、範例、設定
參考資料:
  1. Apache HttpClient 首頁
  2. HttpComponents HttpClient 4.0 (GA)
  3. Apache HttpClient Tutorial
  4. Apache HttpClient apidocs
  5. HttpClient 4 HTTP request
  6. HttpClient 4 使用POST方式提交普通表单数据的例子 

2009年11月19日

Java:Log4j 的簡單教學


Log4j 是目前開發 java 時很常用到的 log 套件,
以下整理一些我目前用到的功能,並附上更多更深入的教學。

首先在使用  Log4j 時我們要先將一些 jar 檔匯入,
如果有出現意外的 Exception 記得先找看看是不是有 jar 檔沒有匯入,
類似的問題將 Exception 丟到 google 就會有解答,所以在這邊就不詳細說明。
只列出官方的使用前須知:http://logging.apache.org/log4j/1.2/faq.html#1.3

(2011.10.04更新)
若您只是要快速產生或下載 Log4j 的設定檔,請參考:
Logback, Log4j 設定檔自動產生器

使用 Log4j 時我們可以建立一個 Log4j.properties 檔來描述我們要記錄的項目,
這個設定檔長得像下面這樣:
--------------------------------------------------------------------------------------------------------------
log4j.rootLogger=Info, A1, A2


# A1 is set to be a ConsoleAppender
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%d{yy/MM/dd HH:mm:ss}][%p][%C-%L] %m%n

# A2 is set to be a file
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=[%d{yy/MM/dd HH:mm:ss}][%p][%C-%L] %m%n
log4j.appender.A2.File=./log/Log4j.log
--------------------------------------------------------------------------------------------------------------
關於設定檔的詳細設定說明可以參考史帝芬心得筆記,重要部份節錄如下:
  1. 階層:
  2. Log4j將輸出訊息分成五個等級,分別為DEBUG、INFO、WARN、ERROR、FATAL,在上面設定檔將輸出等級 設為INFO,就表示INFO~FATAL等級的訊息將會輸出,因此DEBUG等級的訊息就會被忽略,如果將設定檔的 第一行改為log4j.rootLogger=DEBUG, A1, A2,就會兩個訊息都輸出了。除了這五個等級外,也可以設為ALL或OFF, ALL很示全部訊息都輸出,OFF則表示不輸出訊息。
  3. 輸出格式:
  4. # %c 輸出日誌訊息所屬的類別的全名 # %d 輸出日誌時間點的日期或時間,指定格式的方式:%d{yyy-MM-dd HH:mm:ss }。 # %l 輸出日誌事件的發生位置,即輸出日誌訊息的語句處於它所在的類別的第幾行。 # %m 輸出訊息,如log(message)中的message。 # %n 輸出一個列尾符號。 # %p 輸出優先階層,即DEBUG,INFO,WARN,ERROR,FATAL。如果是調用debug()輸出的,則為DEBUG,依此類推。 # %r 輸出自應用啟動到輸出該日誌訊息所耗費的毫秒數。 # %t 輸出產生該日誌事件的線程名。 # %r 輸出自應用啟動到輸出該日誌訊息所耗費的毫秒數。 # %f 輸出日誌訊息所屬的類別的類別名。 值得注意的是A2的appender被設為org.apache.log4j.DailyRollingFileAppender表示Log4j會將日誌檔依日期分開。
完成設定檔後可以開始寫程式,程式的內容非常簡單:
    1 package demo.log4j;
    2 
    3 import org.apache.log4j.Logger;
    4 import org.apache.log4j.PropertyConfigurator;
    5 
    6 public class Log4jDemo {
    7 
    8     static public void main(String args[]) {
    9 
   10         // 純 java project 中,若將 Log4j.properties 和 java 檔放在一起,
   11         // 則 Eclipse 會把他複製到 .class 檔的位置,(project路徑/build/classes/package路徑/檔名)
   12         // 若是 web-application 的話,會在 (project路徑/WEB-INF/classes/package路徑/檔名)
   13         PropertyConfigurator.configure("build/classes/demo/log4j/Log4j.properties");
   14         Logger logger = Logger.getLogger(Log4jDemo.class);
   15 
   16         // 對應的 Log4j.properties 設定要在等級 Info 之上才會顯示,所以logger.debug 不會出現
   17         logger.debug("Hello Log4j, this is debug message");
   18 
   19         // 以下的訊息會出現在 console 和 log file 中
   20         logger.info("Hi Log4j, this will appear in console and log file");
   21         logger.error("This is error message!!!");
   22     }
   23 }
其結果會在 console 和 log file 中出現這些log :
[09/11/19 18:44:39][INFO][demo.log4j.Log4jDemo-20] Hi Log4j, this will appear in console and log file
[09/11/19 18:44:39][ERROR][demo.log4j.Log4jDemo-21] This is error message!!!

除了將 log 寫在 console 和 log file 外,Log4j 還可以寫入其他更多地方,如 DB、Email等等,
這些應用可以參考:利用log4j實作console log + file log + mail log + db log 

關鍵字:Log4j、properties、設定檔、教學、示範、範例、設定
參考資料:
  1. Log4j 官方網站
  2. Log4j 官方網站 F&Q
  3. 史帝芬心得筆記
  4. 利用log4j實作console log + file log + mail log + db log 

Gliffy:取代 Visio 的線上繪圖網站


當我們想畫流程圖的時候常想到 Visio,
但因為 Visio 太貴學校公司不一定有購買故取得不易,
而且只是偶爾用卻得安裝肥大的程式,這都讓人相當不開心。

然而自從發現 Gliffy 後感覺生命出現了光采呢!(好像老套的廣告 XD)
Gliffy 這個網站如同他自己的介紹,是個 Online Diagram Software,
雖然陽春,但免費又免安裝就讓人用起來相當舒服,
而且 Visio 中比較常用到的功能也都有支援,真的相當不錯。

目前 Gliffy 有提供一些常用的圖片,也支援自己上傳,
另外也有一些基本的功能如:區塊連線、圖形旋轉、調整大小等功能,
但他的群組功能還有點小問題,建議使用時要常存檔,不然格式跑掉很慘。
在繪圖完成後 Gliffy 支援的儲存格式包括 JPG, PNG 和 SVG,
其中 SVG 格式可以透過 Visio 開啟和編輯。

關鍵字:Gliffy、Visio、線上繪圖、繪圖軟體、流程圖、破解、序號
參考資料:
  1. Gliffy
  2. [webapp] Visio 苦手的救星,線上畫圖靠 Gliffy
下面是介紹圖:


2009年11月18日

使用 Dom4j 時的 XPath 問題


我們使用 dom4j 時可使用 XPath 來取得特定的 node,如:
List list = document.selectNodes(specificColumnXPath);

此時可能會出現這樣的 Exception:
Exception in thread "main" java.lang.NoClassDefFoundError: org/jaxen/JaxenException
其原因是因為少了 jaxen,下載 jar 檔匯入後應該就可以解決了。

另外如果確定 XPath 正確,selectNodes() 卻一直回傳空值(null)的話,
有可能是因為 xmlns 不是 default 值的關係,相關討論網址如下:
  1. JavaWorld@TW Java論壇- 請教dom4j 的 xpath 問題
  2. 主题:解决dom4j无法解析xml命名空间的问题
關於Dom4j、XPath的教學則可以參考:
  1. http://www.dom4j.org/dom4j-1.6.1/guide.html
  2.  http://www.zvon.org/xxl/XPathTutorial/General/examples.html
關鍵字:dom4j、XPath、jaxen、問題、錯誤、無法使用、xmlns、命名空間
參考資料:
  1. jaxen
  2. 在Dom4j中使用xpath
  3. JavaWorld@TW Java論壇- 請教dom4j 的 xpath 問題
  4. 主题:解决dom4j无法解析xml命名空间的问题
  5. http://www.dom4j.org/dom4j-1.6.1/guide.html
  6. http://www.zvon.org/xxl/XPathTutorial/General/examples.html   

2009年11月16日

XP常用的「開始-執行」指令


在XP中的「開始 - 執行」其實能做很多事,
只要輸入簡單的指令就可以省去在重重資料夾中尋找捷徑的麻煩,
對常用某些服務的人記住幾個字母的指令也許方便得多。

以下是我常用的指令,往後會慢慢更新:
  1. 計算機:calc 
  2. 工作管理員:taskmgr
  3. 遠端桌面:mstsc
  4. 登錄編輯程式:regedit
  5. 系統設定公用程式:msconfig
  6. ping
其他更多的指令可參考別人所整理的文件:開始-執行指令大全

關鍵字:Windows XP、XP、開始、執行、指令、輸入、快速
參考資料:
  1. 開始-執行指令大全

2009年11月12日

加快XP開機速度和停頓問題(ADSL使用者)


這篇算是給自己的小筆記。

XP的ADSL使用者常常遇到和我一樣的狀況,
就是開機時網路要等很久或停頓一下才能連線,
連帶地也影響到開機的速度。

面對這種問題可以依以下的步驟解決:
  1. 開始-連線-顯示所有連線 
  2. 區域網路-右鍵-選內容
  3. 一般-Internet Protocol(TCP/IP)-內容
  4. 使用下列的ip位址:IP位址:192.168.0.1,子網路遮罩:255.255.255.0
套用後就可以解決上面的問題了。

關於這個解法很久之前有看過說明,
大意是說XP原本設定會由DHCP自動找IP,但ADSL用戶在連線前並沒有IP,
而XP一直到檢查找不到IP後才會用ADSL連線,也因此會停頓一下。
剛剛google了一下有個大陸的網頁有說明:
如何消除XP开机ADSL拨号等待的问题

其他的XP加速法可參考:
XP使用及加速法!!

關鍵字:Windows XP、ADSL、網路連線、網路、加速
參考資料:
  1. XP使用及加速法!!
  2. 如何消除XP开机ADSL拨号等待的问题

2009年10月11日

為7-Zip變裝:7-Zip Theme Manager


壓縮軟體有很多種,從一開始接觸XP內建的WinZip,
到後來紅透半邊天的WinRAR,一直到現在用的7-Zip
當初會從WinRAR換到7-Zip是因為7-Zip是免費軟體,
而WinRAR雖然在到期後還是能持續用,但用起來就有點不開心 XD。
從WinRAR換到7-Zip在功能上都沒什麼重大的影響,
但在使用介面上7-Zip就相當遜色,
因此今天就要來介紹如何將7-Zip的theme和icon變漂亮。
首先可以連到7-Zip Theme Manager下載軟體,或按這裡下載
將軟體解壓縮後執行 7zTM.exe 。

執行後首先會問我們要何種語言,我想大家大概也只會英文吧(選項還有德文、義大利文)。


因為要更改7-Zip的設定,所以會詢問7-Zip的安裝資料夾在哪,
如果當初安裝時沒有更改的話就用預設值即可。


7-Zip Theme Manager可以更改7-Zip工具列和檔案的圖示,
首先先在左上角選擇 Toolbar Themes,再由下方列表中選擇想要的模式。
這段期間右方都可以直接看到預覽畫面,選完後接下Activate theme即可。



另外若想改變檔案的圖示(也就是icon),則在左上角選擇 Filetype Themes。
這邊的圖示真的比7-Zip內建的漂亮多了呢!選完後一樣記得要 Activate theme。



執行結束後馬上就可以看到成果囉。


關鍵字:7-Zip、7-Zip Theme Manager、圖示、icon、theme、佈景、主題、切換、變更
參考資料:
  1. 7-Zip官方網站
  2. 7-Zip Theme Manager官方網站
  3. 7-Zip Theme Manager 佈景主題切換器,讓你的7-ZIP介面、壓縮檔變漂亮!