如果沒有經過任何設定,當使用 domain name 存取一個對方的主機時,等於是以外部ip傳遞封包
封包一定是經由網域的外部出去internet再到對方的主機,即使對方的主機是和自已主機同網域。
例如:
同一個hub的兩個孔的主機,各指定自己的domain name為ftp.bennu.tw和www.bennu.tw
ftp到www封包路徑 ftp -> hub -> internet -> hub -> www,速度會變得很慢。
這個情況下可以將ftp和www的網卡,假設都是eth0,各綁定第二個內部ip
ftp:
#ifconfig eth0:0 192.168.1.100
www:
#ifconfig eth0:0 192.168.1.101
然後再將各自的/etc/hosts加入:
ftp:
192.168.1.101 www.bennu.tw www
www:
192.168.1.100 ftp.bennu.tw ftp
這樣一來即使使用domain name傳遞封包,路徑就不會再繞到internet,
而是僅僅在內部的網域內傳遞,速度快得多了:
ftp -> hub -> www
2009年3月8日 星期日
2009年3月7日 星期六
python的中文註解
必須在#!/usr/bin/env python下加入:
#-*- coding: utf-8 -*-
否則當python直譯器遇到中文字時會抱怨非ANSI字元,顯示以下訊息:
SyntaxError: Non-ASCII character .....
#-*- coding: utf-8 -*-
否則當python直譯器遇到中文字時會抱怨非ANSI字元,顯示以下訊息:
SyntaxError: Non-ASCII character .....
2009年2月23日 星期一
掃描 XSANE-HP Deskjet
安裝 xsane
sudo aptitude install xsane
並加入 scanner group
sudo usermod -G scanner -a muchu1983
之後在X的功能選單下就可以使用XSane進行掃描。
sudo aptitude install xsane
並加入 scanner group
sudo usermod -G scanner -a muchu1983
之後在X的功能選單下就可以使用XSane進行掃描。
2009年2月16日 星期一
使用 springframework 3.0.0 建立 RESTful 網路應用程式 Controller
RESTful是一種新的Webapp設計概念,可以減少很多傳統Webapp程式的code,
傳統Webapp以一個 url mapping 到一個 service ,如 java servlet 或 spring controller,
以操作資料庫的 CRUD 四個步驟來說,一張資料表至少就需要4個 service 命令來完成實作。
也就是要分別對四個 url 進行操作。
RESTful 則將資料當成一種資源,利用 http 原本就有的 Get、Post、Delete、Put…
等七個 method ,對同一個 url 進行操作,如下圖。

spring 在 3.0版之後的 spring MVC 框架就有提供 RESTful 相關的支援,並使用 java 5.0 的
annotation 語法,用起非常簡單方便。
spring 3.0.0 相依的 jar有:
antlr-3.0.1.jar
asm-3.1.jar
asm-common-3.1.jar
commons-logging.jar
log4j-1.2.13.jar
簡單的 RESTful 範例 /rest/{i}/{n} : i、n 均為變數
web.xml 加入 DispatcherServlet 的servlet定義,並mapping到 /rest/*
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/conf/spring-restful-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
需注意:
DispatcherServlet 因為被 mapping 到 /rest/* 所以在 DispatcherServlet 帶起來的WebApplicationContext 之下 做mapping時, "/"符號就等於 "/rest/"這一層 ,
也就是說 html form action 的 "/rest/1/2/3/4" mapping 要寫成 "/1/2/3/4"。
在 web.xml 指定了 /WEB-INF/conf/spring-restful-config.xml 這個檔為 spring bean config
內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- test jsp view -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="testController"
class="com.transtep.restful.server.framework.spring.controller.TestController">
</bean>
</beans>
spring-restful-config.xml 檔裡有 2 個 bean 負責 spring 2.5 開始有的 annotation MVC功能,
DefaultAnnotationHandlerMapping -> 處理 class level 的 annotation。
AnnotationMethodHandlerAdapter -> 處理 method level 的 annotation。
底下再定義 Controller 的 bean class,這些 bean 就可以用 annotation 的語法來定義了。
如這裡的 TestController :
@Controller
public class TestController {
@RequestMapping(value = "/1/{ii}/{nn}", method = RequestMethod.GET)
public ModelAndView getTest(@PathVariable(value = "ii") String id, @PathVariable(value = "nn") String number) {
System.out.println("run 1");
Map model = new HashMap();
model.put("message", "id " + id + "\n" + "number " + number);
return new ModelAndView("test", model);
}
@RequestMapping(value = "/1/{ii}/{nn}", method = RequestMethod.POST)
public ModelAndView postTest(@PathVariable(value = "ii") String id, @PathVariable(value = "nn") String number) {
Map model = new HashMap();
model.put("message", "id " + id + "\n" + "number " + number);
return new ModelAndView("test", model);
}
}
首先在 class 宣告上以 @Controller 定義這是一個 Controller (不需要再implements Controller)
再以 @RequestMapping 定義各別的 method 的 URI 、 method mapping,特別是 URI 可以{}
定義成變數的格式,再配合 @PathVariable 將變數的實際值綁到 method的參數上,同時根據
方法的參數型別不同,自動轉換成正確的型別。
上面的例子以 get /rest/1/123/456 則會執行 getTest() 方法,id=123,number=456
而如果以 post /rest/1/456/789 則會執行 postTest() 方法,id=456,number=789
傳統Webapp以一個 url mapping 到一個 service ,如 java servlet 或 spring controller,
以操作資料庫的 CRUD 四個步驟來說,一張資料表至少就需要4個 service 命令來完成實作。
也就是要分別對四個 url 進行操作。
RESTful 則將資料當成一種資源,利用 http 原本就有的 Get、Post、Delete、Put…
等七個 method ,對同一個 url 進行操作,如下圖。

spring 在 3.0版之後的 spring MVC 框架就有提供 RESTful 相關的支援,並使用 java 5.0 的
annotation 語法,用起非常簡單方便。
spring 3.0.0 相依的 jar有:
antlr-3.0.1.jar
asm-3.1.jar
asm-common-3.1.jar
commons-logging.jar
log4j-1.2.13.jar
簡單的 RESTful 範例 /rest/{i}/{n} : i、n 均為變數
web.xml 加入 DispatcherServlet 的servlet定義,並mapping到 /rest/*
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/conf/spring-restful-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
需注意:
DispatcherServlet 因為被 mapping 到 /rest/* 所以在 DispatcherServlet 帶起來的WebApplicationContext 之下 做mapping時, "/"符號就等於 "/rest/"這一層 ,
也就是說 html form action 的 "/rest/1/2/3/4" mapping 要寫成 "/1/2/3/4"。
在 web.xml 指定了 /WEB-INF/conf/spring-restful-config.xml 這個檔為 spring bean config
內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- test jsp view -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="testController"
class="com.transtep.restful.server.framework.spring.controller.TestController">
</bean>
</beans>
spring-restful-config.xml 檔裡有 2 個 bean 負責 spring 2.5 開始有的 annotation MVC功能,
DefaultAnnotationHandlerMapping -> 處理 class level 的 annotation。
AnnotationMethodHandlerAdapter -> 處理 method level 的 annotation。
底下再定義 Controller 的 bean class,這些 bean 就可以用 annotation 的語法來定義了。
如這裡的 TestController :
@Controller
public class TestController {
@RequestMapping(value = "/1/{ii}/{nn}", method = RequestMethod.GET)
public ModelAndView getTest(@PathVariable(value = "ii") String id, @PathVariable(value = "nn") String number) {
System.out.println("run 1");
Map
model.put("message", "id " + id + "\n" + "number " + number);
return new ModelAndView("test", model);
}
@RequestMapping(value = "/1/{ii}/{nn}", method = RequestMethod.POST)
public ModelAndView postTest(@PathVariable(value = "ii") String id, @PathVariable(value = "nn") String number) {
Map
model.put("message", "id " + id + "\n" + "number " + number);
return new ModelAndView("test", model);
}
}
首先在 class 宣告上以 @Controller 定義這是一個 Controller (不需要再implements Controller)
再以
定義成變數的格式,再配合 @PathVariable 將變數的實際值綁到 method的參數上,同時根據
方法的參數型別不同,自動轉換成正確的型別。
上面的例子以 get /rest/1/123/456 則會執行 getTest() 方法,id=123,number=456
而如果以 post /rest/1/456/789 則會執行 postTest() 方法,id=456,number=789
2009年2月10日 星期二
在 xorg.conf 檔調整顯示器的水平垂直更新率
每個場商的每個螢幕的設定範圍都不同,即使設定不正確螢幕也不一定就沒畫面,
有可能是在執行某些需要特殊畫面更新率的軟體,例如640x480解析度的遊戲時,
會因為更新率不支援(其實是沒設定好),而造成畫面一片黑,出現 out of range 等等。
先查詢螢幕的正確水平,垂直更新率。
編輯 /etc/X11/xorg.conf
找到 Section "Monitor" 裡面有 HorizSync VertRefresh 兩項,
各自填入查到的 水平(HorizSync)、垂直(VertRefresh) 更新率,
有時可能填的範圍要比查詢到的還小一點,50.0 - 80.0 可以只填 30.0 - 70.0就好。
更新後 startx 進入X,切換一下解析度,看看能不能正常顯示。
有可能是在執行某些需要特殊畫面更新率的軟體,例如640x480解析度的遊戲時,
會因為更新率不支援(其實是沒設定好),而造成畫面一片黑,出現 out of range 等等。
先查詢螢幕的正確水平,垂直更新率。
編輯 /etc/X11/xorg.conf
找到 Section "Monitor" 裡面有 HorizSync VertRefresh 兩項,
各自填入查到的 水平(HorizSync)、垂直(VertRefresh) 更新率,
有時可能填的範圍要比查詢到的還小一點,50.0 - 80.0 可以只填 30.0 - 70.0就好。
更新後 startx 進入X,切換一下解析度,看看能不能正常顯示。
2009年2月8日 星期日
lenny中使用wine設定執行魔獸爭霸3
首先安裝wine就不多說了,我使用的是1.0.1-1
安裝好wine後,先執行winecfg設定一下
1.windows版本的地方選windows 2000
2.函式庫->已有的函式庫頂替 維持空的
3.顯示 -> 模擬一個虛擬桌面 打勾 800x600
4.儲存槽 -> 按一下自動偵測 讓wine對應linux的路徑到磁碟機代號
開始安裝Warcraft3,如果已經有安裝好的則直接copy過來linux下,跳過這一步
mount主程式的光碟,並在光碟的掛載點下執行wine install.exe
mount資料片的光碟,並在光碟的掛載點下執行wine install.exe
更新patch
下載 http://todian.myweb.hinet.net/ 提供的傻瓜包來更新
更新完成後也會變成免光碟版,一樣以 wine 執行更新程式,
wine warcraft_patch_upgrade_122a_v3.exe
選擇Warcraft III的安裝(或copy)資料夾,由於傻包完成後會自動執行遊戲,
但wine的Directx3D還不夠完整,現在執行畫面可能一片黑,先想辦法關掉遊戲
大絕招是ctrl-alt-←關掉整個X再startx
透過安裝步驟 wine的register表也會自動加入Warcraft資料,
但如果是從別的地方copy的,就要手動去新增wine register裡的資料
執行 regedit
找到下列的key,如果沒有就按右鍵新增key(一個key就是一層資料夾)
HKEY_CURRENT_USER\Software\Blizzard Entertainment\Warcraft III
在右側建立名為Gfx OpenGL的DWORD值,Value data設置為1
(這個regedit主要設定War3以opengl執行遊戲)
現在回到 Warcraft III 資料夾下,執行
wine War3.exe -opengl或wine War3.exe -x11
順利的話會在wine虛擬桌面下看到開場動畫,等動畫播完,遊戲畫面會一片黑
滑鼠點一下黑色的遊戲畫面,則遊戲界面就會出來。先離開遊戲
再次執行 winecfg
將 顯示 -> 模擬一個虛擬桌面 打勾取消掉
重新回到Warcraft III 資料夾下,執行
wine War3.exe -opengl或wine War3.exe -x11
就可以以全螢幕進行遊戲了。
(因為開場動畫沒有用虛擬桌面的話就不能播)
安裝好wine後,先執行winecfg設定一下
1.windows版本的地方選windows 2000
2.函式庫->已有的函式庫頂替 維持空的
3.顯示 -> 模擬一個虛擬桌面 打勾 800x600
4.儲存槽 -> 按一下自動偵測 讓wine對應linux的路徑到磁碟機代號
開始安裝Warcraft3,如果已經有安裝好的則直接copy過來linux下,跳過這一步
mount主程式的光碟,並在光碟的掛載點下執行wine install.exe
mount資料片的光碟,並在光碟的掛載點下執行wine install.exe
更新patch
下載 http://todian.myweb.hinet.net/ 提供的傻瓜包來更新
更新完成後也會變成免光碟版,一樣以 wine 執行更新程式,
wine warcraft_patch_upgrade_122a_v3.exe
選擇Warcraft III的安裝(或copy)資料夾,由於傻包完成後會自動執行遊戲,
但wine的Directx3D還不夠完整,現在執行畫面可能一片黑,先想辦法關掉遊戲
大絕招是ctrl-alt-←關掉整個X再startx
透過安裝步驟 wine的register表也會自動加入Warcraft資料,
但如果是從別的地方copy的,就要手動去新增wine register裡的資料
執行 regedit
找到下列的key,如果沒有就按右鍵新增key(一個key就是一層資料夾)
HKEY_CURRENT_USER\Software\Blizzard Entertainment\Warcraft III
在右側建立名為Gfx OpenGL的DWORD值,Value data設置為1
(這個regedit主要設定War3以opengl執行遊戲)
現在回到 Warcraft III 資料夾下,執行
wine War3.exe -opengl或wine War3.exe -x11
順利的話會在wine虛擬桌面下看到開場動畫,等動畫播完,遊戲畫面會一片黑
滑鼠點一下黑色的遊戲畫面,則遊戲界面就會出來。先離開遊戲
再次執行 winecfg
將 顯示 -> 模擬一個虛擬桌面 打勾取消掉
重新回到Warcraft III 資料夾下,執行
wine War3.exe -opengl或wine War3.exe -x11
就可以以全螢幕進行遊戲了。
(因為開場動畫沒有用虛擬桌面的話就不能播)
2009年2月7日 星期六
debian下apache2安裝mod_python模組
首先安裝好apache2
sudo aptitude install apache2
安裝好後預設的web context根目錄會在/var/www下
安裝mod_python模組
sudo aptitude install libapache2-mod-python
設定網站支援mod_python
vim /etc/apache2/sites-available/default
在Directory /var/www的項目中
把內容改為:
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
AddHandler mod_python .py
PythonHandler mod_python.publisher
PythonDebug On
存檔
重新啟動apache
/etc/init.d/apache2 restart
這樣就完成mod_python的安裝與設定了
現在可以建立python程式
vi /var/www/test.py
內容為:
#!/usr/bin/env python
def index(req):
return "Test successful";
以browser連到 http://localhost/test.py
就可以看到 Test successful 的輸出結果。
sudo aptitude install apache2
安裝好後預設的web context根目錄會在/var/www下
安裝mod_python模組
sudo aptitude install libapache2-mod-python
設定網站支援mod_python
vim /etc/apache2/sites-available/default
在Directory /var/www的項目中
把內容改為:
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
AddHandler mod_python .py
PythonHandler mod_python.publisher
PythonDebug On
存檔
重新啟動apache
/etc/init.d/apache2 restart
這樣就完成mod_python的安裝與設定了
現在可以建立python程式
vi /var/www/test.py
內容為:
#!/usr/bin/env python
def index(req):
return "Test successful";
以browser連到 http://localhost/test.py
就可以看到 Test successful 的輸出結果。
2009年1月23日 星期五
svnadmin dump 參數說明
在命令列下輸入
$svnadmin help dump 會出現以下訊息:
dump: 用法: svnadmin dump REPOS_PATH [-r LOWER[:UPPER]] [--incremental]
將檔案系統的內容, 以一種可攜式 '傾印檔' 格式輸出到標準輸出, 並將訊息
回報輸出到標準錯誤. 將 LOWER 與 UPPER 之間修訂版內容傾印出來. 如果沒
有指定修訂版的話, 傾印所有的修訂版樹. 如果只有指定 LOWER 的話, 只傾印
一個修訂版樹. 如果使用了 --incremental 選項, 那麼第一個傾印的修訂版會
是與前一個修訂版的差異, 而非平常的全文輸出.
有效選項:
-r [--revision] ARG : 指定修訂版編號 ARG (或 X:Y 範圍)
--incremental : 以差異增量進行傾印
--deltas : 於傾印檔輸出中使用檔案差異
-q [--quiet] : 不顯示進度 (僅錯誤) 至標準錯誤輸出
僅備份部分版本需使用 -r 參數,如:
repos檔案庫的最新版本號為100
svnadmin dump repos/ -r 90:100
即是完整備份90到最新的100的資料,但下次使用svnadmin load指令回來時
版本會從1開始算,也就是之前的版本90變成版本1
--incremental是進行差異備份,影響的是第一個版本的內容,如:
svnadmin dump repos/ -r 90:100 --incremental
一樣是備份 90-100 之間的資料,但版本90的資料卻不包含版本89之前的資料
也就是備份出來的資料必須建立在已經有版本89的檔案庫為基礎的檔案庫
如果 svnadmin load 時沒有版本 89的檔案庫為基礎,則會出現錯誤。
$svnadmin help dump 會出現以下訊息:
dump: 用法: svnadmin dump REPOS_PATH [-r LOWER[:UPPER]] [--incremental]
將檔案系統的內容, 以一種可攜式 '傾印檔' 格式輸出到標準輸出, 並將訊息
回報輸出到標準錯誤. 將 LOWER 與 UPPER 之間修訂版內容傾印出來. 如果沒
有指定修訂版的話, 傾印所有的修訂版樹. 如果只有指定 LOWER 的話, 只傾印
一個修訂版樹. 如果使用了 --incremental 選項, 那麼第一個傾印的修訂版會
是與前一個修訂版的差異, 而非平常的全文輸出.
有效選項:
-r [--revision] ARG : 指定修訂版編號 ARG (或 X:Y 範圍)
--incremental : 以差異增量進行傾印
--deltas : 於傾印檔輸出中使用檔案差異
-q [--quiet] : 不顯示進度 (僅錯誤) 至標準錯誤輸出
僅備份部分版本需使用 -r 參數,如:
repos檔案庫的最新版本號為100
svnadmin dump repos/ -r 90:100
即是完整備份90到最新的100的資料,但下次使用svnadmin load指令回來時
版本會從1開始算,也就是之前的版本90變成版本1
--incremental是進行差異備份,影響的是第一個版本的內容,如:
svnadmin dump repos/ -r 90:100 --incremental
一樣是備份 90-100 之間的資料,但版本90的資料卻不包含版本89之前的資料
也就是備份出來的資料必須建立在已經有版本89的檔案庫為基礎的檔案庫
如果 svnadmin load 時沒有版本 89的檔案庫為基礎,則會出現錯誤。
2009年1月19日 星期一
非 standalone jetty的啟動關閉方式
非 standalone jetty的啟動關閉方式:
cd %JETTY_HOME%
java -DSTOP.PORT=8079 -DSTOP.KEY=secret -jar start.jar
這將告訴Jetty在8079 Port偵聽Stop命令,並且Stop時要求提供Key:secret。對應的Stop命令:
java -DSTOP.PORT=8079 -DSTOP.KEY=secret -jar start.jar --stop
一個簡單的 shell script進行控制
#!/bin/bash
cd /usr/local/jetty-6.1.12.rc2
if [ "$1" == "start" ]; then
java -DSTOP.PORT=8079 -DSTOP.KEY=green -jar start.jar etc/jetty.xml etc/green-jaas.xml &
elif [ "$1" == "stop" ]; then
java -DSTOP.PORT=8079 -DSTOP.KEY=green -jar start.jar --stop
else
echo "useage: switch.sh [start|stop]."
fi
cd %JETTY_HOME%
java -DSTOP.PORT=8079 -DSTOP.KEY=secret -jar start.jar
這將告訴Jetty在8079 Port偵聽Stop命令,並且Stop時要求提供Key:secret。對應的Stop命令:
java -DSTOP.PORT=8079 -DSTOP.KEY=secret -jar start.jar --stop
一個簡單的 shell script進行控制
#!/bin/bash
cd /usr/local/jetty-6.1.12.rc2
if [ "$1" == "start" ]; then
java -DSTOP.PORT=8079 -DSTOP.KEY=green -jar start.jar etc/jetty.xml etc/green-jaas.xml &
elif [ "$1" == "stop" ]; then
java -DSTOP.PORT=8079 -DSTOP.KEY=green -jar start.jar --stop
else
echo "useage: switch.sh [start|stop]."
fi
2009年1月14日 星期三
debian base安裝+icewm+基本套件
安裝好base system
xorg:
aptitude install xorg
x window:
aptitude install icewm
update-alternatives --config x-session-manager
update-alternatives --config x-window-manager
terminal:
aptitude install mlterm mlterm-tools
update-alternatives --config x-terminal-emulator
input:
aptitude install gcin
font:
sudo aptitude install ttf-wqy-zenhei
sudo aptitude install xfonts-wqy
xorg:
aptitude install xorg
x window:
aptitude install icewm
update-alternatives --config x-session-manager
update-alternatives --config x-window-manager
terminal:
aptitude install mlterm mlterm-tools
update-alternatives --config x-terminal-emulator
input:
aptitude install gcin
font:
sudo aptitude install ttf-wqy-zenhei
sudo aptitude install xfonts-wqy
修改startx啟動的X windows manager
update-alternatives --config x-session-manager
update-alternatives --config x-window-manager
update-alternatives --config x-window-manager
2009年1月9日 星期五
2009年1月3日 星期六
Debian好看的中文字型-文泉驛
文泉驛
sudo aptitude install ttf-wqy-zenhei
sudo aptitude install xfonts-wqy
文鼎
sudo aptitude install ttf-arphic-bkai00mp
sudo aptitude install ttf-arphic-uming
sudo aptitude install ttf-wqy-zenhei
sudo aptitude install xfonts-wqy
文鼎
sudo aptitude install ttf-arphic-bkai00mp
sudo aptitude install ttf-arphic-uming
Debian安裝過程載入adsl pppoe設定
使用debian安裝光碟開機後,不直接按Enter進入安裝程序.
選擇Help選項,即可查尋及輸入特殊參數,
啟動載入 pppoe 模組的參數:
install modules=ppp-udeb
這樣一來在安裝過程,安裝程式會詢問adsl的帳號密碼
來進行網路設定.
選擇Help選項,即可查尋及輸入特殊參數,
啟動載入 pppoe 模組的參數:
install modules=ppp-udeb
這樣一來在安裝過程,安裝程式會詢問adsl的帳號密碼
來進行網路設定.
2009年1月2日 星期五
建立USB隨身碟debian安裝碟
安裝套件:
DEFAULT vmlinuz auto url=debian.org.tw modules=ppp-udeb
APPEND initrd=initrd.gz
5. copy debian 安裝光碟映象檔
#cp debian-testing-i386-xfce-CD-1.iso /mnt
7. 安裝mbr到USB的開機區
#install-mbr /dev/sdb
8. 重開機並設定BIOS使用USB開機
dosfstools,syslinux,mtools,mbr
步驟:
1. 建立FAT16到USB的第一分割區上
#fdisk /dev/sdb (設定bootable,partition system id)
#mkdosfs /dev/sdb1
2. 安裝syslinux到USB
#syslinux /dev/sdb1 (會在sdb1上建立ldlinux.sys)
3. mount USB 並 copy必需的檔案
#mount /dev/sdb1 /mnt
#cp vmlinuz /mnt (kernel)
#cp initrd.gz /mnt (initrd)
4. 建立 syslinux 設定檔
在 /mnt 新建 syslinux.cfg
內容包含下兩行:DEFAULT vmlinuz auto url=debian.org.tw modules=ppp-udeb
APPEND initrd=initrd.gz
5. copy debian 安裝光碟映象檔
#cp debian-testing-i386-xfce-CD-1.iso /mnt
6. mount USB
#umount /dev/sdb17. 安裝mbr到USB的開機區
#install-mbr /dev/sdb
8. 重開機並設定BIOS使用USB開機
2008年12月25日 星期四
jetty 的 JAAS 啟動設定
不能再以 $JETTY_HOME/bin/jetty.sh start 啟動 jetty server
而是在 $JETTY_HOME 下,以 java -jar start.jar etc/jetty.xml etc/jetty-jaas.xml 來啟動 server
首先在 webapp 的 web.xml 下加入有關的security設定,主要是以下3個tag:
security-constraint 、login-config、security-role,
其中login-config下的realm-name會對應到 etc/jetty-jaas.xml下的UserRealm中的setName資料
JAAS又自動從java.security.auth.login.config環境變數指定到的檔案中去找到UserRealm中
LoginModuleName所設定的名字進而找到java.security.auth.login.config裡應該被運作的
LoginModule 。
web.xml(設定realm-name) =>
jetty-jaas.xml (設定realm與LoginModule對應,與指定LoginModule設定檔位置) =>
java.security.auth.login.config(指定LoginModule設定檔位置) =>
LoginModule設定檔(某LoginModuleName使用哪些LoginModule的實作類別及其條件參數)
而是在 $JETTY_HOME 下,以 java -jar start.jar etc/jetty.xml etc/jetty-jaas.xml 來啟動 server
首先在 webapp 的 web.xml 下加入有關的security設定,主要是以下3個tag:
security-constraint 、login-config、security-role,
其中login-config下的realm-name會對應到 etc/jetty-jaas.xml下的UserRealm中的setName資料
JAAS又自動從java.security.auth.login.config環境變數指定到的檔案中去找到UserRealm中
LoginModuleName所設定的名字進而找到java.security.auth.login.config裡應該被運作的
LoginModule 。
web.xml(設定realm-name) =>
jetty-jaas.xml (設定realm與LoginModule對應,與指定LoginModule設定檔位置) =>
java.security.auth.login.config(指定LoginModule設定檔位置) =>
LoginModule設定檔(某LoginModuleName使用哪些LoginModule的實作類別及其條件參數)
2008年12月12日 星期五
DNS修改ip對應的小技巧
假設最優先DNS server 為 168.95.1.1
當有client要尋找某網址的ip時,例如要找:www.google.com.tw
168.95.1.1的運作方式是:
會先去問(root) . DNS -> .tw DNS -> .com.tw DNS -> .google.com.tw
但一但問到後168.95.1.1 DNS server會將www.google.com.tw的對應暫時放在memory裡
這樣下一次又有client問www.google.com.tw時就不用再跑一次,
不過如果www.google.com.tw改了ip位址,這樣一來所有和168.95.1.1詢問的client
都會問到錯的ip,這時可以將client的DNS server優先順序改一下,
讓client暫時以別台沒有暫存www.google.com.tw的DNS server去重新由root開始查找ip
如此即可暫時解決,而約1-2天後168.95.1.1的暫存記錄也會因timeout而消失,
這時到168.95.1.1查找的client也可以找到對的ip了。
當有client要尋找某網址的ip時,例如要找:www.google.com.tw
168.95.1.1的運作方式是:
會先去問(root) . DNS -> .tw DNS -> .com.tw DNS -> .google.com.tw
但一但問到後168.95.1.1 DNS server會將www.google.com.tw的對應暫時放在memory裡
這樣下一次又有client問www.google.com.tw時就不用再跑一次,
不過如果www.google.com.tw改了ip位址,這樣一來所有和168.95.1.1詢問的client
都會問到錯的ip,這時可以將client的DNS server優先順序改一下,
讓client暫時以別台沒有暫存www.google.com.tw的DNS server去重新由root開始查找ip
如此即可暫時解決,而約1-2天後168.95.1.1的暫存記錄也會因timeout而消失,
這時到168.95.1.1查找的client也可以找到對的ip了。
2008年12月11日 星期四
滑鼠連點3下觸發mouse listener實作(AWT)
source.addMouseListener(new MouseAdapter() {
private int interval = 300; // ms
private int target = 3; // 連點3下
private int addup = 0; // 已連點了addup下
private Calendar calPriorTime = Calendar.getInstance();
@Override
public void mouseClicked(java.awt.event.MouseEvent e) {
Calendar calNow = Calendar.getInstance();
long curInterval = calNow.getTimeInMillis() - calPriorTime.getTimeInMillis();
if (curInterval > interval) {
// 點第一下(和上一次點的時間相差太久)
addup = 1;
} else {
// 連點(和上一次點的時間相差在interval內)
addup++;
}
if (addup >= target) {
addup = 0;
System.out.println("連點三下已被觸發。");
}
calPriorTime = calNow;
}
});
private int interval = 300; // ms
private int target = 3; // 連點3下
private int addup = 0; // 已連點了addup下
private Calendar calPriorTime = Calendar.getInstance();
@Override
public void mouseClicked(java.awt.event.MouseEvent e) {
Calendar calNow = Calendar.getInstance();
long curInterval = calNow.getTimeInMillis() - calPriorTime.getTimeInMillis();
if (curInterval > interval) {
// 點第一下(和上一次點的時間相差太久)
addup = 1;
} else {
// 連點(和上一次點的時間相差在interval內)
addup++;
}
if (addup >= target) {
addup = 0;
System.out.println("連點三下已被觸發。");
}
calPriorTime = calNow;
}
});
2008年12月5日 星期五
JUnit 4 簡介
JUnit 4是JUnit框架有史以來的最大改進,其主要目標便是利用Java 5的Annotation特性簡化測試用例的編寫。讓我們看看如何使用JUnit 4來進行Unit測試。
我們先看一個簡單的Math類:
package com.javaeedev.junit4;
public class Math {
public int abs(int value) {
return value>=0 ? value : (-value);
}
public int div(int a, int b) {
return a / b;
}
/**
* BUG: if b less than 0!
*/
public float exp(int a, int b) {
float r = 1;
for(int i=0; i
r = r * a;
return r;
}
}
注意exp()方法是有Bug的,如果傳入參數2, -1,則期待的返回值應為0.5F,但實際返回值為1.0F。
傳統的JUnit的TestCase:
public class MathTest extends TestCase {
public void setUp() { super.setUp(); }
public void tearDown() { super.tearDown(); }
public void testAbs() { assertTrue(true); }
public void testDiv() {...}
public void testExp() {...}
}
JUnit依賴反射來執行每個以test開頭的方法。然而,在最新的JUnit 4中,由於有了Annotation的支持,我們的測試方法不需要再以testXxx標識了,而是寫上一個@Test標註即可。例如:
@Test public void doAbs() {...}
甚 至MathTest類也不必繼承自TestCase。你也許會想到,不繼承自TestCase就無法調用assertXxx方法了,正因為如此,所有的 assertXxx方法全部以靜態方法被放入了Assert類,使用Assert.assertXxx()調用。如果使用
import static org.junit.Assert.*;
則原有的代碼不必改動。
setUp()和tearDown()方法也依賴@Before和@After標記,這樣做的最大的好處是在繼承體系內不必擔心忘記了在setUp ()方法中調用父類的super.setUp()方法,JUnit框架會自動處理父類的@Before和@After標記的方法。
並且,JUnit框架對@Before和@After的調用順序類似於類的構造方法和析構方法,即@Before按照父類到子類的順序調用,@After則相反,這樣保證了資源的正確獲取和釋放。
當然,不再強迫必須使用setUp和tearDown作為方法名,可以使用更有意義的方法名,例如:initDatabase()和closeDatabase(),只要它們被標註了@Before和@After即可。
來看看使用Annotation的MathTest:
package com.javaeedev.junit4;
import static org.junit.Assert.*;
import org.junit.*;
public class MathTest {
public MathTest() {
System.out.println("new MathTest instance.");
}
@Before
public void setUp() throws Exception {
System.out.println("call @Before before a test method");
}
@After
public void tearDown() throws Exception {
System.out.println("call @After after a test method");
}
@Test
public void doAbs() {
Math math = new Math();
assertEquals(200, math.abs(200));
assertEquals(100, math.abs(-100));
assertEquals(0, math.abs(0));
}
@Test
public void doDiv() {
Math math = new Math();
assertEquals(5, math.div(100, 20));
assertEquals(4, math.div(100, 21));
}
@Test(expected=ArithmeticException.class)
public void doDiv0() {
new Math().div(127, 0);
}
@Test(timeout=1)
public void doLongTimeTask() {
double d = 0;
for(int i=1; i<10000000; i )
d =i;
}
@Test
public void testExp() {
Math math = new Math();
assertEquals(32f, math.exp(2, 5), 0.001f);
assertEquals(1f, math.exp(2, 0), 0.001f);
assertEquals(0.5f, math.exp(2, (-1)), 0.001f);
}
}
對測試異常,JUnit 4可以用expected=Exception.class來期待一個預期的異常,而不必編寫
try {
...
fail("No exception");
}
catch(Exception e) {
// OK!
}
來看看doDiv0測試,我們期待一個除數為0的ArithmeticException,因此編寫如下測試方法:
@Test(expected=ArithmeticException.class)
public void doDiv0() {
new Math().div(127, 0);
}
對於非常耗時的測試,@Test還有一個timeout來標識該方法最長執行時間,超過此時間即表示該測試方法失敗:
@Test(timeout=1)
public void doLongTimeTask() {
double d = 0;
for(int i=1; i<10000000; i )
d =i;
}
以上方法若執行時間超過1ms則測試失敗,由於依賴CPU的執行速度,在不同的機器上測試結果也不同。
JUnit 4另一個較大的變化是引入了@BeforeClass和@AfterClass,它們在一個Test類的所有測試方法執行前後各執行一次。這是為了能在 @BeforeClass中初始化一些昂貴的資源,例如數據庫連接,然後執行所有的測試方法,最後在@AfterClass中釋放資源。
正如你能想到的,由於@BeforeClass和@AfterClass僅執行一次,因此它們只能標記靜態方法,在所有測試方法中共享的資源也必須是靜態引用:
private static Object dbConnection;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("call @BeforeClass and init database connection");
dbConnection = new Object();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("call @AfterClass to release database connection");
dbConnection = null;
}
最後執行測試用例,可以看到結果:
各個方法執行順序如下:
call @BeforeClass and init database connection
new MathTest instance.
call @Before before a test method
call @After after a test method
new MathTest instance.
call @Before before a test method
call @After after a test method
...
call @AfterClass to release database connection
可以看到,@BeforeClass是在實例化MathTest之前調用的,因此不能在構造方法中初始化共享資源。
最後需要注意的是由於Java 5的自動Box/Unbox特性,在調用assertEquals()時要特別注意,如果你傳入:
assertEquals(100F, 100);
則按照自動Box變為:
assertEquals(new Float(100F), new Integer(100));
測試失敗,因為Float類和Integer類不是同一類型。
因此要特別注意float和double的測試。事實上對float和double應使用
assertEquals(float, float, float delta);
assertEquals(double, double, double delta);
delta指定了兩個作比較的浮點數的相差範圍,在此範圍內的兩個浮點數將認為相等。可以傳入一個很小的數例如0.0001F。
JUnit 4非常適合使用Java 5的開發人員,但是無法在Java 1.4中獲得這些好處,並且,也不與以前的版本兼容。因此,如果你正在使用Java 5,就可以考慮使用JUnit 4來編寫測試。
我們先看一個簡單的Math類:
package com.javaeedev.junit4;
public class Math {
public int abs(int value) {
return value>=0 ? value : (-value);
}
public int div(int a, int b) {
return a / b;
}
/**
* BUG: if b less than 0!
*/
public float exp(int a, int b) {
float r = 1;
for(int i=0; i
r = r * a;
return r;
}
}
注意exp()方法是有Bug的,如果傳入參數2, -1,則期待的返回值應為0.5F,但實際返回值為1.0F。
傳統的JUnit的TestCase:
public class MathTest extends TestCase {
public void setUp() { super.setUp(); }
public void tearDown() { super.tearDown(); }
public void testAbs() { assertTrue(true); }
public void testDiv() {...}
public void testExp() {...}
}
JUnit依賴反射來執行每個以test開頭的方法。然而,在最新的JUnit 4中,由於有了Annotation的支持,我們的測試方法不需要再以testXxx標識了,而是寫上一個@Test標註即可。例如:
@Test public void doAbs() {...}
甚 至MathTest類也不必繼承自TestCase。你也許會想到,不繼承自TestCase就無法調用assertXxx方法了,正因為如此,所有的 assertXxx方法全部以靜態方法被放入了Assert類,使用Assert.assertXxx()調用。如果使用
import static org.junit.Assert.*;
則原有的代碼不必改動。
setUp()和tearDown()方法也依賴@Before和@After標記,這樣做的最大的好處是在繼承體系內不必擔心忘記了在setUp ()方法中調用父類的super.setUp()方法,JUnit框架會自動處理父類的@Before和@After標記的方法。
並且,JUnit框架對@Before和@After的調用順序類似於類的構造方法和析構方法,即@Before按照父類到子類的順序調用,@After則相反,這樣保證了資源的正確獲取和釋放。
當然,不再強迫必須使用setUp和tearDown作為方法名,可以使用更有意義的方法名,例如:initDatabase()和closeDatabase(),只要它們被標註了@Before和@After即可。
來看看使用Annotation的MathTest:
package com.javaeedev.junit4;
import static org.junit.Assert.*;
import org.junit.*;
public class MathTest {
public MathTest() {
System.out.println("new MathTest instance.");
}
@Before
public void setUp() throws Exception {
System.out.println("call @Before before a test method");
}
@After
public void tearDown() throws Exception {
System.out.println("call @After after a test method");
}
@Test
public void doAbs() {
Math math = new Math();
assertEquals(200, math.abs(200));
assertEquals(100, math.abs(-100));
assertEquals(0, math.abs(0));
}
@Test
public void doDiv() {
Math math = new Math();
assertEquals(5, math.div(100, 20));
assertEquals(4, math.div(100, 21));
}
@Test(expected=ArithmeticException.class)
public void doDiv0() {
new Math().div(127, 0);
}
@Test(timeout=1)
public void doLongTimeTask() {
double d = 0;
for(int i=1; i<10000000; i )
d =i;
}
@Test
public void testExp() {
Math math = new Math();
assertEquals(32f, math.exp(2, 5), 0.001f);
assertEquals(1f, math.exp(2, 0), 0.001f);
assertEquals(0.5f, math.exp(2, (-1)), 0.001f);
}
}
對測試異常,JUnit 4可以用expected=Exception.class來期待一個預期的異常,而不必編寫
try {
...
fail("No exception");
}
catch(Exception e) {
// OK!
}
來看看doDiv0測試,我們期待一個除數為0的ArithmeticException,因此編寫如下測試方法:
@Test(expected=ArithmeticException.class)
public void doDiv0() {
new Math().div(127, 0);
}
對於非常耗時的測試,@Test還有一個timeout來標識該方法最長執行時間,超過此時間即表示該測試方法失敗:
@Test(timeout=1)
public void doLongTimeTask() {
double d = 0;
for(int i=1; i<10000000; i )
d =i;
}
以上方法若執行時間超過1ms則測試失敗,由於依賴CPU的執行速度,在不同的機器上測試結果也不同。
JUnit 4另一個較大的變化是引入了@BeforeClass和@AfterClass,它們在一個Test類的所有測試方法執行前後各執行一次。這是為了能在 @BeforeClass中初始化一些昂貴的資源,例如數據庫連接,然後執行所有的測試方法,最後在@AfterClass中釋放資源。
正如你能想到的,由於@BeforeClass和@AfterClass僅執行一次,因此它們只能標記靜態方法,在所有測試方法中共享的資源也必須是靜態引用:
private static Object dbConnection;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("call @BeforeClass and init database connection");
dbConnection = new Object();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("call @AfterClass to release database connection");
dbConnection = null;
}
最後執行測試用例,可以看到結果:
各個方法執行順序如下:
call @BeforeClass and init database connection
new MathTest instance.
call @Before before a test method
call @After after a test method
new MathTest instance.
call @Before before a test method
call @After after a test method
...
call @AfterClass to release database connection
可以看到,@BeforeClass是在實例化MathTest之前調用的,因此不能在構造方法中初始化共享資源。
最後需要注意的是由於Java 5的自動Box/Unbox特性,在調用assertEquals()時要特別注意,如果你傳入:
assertEquals(100F, 100);
則按照自動Box變為:
assertEquals(new Float(100F), new Integer(100));
測試失敗,因為Float類和Integer類不是同一類型。
因此要特別注意float和double的測試。事實上對float和double應使用
assertEquals(float, float, float delta);
assertEquals(double, double, double delta);
delta指定了兩個作比較的浮點數的相差範圍,在此範圍內的兩個浮點數將認為相等。可以傳入一個很小的數例如0.0001F。
JUnit 4非常適合使用Java 5的開發人員,但是無法在Java 1.4中獲得這些好處,並且,也不與以前的版本兼容。因此,如果你正在使用Java 5,就可以考慮使用JUnit 4來編寫測試。
訂閱:
文章 (Atom)

