#
什么是HTTP Referer
簡言之,HTTP
Referer是header的一部分,當瀏覽器向web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器
籍此可以獲得一些信息用于處理。比如從我主頁上鏈接到一個朋友那里,他的服務器就能夠從HTTP
Referer中統計出每天有多少用戶點擊我主頁上的鏈接訪問他的網站。
Referer其實應該是英文單詞Referrer,不過拼錯的人太多了,所以編寫標準的人也就將錯就錯了。
我的問題
我剛剛把feed閱讀器改變為Gregarius,但他不像我以前用的liferea,訪問新浪博客的時候,無法顯示其中的圖片,提示“此圖片僅限于新浪博客用戶交流與溝通”,我知道,這就是HTTP Referer導致的。
由于我上網客戶端配置的特殊性,首先懷疑是squid的問題,但通過實驗排除了,不過同時發現了一個Squid和Tor、Privoxy協同使用的隱私泄露問題,留待以后研究。
Gregarius能處理這個問題么?
答案是否定的,因為Gregarius只是負責輸出html代碼,而對圖像的訪問是有客戶端瀏覽器向服務器請求的。
不過,安裝個firefox擴展也許能解決問題,文中推薦的”Send Referrer”我沒有找到,但發現另外一個可用的:”RefControl“,可以根據訪問網站的不同,控制使用不同的Referer。
但是我不喜歡用Firefox擴展來解決問題,因為我覺得他效率太低,所以我用更好的方式——Privoxy。
Privoxy真棒
在Privoxy的default.action中添加兩行:
{+hide-referrer{forge}}
.album.sina.com.cn
這樣Gregarius中新浪博客的圖片就出來了吧?+hide-referrer
是Privoxy的一個過濾器,設置訪問時對HTTP Referer的處理方式,后面的forge
代表用訪問地址當作Refere的,還可以換成block
,代表取消Referer,或者直接把需要用的Referer網址寫在這里。
用Privoxy比用Firefox簡單的多,趕緊換吧。
From https to http
我還發現,從一個https頁面上的鏈接訪問到一個非加密的http頁面的時候,在http頁面上是檢查不到HTTP Referer的,比如當我點擊自己的https頁面下面的w3c xhtml驗證圖標(網址為http://validator.w3.org/check?uri=referer),從來都無法完成校驗,提示:
No Referer header found!
原來,在http協議的rfc文檔中有定義:
15.1.3 Encoding Sensitive Information in URI's
...
Clients SHOULD NOT include a Referer header field in a (non-secure)
HTTP request if the referring page was transferred with a secure
protocol.
這樣是出于安全的考慮,訪問非加密頁時,如果來源是加密頁,客戶端不發送Referer,IE一直都是這樣實現的,Firefox瀏覽器也不例外。但這并不影響從加密頁到加密頁的訪問。
Firefox中關于Referer的設置
都在里,有兩個鍵值:
-
network.http.sendRefererHeader (default=2)
設置Referer的發送方式,0為完全不發送,1為只在點擊鏈接時發送,在訪問頁面中的圖像什么的時候不發送,2為始終發送。參見Privacy Tip #3: Block Referer Headers in Firefox
-
network.http.sendSecureXSiteReferrer (default=true)
設置從一個加密頁訪問到另外一個加密頁的時候是否發送Referer,true為發送,false為不發送。
利用Referer防止圖片盜鏈
雖然Referer并不可靠,但用來防止圖片盜鏈還是足夠的,畢竟不是每個人都會修改客戶端的配置。實現一般都是通過apache的配置文件,首先設置允許訪問的地址,標記下來:
# 只允許來自domain.com的訪問,圖片可能就放置在domain.com網站的頁面上
SetEnvIfNoCase Referer "^http://www.domain.com/" local_ref
# 直接通過地址訪問
SetEnvIf Referer "^$" local_ref
然后再規定被標記了的訪問才被允許:
<FilesMatch ".(gif|jpg)">
Order Allow,Deny
Allow from env=local_ref
</FilesMatch>
或者
<Directory /web/images>
Order Deny,Allow
Deny from all
Allow from env=local_ref
</Directory>
這方面的文章網上很多,參考:
不要使用Rerferer的地方
不要把Rerferer用在身份驗證或者其他非常重要的檢查上,因為Rerferer非常容易在客戶端被改變,不管是通過上面介紹的Firefox擴展,或者是Privoxy,甚至是libcurl的調用,所以Rerferer數據非常之不可信。
如果你想限制用戶必須從某個入口頁面訪問的話,與其使用Referer,不如使用session,在入口頁面寫入session,然后在其他頁面檢查,如果用戶沒有訪問過入口頁面,那么對應的session就不存在,參見這里的討論。不過和上面說的一樣,也不要過于相信這種方式的“驗證”結果。
個人感覺現在Rerferer除了用在防盜鏈,其他用途最多的就是訪問統計,比如統計用戶都是從哪里的鏈接訪問過來的等等。
1 變量替換
public static void fun1() {
StringTemplate st = new StringTemplate(
"對象變量替換 姓名:$KeyList.Name$, 年齡:$KeyList.Age$ ");
HashMap ht = new HashMap();
ht.put("Name", "李四");
ht.put("Age", "35");
st.setAttribute("KeyList", ht);
System.out.print(st.toString());
}
2 自定義集合替換
public static void fun2() {
StringTemplate st = new StringTemplate(
"自定義集合替換 $List:{姓名:$it.Name$ 年齡:$it.Age$}$");
st.setAttribute("List.{Name,Age}", "王二", "29");
System.out.print(st.toString());
}
3 對象變量替換
定義類
private static class User {
String name;
String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
public static void fun3() {
User us = new User();
us.name = "張三";
us.age = "23";
List<User> uss = new ArrayList<User>();
uss.add(us);
uss.add(us);
uss.add(us);
uss.add(us);
uss.add(us);
StringTemplate st = new StringTemplate(
"<table>$Item:{<tr
class=black><td>$it.name$</td></tr>},{<tr
class=red><td>$it.age$</td></tr>};separator=\"\n\"$</table>");
st.setAttribute("Item", uss);
System.out.print(st.toString());
}
交叉替換
public static void fun4() {
User us = new User();
us.name = "張三";
us.age = "23";
List<User> uss = new ArrayList<User>();
uss.add(us);
uss.add(us);
uss.add(us);
uss.add(us);
uss.add(us);
StringTemplateGroup sg = new StringTemplateGroup("GroupTest");
sg.defineTemplate("RowRed",
"<tr class=red><td>$it.Name$</td><td>$it.Age$</td></tr>\n");
sg.defineTemplate("Rowblack",
"<tr class=black><td>$it.Name$</td><td>$it.Age$</td></tr>\n");
StringTemplate st = sg.defineTemplate("List",
"<table>$Item:RowRed(),Rowblack()$</table>");
st.setAttribute("Item", uss);
System.out.print(st.toString());
}
4 條件判斷
public static void fun5() {
StringTemplate st = new StringTemplate(
"當前用戶登陸狀態: $if(IsAdmin)$ 用戶登陸成功! $else$ 用戶沒有登陸! $endif$");
st.setAttribute("IsAdmin", true);
System.out.print(st.toString());
}
5 sql語句實現
theQuery.st內容
SELECT $column; separator=","$ FROM $table$;
public static void fun6() {
// 一個sql語句的實現
StringTemplateGroup group = new StringTemplateGroup("myGroup", "c:/");
StringTemplate query = group.getInstanceOf("theQuery");
query.setAttribute("column", "name");
query.setAttribute("column", "email");
query.setAttribute("table", "User");
System.out.print(query.toString());
}
6 使用AttributeRenderer
private static class DateRenderer implements AttributeRenderer {
public String toString(Object o) {
SimpleDateFormat f = new SimpleDateFormat("yyyy.MM.dd");
return f.format(((Calendar) o).getTime());
}
}
public static void fun7() {
StringTemplate st = new StringTemplate("date: <created>",
AngleBracketTemplateLexer.class);
st.setAttribute("created", new GregorianCalendar(2005, 07 - 1, 05));
st.registerRenderer(GregorianCalendar.class, new DateRenderer());
String result = st.toString();
System.out.print(result.toString());
}
在Linux上習慣了自動補全功能,在Windows上還真有些不習慣,好在微軟也體諒我們大家,通過修改注冊表可以實現此功能。HKEY_LOCAL_MACHINE-->Software-->Microsoft-->Command Prosessor-->PathCompletionChar的鍵值改為9(16進制)后,在Dos窗口中就可以使用自動補齊功能了。
1.抽象:
抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。抽象并不打算了解全部問題,而只是選擇其中的一部分,暫時不用部分細節。抽象包括兩個方面,一是過程抽象,二是數據抽象。
2.繼承:
繼
承是一種聯結類的層次模型,并且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類可以從現有的類中派生,這個過程稱為類繼承。新類繼
承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。派生類可以從它的基類那里繼承方法和實例變量,并且類可以修改或增
加新的方法使之更適合特殊的需要。
3.封裝:
封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的界面。面向對象計算始于這個基本概念,即現實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的接口訪問其他對象。
4.多態性:
多態性是指允許不同類的對象對同一消息作出響應。多態性包括參數化多態性和包含多態性。多態性語言具有靈活、抽象、行為共享、代碼共享的優勢,很好的解決了應用程序函數同名問題。
Oracle數據庫由
數據文件,控制文件和聯機日志文件三種文件組成。
由于磁盤空間的變化,或者基于數據庫磁盤I/O性能的調整等,我們可能會考慮移動數據庫文件。(
注:恢復數據庫時非常有用,屬于冷備份)
查詢當前數據庫中,相關文件路徑
select * from v$datafile;
select * from v$controlfile;
select * from v$logfile;
根據以上路徑,找到當前數據庫相應文件路徑。
一.移動數據文件:
可以用ALTER DATABASE,ALTER TABLESPACE兩種方法移動數據文件。
1. ALTER DATABASE方法;
-- 用此方法,可以移動任何表空間的數據文件。
STEP 1. 停數據庫:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2.用操作系統命令移動數據文件:
將數據文件 'test.dbf' 從/ora/oracle/data1目錄移動到/ora/oracle/data2目錄下:
mv /ora/oracle/data1/test.dbf /ora/oracle/data2
STEP 3. Mount數據庫,用ALTER DATABASE命令將數據文件改名:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE RENAME FILE '/ora/oracle/data1/test.dbf' TO '/ora/oracle/data2/test.dbf';
STEP 4. 打開數據庫:.
SQL> ALTER DATABASE OPEN;
SQL>SELECT NAME,STATUS FROM V$DATAFILE;
2. ALTER TABLESPACE方法:
用此方法,要求此數據文件既不屬于SYSTEM表空間,也不屬于含有ACTIVE回滾段或臨時段的表空間。覺得麻煩,省略不用了。
二. 移動控制文件:
控制文件 在 INIT.ORA文件中指定。移動控制文件相對比較簡單,下數據庫,
編輯INIT.ORA,移動控制文件,重啟動數據庫。
STEP 1. 停數據庫:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2.用操作系統命令 移動控制文件:
--將控制文件'ctl3orcl.ctl' 從/ora/oracle/data1目錄移動到/ora/oracle/data2目錄下:
mv /ora/oracle/data1/ctl3orcl.ctl /ora/oracle/data2
STEP 3. 編輯INIT.ORA文件:
INIT.ORA文件的在ORACLE_HOME/dbs目錄下,
修改參數 "control_files",其中指定移動后的控制文件:
control_files = (/ora/oracle/data1/ctrlorcl1.ctl,/ora/oracle/data1/ctrlorcl2.ctl,/ora/oracle/data2/ctrlorcl3.ctl)
STEP 4. 重啟動數據庫:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP;
SQL>SELECT name FROM V$CONTROLFILE;
SQL> EXIT;
三. 移動聯機日志文件:
STEP 1. 停數據庫:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2. 用操作系統命令移動聯機日志文件:
--將聯機日志文件'redolog1.log' 從/ora/oracle/data1目錄移動到/ora/oracle/data2目錄下:
mv /ora/oracle/data1/redolog1.log /ora/oracle/data2
STEP 3. Mount數據庫,用ALTER DATABASE 命令改聯機日志文件名:.
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP MOUNT ;
SQL> ALTER DATABASE RENAME FILE '/ora/oracle/data1/redolog1.log' TO '/ora/oracle/data2/redolog1.log';
STEP 4.重啟動數據庫: .
SQL> ALTER DATABASE OPEN;
SQL>SELECT MEMBER FROM V$LOGFILE;
最近接觸Jakarta-Common-BeanUtils這個東東比較 多,于是對Apache Jakarta
Project產生了興趣,上他們的官方網站上看了下感覺有用的東西好多,眼花繚亂的,又沒有中文網站,又上各大論壇搜了下,也沒有發現一個集中該項目的
資料,于是決定自己整理翻譯一下,有助于各位網友更好的了解該項目。如果有什么描述不對不全面的地方,希望各位提出來給大家分享。
Jakarta項目是ASF(The Apache Software
Foundation)的一部分。ASF是一個非贏利組織,她鼓勵基于開放的軟件許可下進行合作、注重實效的開發,并提供各個領域的高質量軟件,她涉及到
Http服務器,編譯工具,類庫,開發架構,服務器端Java技術,J2EE容器,數據庫工具,日志工具,XML解析等等諸多領域。ASF提供的java
項目有一部分在Jakarta中,還有一些成為獨立的諸如Tomcat的項目,Jakarta項目則提供了多種多樣開源的java解決通用方案。
先介紹一下ASF中和Jakarta項目并列的java項目:
Ant ——java構建工具,使用一個配置文件就可以完成java的項目的,編譯、打包、測試、運行、部署、生成文檔等諸多工作。
Avalon ——是一個包括核心框架、工具、組件和容器的面向組件編程(AOP)的完整開發平臺。使用關鍵設計模式,如反向控制模式(IoC)和分離考慮模(SoC)。 Avalon提供各種基本組件和缺省的應用程序模塊,幫助你快速的建立你自己的應用程序解決方案。
Excalibur ——集多個開源項目(Avalon Framework、LogKit和Cornerstone)于一身的輕量級可嵌入式反向控制容器。
Gump ——是Apache組織自己也使用的一個持續集成工具,全面支持Ant和Maven,當有新的改動提交到版本控制系統,它可以檢查出潛在的沖突,并及時通知項目組的所有成員并自動生成改動的詳細報告。
James ——是一套用java開發的郵件、新聞組、消息服務器,提供了比較完善的配置方案,尤其是關于郵件內容存儲和用戶信息存儲。 支持 SMTP, POP3 , NNTP , IMAP 。
Logging ——可靠,快速的日志工具。
Lucene
——Java開發的高性能,全方位的文本搜索引擎。替文件的每一個字作索引,索引讓搜尋的效率比傳統的逐字比較大大提高,
Lucen提供一組解讀,過濾,分析文件,編排和使用索引的API,它的強大之處除了高效和簡單外,是最重要的是使使用者可以隨時應自已需要自訂其功能。
Maven ——是一個潛在的基于java的apache ant的構建工具的替代者。提供了更強大的功能和易用性。
Portals
——提供了功能全面的、具有商業價值的企業門戶。門戶概念:門戶對企業內的各種資源如信息管理系統進行整合并通過單一接口對外提供服務,雇員、合伙人及顧
客可以通過任何裝置在任何地點通過門戶入口享受到企業提供的服務,分析家們預計,門戶將成為下一代的桌面環境。
Struts ——一個實現MVC model2的web應用程序開發框架。通過一個配置文件可以很好的對各種組件進行裝配,結構清晰,應用的最廣泛的額web開發框架。
Tapestry——類似 Struts,也是一個基于servlet的應用程序框架,支持MVC,出現的較晚,不如Struts普及,主要利用javabean和xml技術進行開發,
Tomcat ——Serlvet容器,同時具有傳統的Web服務器的功能,如:處理Html頁面。能夠處理動靜態網頁。
Watchdog ——用來檢查一個servlet或jsp容器在相應規范上的執行情況的兼容性。但是該項目已經靜止了,只支持Servlet2.3、JSP1.2,相應的Serlvet容器如Tomcat也只支持Tomcat4.x。
下面介紹下Jakarta的各個子項目:
Alexandria——已經不再開發
BCEL ——The Byte Code Engineering Library
(formerly known as JavaClass) 字節碼引擎類庫,它讓用戶方便的分析,創建,操作java的class文件成為可能。
它可以讓您深入 JVM 匯編語言進行類操作的細節。
BSF ——bean腳本框架 在java應用內對腳本語言提供了支持,通過腳本語言可以訪問java的對象和方法。
Cactus ——一個基于JUnit框架的簡單測試框架,用來單元測試服務端Java代碼。 Cactus單元測試服務端內容包括servlet,EJB, tag librarie, filter等
Commons ——提供很多日常開發中使用率很高的功能解決方案,已被很多著名的開源項目采用。具體的項目列表后面會有。
ECS ——使用Java語言和面向對象方法創建標記語言文檔(HTML,XML)的開源項目。
HiveMind ——是一個服務和配置的微型內核, 一套通過簡單的java對象和接口創建復雜應用的框架。
HttpComponents ——提供了java.net包所不能提供的更多強大的、方便的http協議處理功能。
JCS ——一個分布式的緩存系統,用來提高應用程序的性能,并且提供很多強大的額外功能。
JMeter
——純java開發的一套桌面應用程序。用來進行功能測試和性能測試。它可以用來測試靜止資料庫或者活動資料庫中的服務器的運行情況,可以用來模擬對服務
器或者網絡系統加以重負荷以測試它的抵抗,或者用來分析不同負荷類型下的所有運行情況。它也提供了一個可替換的界面用來定制數據顯示,測試同步及測試的創
建和執行。
ORO ——一套文本處理工具,能提供perl5.0兼容的正則表達式、 AWK-like正則表達式, glob 表達式。還提供替換,分割,文件名過慮等功能。
POI ——一套用來創建,讀寫基于OLE 2組件文檔格式的文件。使用Java來讀寫MS Excel ,Word文件。
Regexp ——一套純java的正則表達式相關的包。
Slide ——主要模塊是一個可以做為內容管理框架底層的內容倉庫.它可以把內容信息存取到專門的,異質的,分布式的數據庫中.Slide還增加了security, locking, versioning等特性.
Taglibs ——一套在開發web應用時十分有用的,jsp 通用 tag包。
Turbine ——類似 Struts,也是一個基于servlet的應用程序框架,支持MVC。提供了大量可重用的組件。此框架包中包含了大量組件,但是這些組件是離散的。
Velocity
——是一個基于java的模板引擎(template engine)。它允許任何人僅僅簡單的使用模板語言(template
language)來引用由java代碼定義的對象。
當Velocity應用于web開發時,界面設計人員可以和java程序開發人員同步開發一個遵循MVC架構的web站點,也就是說,頁面設計人員可以只
關注頁面的顯示效果,而由java程序開發人員關注業務邏輯編碼。 Velocity將
java代碼從web頁面中分離出來,這樣為web站點的長期維護提供了便利, 同時也為我們在JSP和PHP之外又提供了一種可選的方案。
Velocity的能力遠不止web站點開發這個領域,例如,它可以從模板(template)產生SQL和PostScript、XML,它也可以被當
作一個獨立工具來產生源代碼和報告,或者作為其他系統的集成組件使用。Velocity也可以為Turbine
web開發架構提供模板服務(template service)。
Velocity+Turbine提供一個模板服務的方式允許一個web應用以一個真正的MVC模型進行開發。
Apache java項目全介紹2
下面介紹一下Jakarta下的Commons:一個csdn網友描述得很貼切,Commons就好比一個java百寶箱。
commons分為3部分Commons Proper、Commons Sandbox和Commons Dormant。
Commons Proper:提供了設計良好可重用的java組件,并都經過了廣泛、嚴格的測試。
Commons Sandbox:處于實驗、測試階段的組件。
Commons Dormant:處于停滯狀態,從Sandbox退出的,不活躍的組件,謹慎使用。
Commons Proper組件:
Attributes—— 支持源代碼級的元數據。
BeanUtils——提供對 Java 反射和自省API的包裝,處理javabean的工具。
Betwixt——將JavaBeans與XML相互轉換。
Chain——對Chain of Responsibility(責任鏈)設計模式的實現。使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,并沿著這條鏈傳遞請求,直到有一個對象處理它為止。
CLI——處理命令行的命令的解析。
Codec——包含一些通用的編碼解碼算法。包括一些語音編碼器, Hex, Base64, 以及URL encoder。
Collections——擴展和增加標準的 Java Collection框架。
Configuration——操作各種格式的配置文件。Properties文件 /XML文件 /JNDI /JDBC 數據源 /System properties /Applet parameters / Servlet parameters
Daemon——創建類似unix守護線程的java代碼,可以安全地執行一些后臺操作,線程不被某個應用程序控制,而是由操作系統控制類似windows的service,可以設置一個服務依賴于另一個服務,一個服務關閉前必須先執行另一個服務。
DBCP——一個數據庫連接池
DbUtils——一個JDBC的工具類,比如可以將ResultSets生成javabean。
Digester——基于規則的XML文檔解析,主要用于XML到Java對象的映射.
Discovery——提供工具來定位資源 (包括類) ,通過使用各種模式來映射服務/引用名稱和資源名稱。
EL——JSP 2.0引入的表達式
Email——處理e-mail
FileUpload——web應用中的文件上傳組件
HttpClient——使用HTTP協議的客戶端開發框架
IO——幫助進行IO功能開發
Jelly
——Jelly能夠把XML轉換成可執行代碼,所以Jelly是一個基于XML與Java的腳本和處理引擎。
Jelly借鑒了JSP定指標簽,Velocity,
Cocoon和Xdoclet中的腳本引擎的許多優點。Jelly可以用在命令行,Ant或者Servlet之中。
Jexl——Jexl是一個表達式語言,通過借鑒來自于Velocity的經驗擴展了JSTL定義的表達式語言。
JXPath——使用XPath語法操作javabean的工具。
Lang——提供對java.lang包的擴展。
Launcher——跨平臺的java程序的啟動
Logging
——提供的是一個日志(Log)接口(interface),同時兼顧輕量級和不依賴于具體的日志實現工具。它提供給中間件/日志工具開發者一個簡單的日
志操作抽象,允許程序開發人員使用不同的具體日志實現工具。用戶被假定已熟悉某種日志實現工具的更高級別的細節。JCL提供的接口,對其它一些日志工具,
包括Log4J, Avalon LogKit, and JDK 1.4等,進行了簡單的包裝,此接口更接近于Log4J和LogKit的實現.
Math——Math 是一個輕量的,自包含的數學和統計組件,解決了許多非常通用但沒有及時出現在Java標準語言中的實踐問題.
Modeler—— 支持兼容JMX規范的MBeans開發。
Net——集合了網絡工具和協議工具的實現
Pool——Commons-Pool 提供了通用對象池接口,一個用于創建模塊化對象池的工具包,以及通常的對象池實現。
Primitives——對java原始類型的支持。
SCXML——處理SCXML
Transaction——事務處理,實現了多層次鎖、事務集合、事務文件的訪問。
Validator——提供了一個簡單的,可擴展的框架來在一個XML文件中定義校驗器 (校驗方法)和校驗規則。支持校驗規則的和錯誤消息的國際化。
VFS——訪問各種文件系統,可以是本地文件、HTTP服務器上的文件、zip中的文件。
Commons Sandbox組件:
Compress——處理壓縮文件如tar, zip 和 bzip2 格式。
CSV——處理CSV文件
Exec——安全地處理外部進程
Finder——實現類似UNIX find命令的功能
I18n——處理軟件的I18n功能
Id——生成id號功能
Javaflow——捕捉程序運行狀態
JCI——java編譯接口
OpenPGP——處理加密方法OpenPGP.
Pipeline——處理類似工作隊列的管道工具
Proxy——生成動態代理
Alias Type
Transaction manager aliases
JDBC com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig
JTA com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
EXTERNAL com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
Data types
string java.lang.String
byte java.lang.Byte
long java.lang.Long
short java.lang.Short
int java.lang.Integer
integer java.lang.Integer
double java.lang.Double
float java.lang.Float
boolean java.lang.Boolean
date java.util.Date
decimal java.math.BigDecimal
object java.lang.Object
map java.util.Map
hashmap java.util.HashMap
list java.util.List
arraylist java.util.ArrayList
collection java.util.Collection
iterator java.util.Iterator
Data source factory types
SIMPLE com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory
DBCP com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory
JNDI com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory
Cache controller types
FIFO com.ibatis.sqlmap.engine.cache.fifo.FifoCacheController
LRU com.ibatis.sqlmap.engine.cache.lru.LruCacheController
MEMORY com.ibatis.sqlmap.engine.cache.memory.MemoryCacheController
OSCACHE com.ibatis.sqlmap.engine.cache.oscache.OSCacheController
XML result types
Dom com.ibatis.sqlmap.engine.type.DomTypeMarker
domCollection com.ibatis.sqlmap.engine.type.DomCollectionTypeMarker
Xml com.ibatis.sqlmap.engine.type.XmlTypeMarker
XmlCollection com.ibatis.sqlmap.engine.type.XmlCollectionTypeMarker
事務處理是所有大型數據庫產品的一個關鍵問題,各數據庫廠商都在這個方面花費了很大精力,不同的事務處理方式會導致數據庫性能和功能上的巨大差異。
事務處理也是數據庫管理員與數據庫應用程序開發人員必須深刻理解的一個問題,對這個問題的疏忽可能會導致應用程序邏輯錯誤以及效率低下。
下
面我們針對Oracle及SQL
Server這兩種當前廣泛使用的大型數據庫產品,探討一下它們在事務處理方面的一些差異。如沒有特殊說明,本文內容適用的數據庫產品版本為
Oracle9i及SQL Server 2000,其中的示例SQL語句,對于Oracle是在SQL*Plus中執行,而對于SQL Server
2000是在osql中執行。
1. 事務的概念
事務可以看作是由對數據庫的若干操作組成的一個單元,這些操作要么都完成,要么都取消,從而保證數據滿足一致性的要求。事務的一個典型例子是銀行中的轉帳
操作,帳戶A把一定數量的款項轉到帳戶B上,這個操作包括兩個步驟,一個是從帳戶A上把存款減去一定數量,二是在帳戶B上把存款加上相同的數量。這兩個步
驟顯然要么都完成,要么都取消,否則銀行就會受損失。顯然,這個轉帳操作中的兩個步驟就構成一個事務.
數據庫中的事務還有如下ACID特征。
ACID分別是四個英文單詞的首寫字母,這四個英文單詞是Atomicity、Consistency、Isolation、Durability,分別翻譯為原子性、一致性、隔離性、持久性。
原子性:指事務中的操作,或者都完成,或者都取消。
一致性:指事務中的操作保證數據庫中的數據不會出現邏輯上不一致的情況,一致性一般會隱含的包括在其他屬性之中。
隔離性:指當前的事務與其他未完成的事務是隔離的。在不同的隔離級別下,事務的讀取操作,可以得到的結果是不同的。
持久性:指對事務發出COMMIT命令后,即使這時發生系統故障,事務的效果也被持久化了。與此相反的是,當在事務執行過程中,系統發生故障,則事務的操作都被回滾,即數據庫回到事務開始之前的狀態。
對數據庫中的數據修改都是在內存中完成的,這些修改的結果可能已經寫到硬盤也可能沒有寫到硬盤,如果在操作過程中,發生斷電或系統錯誤等故障,數據庫可以
保證未結束的事務對數據庫的數據修改結果即使已經寫入磁盤,在下次數據庫啟動后也會被全部撤銷;而對于結束的事務,即使其修改的結果還未寫入磁盤,在數據
庫下次啟動后會通過事務日志中的記錄進行“重做”,即把丟失的數據修改結果重新生成,并寫入磁盤,從而保證結束事務對數據修改的永久化。這樣也保證了事務
中的操作要么全部完成,要么全部撤銷。
2. 事務設置及類型的區別
在SQL Server中有三種事務類型,分別是:隱式事務、顯式事務、自動提交事務,缺省為自動提交。
自動提交,是指對于用戶發出的每條SQL語句,SQL Server都會自動開始一個事務,并且在執行后自動進行提交操作來完成這個事務,也可以說在這種事務模式下,一個SQL語句就是一個事務。
顯式事務,是指在自動提交模式下以Begin
Transaction開始一個事務,以Commit或Rollback結束一個事務,以Commit結束事務是把事務中的修改永久化,即使這時發生斷電
這樣的故障。例如下面是SQL Server中的一個顯式事務的例子。
Begin Tran
Update emp Set ename=’Smith’ Where empno=7369
Insert Into dept Values(60,’HR’,’GZh’)
Commit
<!--[if !vml]--><!--[endif]-->
隱式事務,是指在當前會話中用Set Implicit_Transactions On命令設置的事務類型,這時任何DML語句(Delete、Update、Insert)都會開始一個事務,而事務的結束也是用Commit或Rollback。
在Oracle中沒有SQL Server的這些事務類型,缺省情況下任何一個DML語句都會開始一個事務,直到用戶發出Commit或Rollback操作,這個事務才會結束,這與SQL Server的隱式事務模式相似。
3. 事務隔離級別
在SQL92標準中,事務隔離級別分為四種,分別為:Read Uncommitted、Read
Committed、Read Repeatable、Serializable,其中Read Uncommitted與Read
Committed為語句級別的,而Read Repeatable與Serializable是針對事務級別的。
在Oracle和SQL Server中設置事務隔離級別的語句是相同的,都使用SQL92標準語法,即:
Set Transaction Isolation Level Read Committed
上面示例中的Read Committed可以被替換為其他三種隔離級別中的任意一種。
1) SQL Server中的隔離級別及實現機制
在SQL Server中提供了所有這四種隔離級別。
下面我們討論在SQL Server中,這幾種隔離級別的含義及其實現方式。
Read Uncommitted:一個會話可以讀取其他事務未提交的更新結果,如果這個事務最后以回滾結束,這時的讀取結果就可能是錯誤的,所以多數的數據庫應用都不會使用這種隔離級別。
Read Committed:這是SQL
Server的缺省隔離級別,設置為這種隔離級別的事務只能讀取其他事務已經提交的更新結果,否則,發生等待,但是其他會話可以修改這個事務中被讀取的記
錄,而不必等待事務結束,顯然,在這種隔離級別下,一個事務中的兩個相同的讀取操作,其結果可能不同。
Read
Repeatable:在一個事務中,如果在兩次相同條件的讀取操作之間沒有添加記錄的操作,也沒有其他更新操作導致在這個查詢條件下記錄數增多,則兩次
讀取結果相同。換句話說,就是在一個事務中第一次讀取的記錄保證不會在這個事務期間發生改變。SQL
Server是通過在整個事務期間給讀取的記錄加鎖實現這種隔離級別的,這樣,在這個事務結束前,其他會話不能修改事務中讀取的記錄,而只能等待事務結
束,但是SQL Server不會阻礙其他會話向表中添加記錄,也不阻礙其他會話修改其他記錄。
Serializable:在一個事務中,讀取操作的結果是在這個事務開始之前其他事務就已經提交的記錄,SQL
Server通過在整個事務期間給表加鎖實現這種隔離級別。在這種隔離級別下,對這個表的所有DML操作都是不允許的,即要等待事務結束,這樣就保證了在
一個事務中的兩次讀取操作的結果肯定是相同的。
2) Oracle中的隔離級別及實現機制
在Oracle中,沒有Read Uncommitted及Repeatable
Read隔離級別,這樣在Oracle中不允許一個會話讀取其他事務未提交的數據修改結果,從而避免了由于事務回滾發生的讀取錯誤。Oracle中的
Read Committed和Serializable級別,其含義與SQL Server類似,但是實現方式卻大不一樣。
在Oracle中,存在所謂的回滾段(Oracle9i之前版本)或撤銷段(Oracle9i版本),Oracle在修改數據記錄時,會把這些記錄被修改
之前的結果存入回滾段或撤銷段中,就是因為這種機制,Oracle對于事務隔離級別的實現與SQL
Server截然不同。在Oracle中,讀取操作不會阻礙更新操作,更新操作也不會阻礙讀取操作,這樣在Oracle中的各種隔離級別下,讀取操作都不
會等待更新事務結束,更新操作也不會因為另一個事務中的讀取操作而發生等待,這也是Oracle事務處理的一個優勢所在。
Oracle缺省的設置是Read
Committed隔離級別(也稱為語句級別的隔離),在這種隔離級別下,如果一個事務正在對某個表進行DML操作,而這時另外一個會話對這個表的記錄進
行讀取操作,則Oracle會去讀取回滾段或撤銷段中存放的更新之前的記錄,而不會象SQL Server一樣等待更新事務的結束。
在Serializable隔離級別(也稱為事務級別的隔離),事務中的讀取操作只能讀取這個事務開始之前已經提交的數據結果。
如果在讀取時,其他事務正 在對記錄進行修改,則Oracle就會在回滾段或撤銷段中去尋找對應的原來未經更改的記錄(而且是在讀取操作所在的事務開始之前存放于回滾段或撤銷段的記 錄),這時讀取操作也不會因為相應記錄被更新而等待。
4. DDL語句對事務的影響
1) Oracle中DDL語句對事務的影響
在Oracle中,執行DDL語句(如Create Table、Create View等)時,會在執行之前自動發出一個Commit命令,并在隨后發出一個Commit或者Rollback命令,也就是說,DDL會象如下偽碼一樣執行:
Commit;
DDL_Statement;
If (Error) then
Rollback;
Else
Commit;
End if;
我們通過分析下面例子來看Oracle中,DDL語句對事務的影響:
<!--[if !vml]--><!--[endif]-->Insert into some_table values(‘Before’);
<!--[if !vml]--><!--[endif]-->Creaate table T(x int);
<!--[if !vml]--><!--[endif]-->Insert into some_table values(‘After’);
<!--[if !vml]--><!--[endif]-->Rollback;
由于在Oracle執行Create table語句之前進行了提交,而在Create
table執行后也會自動發出Commit命令,所以只有插入After的行被回滾,而插入Before的行不會被回滾,Create
table命令的結果也不會被回滾,即使Create
table語句失敗,所進行的Before插入也會被提交。如果最后發出Commit命令,因為插入Before及Create
table的操作結果已經在之前提交,所以Commit命令影響的只有插入After的操作。
2) SQL Server中DDL語句對事務的影響
在SQL Server中,DDL語句對事務的影響與其他DML語句相同,也就是說,在DML語句發出之前或之后,都不會自動發出Commit命令。
在SQL Server 2000中,對于與上面Oracle同樣的例子,最后發出Rollback后,數據庫會回滾到插入Before之前的狀態,即插入Before和After的行都會被回滾,數據表T也不會被創建。
如果最后發出Commit操作,則會把三個操作的結果全部提交。
5. 用戶斷開數據庫連接對事務的影響
另外,對應于Oracle的管理客戶端工具SQL*Plus,在SQL Server
2000中是osql,兩種管理工具都是命令行工具,使用方式及作用也類似,但是在SQL*Plus中,用戶退出連接時,會自動先發出Commit命令,
然后再退出,而在osql中,如果用戶退出連接,會自動發出Rollback命令,這對于SQL
Server的自動提交模式沒有什么影響,但如果處于隱式事務模式,其影響是顯而易見的。對于兩種數據庫產品的其他客戶端管理工具也有類似的不同之處。
SAX (Simple API for XML) 和 DOM (Document Object Model) 是當前兩個主要的XML API,幾乎所有商用的xml 解析器都同時實現了這兩個接口。因此如果你的程序使用了SAX或者DOM APIs,那么你的程序對xml解析器是透明。
1. DOM以一個分層的對象模型來映射xml文檔。而SAX將文檔中的元素轉化為對象來處理。
2. DOM將文檔載入到內存中處理,而SAX則相反,它可以檢測一個即將到來的 XML流,由此并不需要所有的XML代碼同時載入到內存中。
SAX 處理是如何工作的
SAX 在讀取 XML 流的同時處理它們,這很像以前的自動收報機紙帶(ticker tape)。請考慮下面的 XML 代碼片斷:
<?xml version="1.0"?>
<samples>
<server>UNIX</server>
<monitor>color</monitor>
</samples>
分析這個代碼片斷的 SAX 處理器一般情況下將產生以下事件:
Start document
Start element (samples)
Characters (white space)
Start element (server)
Characters (UNIX)
End element (server)
Characters (white space)
Start element (monitor)
Characters (color)
End element (monitor)
Characters (white space)
End element (samples)
SAX API 允許開發人員捕捉這些事件并對它們作出反應。
SAX 處理涉及以下步驟:
1.
創建一個事件處理程序。
2.創建 SAX 解析器。
3.向解析器分配事件處理程序。
4.解析文檔,同時向事件處理程序發送每個事件。
基于事件的處理的優點和缺點
這種處理的優點非常類似于流媒體的優點。分析能夠立即開始,而不是等待所有的數據被處理。而且,由于應用程序只是在讀取數據時檢查數據,
因此不需 要將數據存儲在內存中。這對于大型文檔來說是個巨大的優點。事實上,應用程序甚至不必解析整個文檔;它可以在某個條件得到滿足時
停止解析。一般來說,SAX 還比它的替代者 DOM 快許多。
另一方面,由于應用程序沒有以任何方式存儲數據,使用 SAX 來更改數據或在數據流中往后移是不可能的。
DOM 和基于樹的處理
DOM 是處理 XML 數據的傳統方法。使用 DOM 時,數據以樹狀結構的形式被加載到內存中。
例如,在“SAX 處理是如何工作的”中用作例子的相同文檔在 DOM 中將表示為節點,DOM 使用父子關系。
基于樹的處理的優點和缺點
DOM
以及廣義的基于樹的處理具有幾個優點。首先,由于樹在內存中是持久的,因此可以修改它以便應用程序能對數據和結構作出更改。
它還可以在任何時候在樹中上下導航,而不是像 SAX 那樣是一次性的處理。DOM 使用起來也要簡單得多。
另一方面,在內存中構造這樣的樹涉及大量的開銷。大型文件完全占用系統內存容量的情況并不鮮見。此外,創建一棵 DOM 樹可能是一個緩慢的過程。
如何在 SAX 和 DOM 之間選擇
選擇 DOM 還是選擇 SAX,這取決于下面幾個因素:
1.應用程序的目的:如果打算對數據作出更改并將它輸出為 XML,那么在大多數情況下,DOM 是適當的選擇。并不是說使用 SAX 就不能更改數據,
但是該過程要復雜得多,因為您必須對數據的一份拷貝而不是對數據本身作出更改。
2.數據容量: 對于大型文件,SAX 是更好的選擇。
數據將如何使用:如果只有數據中的少量部分會被使用,那么使用 SAX 來將該部分數據提取到應用程序中可能更好。 另一方面,
如果您知道自己以后會回頭引用已處理過的大量信息,那么 SAX 也許不是恰當的選擇。
3.對速度的需要: SAX 實現通常要比 DOM 實現更快。
SAX 和 DOM 不是相互排斥的,記住這點很重要。您可以使用 DOM 來創建 SAX 事件流,也可以使用 SAX 來創建 DOM 樹。事實上,用于創建 DOM 樹的大多數解析器實際上都使用 SAX 來完成這個任務!
1、增加攔截器
<interceptor-ref name="execAndWait">
<!--等待時間,執行時間沒有超過此值,將不顯示等待畫面(毫秒)-->
<param name="delay">1000</param>
<!-- 間隔檢查時間,檢查后臺進程有沒有執行完畢,如果完成了它就立刻返回-->
<param name="delaySleepInterval">50</param>
</interceptor-ref>
此攔截器必須放在所有攔截器的最后。
2、增加result
<result name="wait">wait.jsp</result>
如果沒有找到"wait"結果,struts2會自動生成一個wait結果(\org\apache\struts2\interceptor
\wait.ftl).這個結果是用FreeMarker做的,所以需要Freemarker支持才能正常工作。如果你不想在程序中加入
FreeMarker,那就必須自己實現一個wait結果。這一般來說是有必要的,因為默認的wait頁面很簡單。
3、Action實現SessionAware接口
因為這個action將會以單獨的線程執行,所以你不能用ActionContext,因為它是ThreadLocal.這也就是說如果你要訪問
session數據,你必須實現 SessionAware結構而不是調用ActionContext.getSesion() 。
public interface SessionAware{
public void setSession(Map map);
}
public abstract class AbsBasicAction extends ActionSupport implements SessionAware{
/** 當前 Session */
protected Map session ;
public void setSession(Map session) {
this.session = session ;
}
}
4、實現 wait 結果 映射的 wait.jsp
必須設置該頁面的meta信息,每隔5秒,重新請求一次前面的action。
<meta http-equiv="refresh" content="2;url=<s:url includeParams="all" />" />