部落客廣告聯播

2007年5月23日 星期三

不只是System.out.print, 筆記: log4j

不只是System.out.print, 筆記: log4j

不管是使用什麼工具撰寫WebApplication,即使IDE提供或多或少的除錯及變數監看的能力,
但使用System.out.println()來尋找出錯誤似乎常有也是最簡單的除錯方式。
但問題就在於,開發階段寫了一堆System.out.print(),等到上線時,這些為了除錯所輸出的訊息,
可能會在螢幕顯示出許多不應該讓使用者知道的資訊,造成安全上的問題,亦或者是這些輸出被container
(如tomcat)寫到檔案去了,造成不必要的儲存空間浪費。

log4j提供了紀錄資訊的一整套framework,透過debug()、info()、warn()、error()、fatal()五層級及
log4j的設定檔,可以設定將某層級及以下層級的訊息關閉輸出。
此外透過appender可將訊息單存輸出到console或轉輸出到file或database中。

1. Logger --> 接收訊息的紀錄器
Logger為階層式。最上層Logger為RootLogger。 ==> Logger.getRootLogger();
通常都會各自class建立Logger。 ==> Logger lg=Logger.getLogger(this.getClass());

2. Appender --> 執行將Logger的訊息寫入特定目的
八種Appender:
a. ConsoleAppender
b. FileAppender
c. RollingFileAppender --> 達某大小後,會rotate
d. DailyRollingFileAppender --> 每天固定rotate
e. JDBCAppender --> 資料庫
f. NTEventLogAppender --> windows only
g. SMTPAppender --> mail
h. SocketAppender

3. Layout --> 用來格式化在Logger裡的訊息
Layout中可用的變數:
a. %c -->logger的名稱
b. %d -->日期與時間
c. %m -->訊息
d. %n -->換行(平台無關)
e. %p -->訊息所屬層級(五層級之一)
f. %t -->thread名稱
g. %% -->百分比符號(跳脫字元)
h. %C -->class名稱
i. %F -->檔名
j. %L -->行號

上列 %x 兩字元中可插入:
a. - -->向左對齊
b. m -->最大長度
c. n -->最小長度

%d後可接{simpleDateFormat字串}來指定要使用的日期格式。

範例:
%-50m%n --> 向左對齊,最大長度為50字
%d{yyyy/MM/dd}

4. 設定檔log4j.properties要放在class path中。
5. log4j.prooerties範例:
log4j.rootLogger=Info,appConsole
log4j.appender.appConsole=org.apache.log4j.ConsoleAppender
log4j.appender.appConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.appConsole.layout.ConversionPattern=%-m [%-d{yyyy/MM/dd} ,%c]%n

6. 更多文件:
官方文件
Reporting Application Errors by Email

2007年5月22日 星期二

筆記: Java Collections

1. Collection Interfaces:


2. Set --> not duplicate , List --> can duplicate,ordered.

3. Hashtable --> Map.

4. 2 種往返Collection的方法:
a. for迴圈

for (Object o : collection)
System.out.println(o);

b. Iterator
static void filter(Collection<?> c) {

for (Iterator<?> it = c.iterator(); it.hasNext(); )
if (!cond(it.next()))
it.remove();
}

5. 移除collection裡的所有null元素:
c.removeAll(Collections.singleton(null));

6. 陣列和collection的橋樑: toArray()

7. Set -->
a. HashSet--> not ordered, fast
b. TreeSet --> ordered by element value. slow
c. LinkedHashSet --> ordered
8. List -->
a. ArrayList-->
b. LinkedList-->

9. List interface:
public interface List<E> extends Collection<E> {
// Positional access
E get(int index);
E set(int index, E element); //optional
boolean add(E element); //optional
void add(int index, E element); //optional
E remove(int index); //optional
boolean addAll(int index,Collection<? extends E> c); //optional

// Search
int indexOf(Object o);
int lastIndexOf(Object o);

// Iteration
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);

// Range-view
List<E> subList(int from, int to);
}

10. Array to List:
java.utli.Arrays.asList(arr);

11. List.iterator傳回ListIterator物件。
12. ListIterator介面:
public interface ListIterator<E> extends Iterator<E> {
boolean hasNext();
E next();
boolean hasPrevious();
E previous();
int nextIndex();
int previousIndex();
void remove(); //optional
void set(E e); //optional
void add(E e); //optional
}

13. Queue 介面:
public interface Queue<E> extends Collection<E> {
boolean offer(E e); -> bounded Queue時,若已滿,傳回false。
add(E e) -> bounded Queue時,若已滿,IllegalStateException。
E peek(); -> //Queue空時,傳回Null,取出但不刪除
E element(); --> //Queue空時,NoSuchElementException,取出但不刪除
E poll(); //Queue空時,傳回Null
E remove(); //Queue空時,NoSuchElementException
}

14. Map 介面:
public interface Map<K,V> {

// Basic operations
V put(K key, V value);
V get(Object key);
V remove(Object key);
boolean containsKey(Object key);
boolean containsValue(Object value);
int size();
boolean isEmpty();

// Bulk operations
void putAll(Map<? extends K, ? extends V> m);
void clear();

// Collection Views
public Set<K> keySet();
public Collection<V> values();
public Set<Map.Entry<K,V>> entrySet();

// Interface for entrySet elements
public interface Entry {
K getKey();
V getValue();
V setValue(V value);
}
}

15. Map -->
a. HashMap
b. TreeMap
c. LinkedHashMap

16. List -- Vector
Map -- HashTable

17. 如果要用Collections.sort(list),在List中的元素需要實做comparable介面。否則會
ClassCastException。

18. Comparable介面:
public interface Comparable<T> {
public int compareTo(T o);
}

19. exam Comparable impl: (from Sun Java Collection Tutorials)
import java.util.*;

public class Name implements Comparable<Name> {
private final String firstName, lastName;

public Name(String firstName, String lastName) {
if (firstName == null || lastName == null)
throw new NullPointerException();
this.firstName = firstName;
this.lastName = lastName;
}

public String firstName() { return firstName; }
public String lastName() { return lastName; }

public boolean equals(Object o) {
if (!(o instanceof Name))
return false;
Name n = (Name)o;
return n.firstName.equals(firstName) &&
n.lastName.equals(lastName);
}

public int hashCode() {
return 31*firstName.hashCode() + lastName.hashCode();
}

public String toString() {
return firstName + " " + lastName;
}

public int compareTo(Name n) {
int lastCmp = lastName.compareTo(n.lastName);
return (lastCmp != 0 ? lastCmp :
firstName.compareTo(n.firstName));
}
}


20. 若要使用collections.sort(e, comparator)需要實做Comparator介面:
public interface Comparator {
int compare(T o1, T o2);
}


21. SortedSet介面:
public interface SortedSet extends Set {
// Range-view
SortedSet subSet(E fromElement, E toElement);
SortedSet headSet(E toElement);
SortedSet tailSet(E fromElement);

// Endpoints
E first();
E last();

// Comparator access
Comparator comparator();

22. SortedMap介面:
public interface SortedMap extends Map{
Comparator comparator();
SortedMap subMap(K fromKey, K toKey);
SortedMap headMap(K toKey);
SortedMap tailMap(K fromKey);
K firstKey();
K lastKey();
}
}

23. implementations: (from Sun Java Collection Tutorials)
General-purpose Implementations
Interfaces Implementations

Hash table Resizable array Tree Linked list Hash table + Linked list
Set HashSet
TreeSet
LinkedHashSet
List
ArrayList
LinkedList
Queue




Map HashMap
TreeMap
LinkedHashMap

2007年5月21日 星期一

CSS筆記:HTML表格隔列交互換底色(CSS Notes: HTML Table background color cross row interchange)

HTML表格隔列交互換底色
(CSS Notes: HTML Table background color cross row interchange)
範例如下:
(Example:)
<style>
.db { border-collapse:collapse;}
.db tr{ background-color:expression('#dbdbdb,#EFEFEF'.split(',')[rowIndex%2]); }
</style>
<table width="100%" border="1" class="db">
<tr>
<td>
fdaafdadfs
</td>
</tr>
<tr>
<td>
fdaafdadfs
</td>
</tr>
</table>

fdaafdadfs
daafdadf
daafdadf
daafdadf

筆記:Java DOC 符號 (Using Java doc symbols)

/**
*@author Dolph

*@param pName 說明

*@return 傳回說明

*@throws IOException

*@see #method(int)

*@see class#method(int)

*@see package.class

*@see package.class#method(int)

*@since Java1.2

*@since JDK1.4

*@deprecated from JDK1.3 ,replaced by {@link #method(int)}

*/

筆記:簡單三步使用JDBC RowSet (使用已有java.sql.Connection物件)
(Notes:Easy using JDBC RowSet with 3 steps (using java.sql.Connection object) )

1. new CachedRowSertXImpl()
CachedRowSetXImpl tuserRowSet = new CachedRowSetXImpl();

2. . .setCommand() //specify SQL command here
tuserRowSet.setCommand("select * from table");

3. query
tuserRowSet.executeQuery(connection);

筆記:簡單五步使用JDBC RowSet (Notes:Easily using JDBC RowSet with 5 steps)

筆記:簡單五步使用JDBC RowSet
(Notes:Easily using JDBC RowSet with 5 steps)
1. new CachedRowSertXImpl()
CachedRowSetXImpl tuserRowSet = new CachedRowSetXImpl();

2. .setDataSourceName()
tuserRowSet.setDataSourceName("java:comp/env/jdbc/some_DatatSrc");

3. .setCommand() //specify SQL command here
tuserRowSet.setCommand("select * from table");

4. tuserRowSet.setTableName()
tuserRowSet.setTableName("TUser");

5. query
tuserRowSet.executeQuery();

2007年5月19日 星期六

筆記:使用Jakarta Upload元件(Note: Using Jakarta Upload component)

1. 記得 form method="post" enctype="multipart/form-data"
1. Remember
form method="post" enctype="multipart/form-data".

2. 參考http://jakarta.apache.org/commons/fileupload/
2. Refer to http://jakarta.apache.org/commons/fileupload/

3. Commons-IO為必要,同樣可從jakarta網站下載。
3. Commons-IO is required,which can be downloaded from the site of jakarta.

4. 基本使用步驟:
1. 檢察是否正確的multipart Request。
ServletFileUpload.isMultipartContent(request)
2.解析。
FileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(factory);
List items=upload.parseRequest(request);
3.處理FileItem(可能為上傳後的檔案、或為表單欄位)
// process file items
Iterator it=items.iterator();
while(it.hasNext())
{
FileItem item=(FileItem)it.next();
String newFileName="";

if(item.isFormField())
{
out.println("Form field parsed:");
out.println("\t field contentType(getContentType()):"+item.getContentType()); // it will be null
out.println("\t field name(getFieldName()):"+item.getFieldName());
out.println("\t value(getString()):"+item.getString());
if(item.getFieldName().equals("fileName")) newFileName=item.getString();
}else
{
out.println("File field parsed:");
out.println("\t field contentType(getContentType()):"+item.getContentType());
out.println("\t field name(getFieldName()):"+item.getFieldName());
out.println("\t value(getString()):"+item.getString());
out.println("\t original file name:"+item.getName());
out.println("\t file size(getSize()):"+String.valueOf(item.getSize()));
out.println("\t isInMemory():"+String.valueOf(item.isInMemory()));
}

out.println("");

}
4.可用FileItem的write(File)寫入檔案,getInputStream()、getOutputStream()進行IO處理。


4.Basic Usage steps:
1. Check request is valid multipart content. (It's a static method)
ServletFileUpload.isMultipartContent(request)
2. parse
FileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(factory);
List items=upload.parseRequest(request);
3. process FileItems(it maybe a uploaded file, or a form filed)
// process file items
Iterator it=items.iterator();
while(it.hasNext())
{
FileItem item=(FileItem)it.next();
String newFileName="";

if(item.isFormField())
{
out.println("Form field parsed:");
out.println("\t field contentType(getContentType()):"+item.getContentType()); // it will be null
out.println("\t field name(getFieldName()):"+item.getFieldName());
out.println("\t value(getString()):"+item.getString());
if(item.getFieldName().equals("fileName")) newFileName=item.getString();
}else
{
out.println("File field parsed:");
out.println("\t field contentType(getContentType()):"+item.getContentType());
out.println("\t field name(getFieldName()):"+item.getFieldName());
out.println("\t value(getString()):"+item.getString());
out.println("\t original file name:"+item.getName());
out.println("\t file size(getSize()):"+String.valueOf(item.getSize()));
out.println("\t isInMemory():"+String.valueOf(item.isInMemory()));
}

out.println("");

}
4. method wirte(File) on FileItem can be used to write uploaded file into disk, and getInputStream() and getOutputStream() can be called to do more IO process.