2011年5月4日 星期三

[轉載] FreeMarker IDE

環境說明

作業環境:Windows XP SP3
軟體版本:
  • Eclipse v3.4.2
說明:FreeMarker 是一套 Java 的樣板引擎,然而 Eclipse 沒有支援 FreeMarker 所以要透過外掛,安裝FreeMarker IDE 可以將 FreeMarker 的語法加上色彩標記,這樣撰寫 FreeMarker 可以比較清楚。
Update Site: http://download.jboss.org/jbosstools/updates/stable
官方網站http://freemarker.sourceforge.net/
版本更新

安裝步驟

  1. 請參考 Subclipse 這篇文章使用 Eclipse 內建的「Software Updates...」來安裝來安裝
  2. 因為 FreeMarker IDE 是由 JBoss 所維護的,所以有許多的 JBoss 的外掛,基本上只要勾選「FreeMarkerIDE Feature」並按下「Install...」即可
    fmide-001.png
  3. 安裝完後,附檔名為「ftl」的 FreeMarker 樣板檔就會改變圖示。
    fmide-002.png
  4. 開啟編輯就會有色彩標示了。
    fmide-003.png

2011年3月18日 星期五

[轉載] 詳細解讀Tomcat 7的七大新特性

Tomcat的7引入了許多新功能,並對現有功能進行了增強。很多文章列出了Tomcat 7的新功能,但大多數並沒有詳細解釋它們,或指出它們的不足,或提供代碼示例。本文將明確描述TOMCAT 7中七個最顯著的特徵和新增的功能,並對其作出評論,而不是僅僅列出新的功能。本文還提供了代碼例子以方便你可以對其有更好的理解。

本文分為兩個部分,分別是「TOMCAT 7的新特性」和「TOMCAT 7」增強的功能。

TOMCAT 7新特性

1 使用隨機數去防止跨站腳本攻擊。
2 改變了安全認證中的jessionid的機制,防止session攻擊。
3 內存洩露的偵測和防止
4 在war文件外使用別名去存儲靜態內容。

TOMCAT 7的增強功能

5 對Servlet 3.0,JSP 2.2和JSP-EL 2。2的支持
6 更容易將Tomcat內嵌到應用去中去,比如JBoss
7 異步日誌記錄
根據Mark Thomas,Tomcat 7委員會的經理的說法,Tomcat 7最顯著的三個特徵是Servlet 3.0,內存檢測洩露和增強的安全特性。
Tomcat 7的例子程序中,包含了Eclipse的工程文件和Ant的構建文件,以方便去構建war文件。其中Eclipse工程文件有例子代碼描述了Tomcat 7的一些新特性。
下面逐一開始介紹。

TOMCAT 7新特性

1使用隨機數去防止跨站請求偽造攻擊。

Wikipedia將跨站請求偽造攻擊(Cross Site Request forgery,CSRF)定義為:「一種影響Web應用的惡意攻擊。CSRF讓用戶當進入一個可信任的網頁時,被強行執行惡意代碼。
經典的防止CSRF攻擊的方法是使用隨機數的方式,Wikipedia中定義為「利用隨機或偽隨機數嵌入到認證協議中,以確保舊的不能在以後的重放攻擊中被利用。」

Tomcat 7中有一個servlet過濾器,用於將隨機數存儲在用戶每次請求處理後的seesion會話中。這個隨機數,必須作為每次請求中的一個參數。 Servlet過濾器然後檢查在請求中的這個隨機數是否與存儲在用戶session中的隨機數是一樣的。如果它們是相同的,該請求是判斷來自指定的網站。 如果它們是不同的,該請求被認為是從其他網站發出並且會被拒絕。
這個servlet過濾器是十分簡單的,下面是從TOMCAT 源代碼CsrfPreventionFilter文檔中摘錄的片段:

public class CsrfPreventionFilter extends FilterBase {

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {

String previousNonce = req.getParameter(Constants.CSRF_NONCE_REQUEST_PARAM);
String expectedNonce = (String) req.getSession(true).getAttribute(Constants.CSRF_NONCE_SESSION_ATTR_NAME);

if (expectedNonce != null && !expectedNonce.equals(previousNonce)) {
res.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}

String newNonce = generateNonce();
req.getSession(
true).setAttribute(Constants.CSRF_NONCE_SESSION_ATTR_NAME, newNonce);

所以每個URL地址中都有一個從用戶session中提取的隨機數,下面是使用的JSTL例子:
在以前,JSTL中構造鏈接可以這樣:


< c:url var="url" value="/show" >
< c:param name="id" value="0" / >
< /c:url >
< a href="${show}" >Show< /a >

而現在可以這樣:


< c:url var="url" value="/show" >
< c:param name="id" value="0" / >
< c:param name="org.apache.catalina.filters.CSRF_NONCE" value="${session.org.apache.catalina.filters.CSRF_NONCE}" / >
< /c:url >

具體的例子可以參考TOMCAT 7自帶例子中的演示,這個過濾器可以在web.xml中進行配置,配置後,所有訪問如http://localhost:8080/tomcat7demo/csrf/的都必須帶上參數,不帶上參數的話會出現403禁止訪問錯誤。
當然這種方法的缺點就是所有的鏈接都必須帶上這個隨機數。

2 改變了安全認證中的jessionid的機制,防止session攻擊。

Session劫持攻擊通常是以下的情況:
1 惡意攻擊者先訪問一個網頁,由於cookie是以jsession id的方式存儲在瀏覽器中的,即使攻擊者不登陸,他可以偽造一個帶有jsession id的地址,把它發給受害者,比如
http://example.com/login?JESSIONID=qwerty)

2 受害者點這個帶有jsessionid的鏈接,提示輸入驗證信息之後就登陸系統。

3 攻擊者現在使用這個帶jsessionid的鏈接,以受害者的身份登陸進系統了。
對於攻擊者來說,將jsessionid加在url中以及通過一個惡意表單發送出去是很容易的事,對於session劫持攻擊的更詳細描述,請 參考Acros Security組織的白皮書「Session Fixation Vulnerability in Web-based Applications」。

TOMCAT 7對此的解決方案是一個補丁,它在驗證後改變了jsessionid。這個補丁主要是應用在TOMCAT 7中,當然在TOMCAT 5和6中也可以使用但只是有些不同。
根據Mark Thomas說的,應用了Tomcat 7的這個補丁後:
• TOMCAT默認情況下安全性不再變得脆弱,因為驗證後會話發生了變化
• 如果用戶改變了默認設置(比如應用程序不能處理變化了的session id),風險也會降到最小,因為在Servlet 3中,可以禁止在url中進行會話跟蹤。
而在TOMCAT 5和TOMCAT 6中,應用了補丁後:
• 能阻止session劫持攻擊,因為能讓TOMCAT在驗證後改變session id。
• 如果應用程序不能處理變化了的session id,可以通過寫自定義的過濾器去檢查request.isRequestedSessionIdFromURL()和其返回的結果,以降低風險。
以上這些改變都是TOMCAT在幕後所做的,開發者根本不用去理會。

3 內存洩露的偵測和防止

開發者在部署他們寫的程序到生產環境上時,經常會遇到Pemgen錯誤:OutOfMemoryError。這是由於內存洩露而引起的。通常開發者是通過增大permgen內存的大小去解決或者就是重新啟動tomcat。

TOMCAT 7包含了一個新的特性,它通過把不能垃圾回收的引用對象移走的方法,能解決一些Permgen內存洩露的問題。這個特性對程序員部署應用程序在他們的開發 環境中是十分方便的,因為程序員在開發環境中為了節省時間一般不重新啟動Tomcat就能部署新的war文件。在生產環境中,最好的建議還是停掉 TOMCAT,然後清除work下面的目錄文件並且重新部署應用。

當然,內存洩露檢測和防止這個特性現在還不是很完善,還是有的情況TOMCAT不能檢測內存洩露和修復之的,所以對於生產環境,最好的的辦法還是停掉TOMCAT,然後清除work下面的目錄文件並且重新部署應用。

Mark Thomas解析應用程序或者庫程序在如下情況下會觸發內存洩露:
• JDBC驅動的註冊
• 一些日誌框架
• 在ThreadLocals中保存了對象但沒有刪除它們
• 啟動了線程但沒停止
而 Java API 存在內存洩漏的地方包括:
1.使用 javax.imageio API ( Google Web Toolkit會用到)
2.使用 java.beans.Introspector.flushCaches()
3.使用 XML 解析器
4.使用 RMI 遠程方法調用
5.從 Jar 文件中讀取資源

4 在war文件外使用別名去存儲靜態內容

Web應用程序需要靜態資源文件,比如象CSS,Javascript和視頻文件、圖片文件等。通常都把它們打包放在war文件中,這將增加了 WAR文件的大小並且導致很多重複的加載靜態資源。一個比較好的解決方法是使用Apache HTTP服務器去管理這些靜態文件資源,下面是一個apache httpd.conf文件的配置摘錄:

< Directory "/home/avneet/temp/static" >
Order allow,deny
Allow from all
< /Directory >
Alias
/static "/home/avneet/temp/static"

以上的設置,使得訪問http://localhost/static時,能訪問到放在/home/avneet/temp/static下的資源。

允許使用新的aliases屬性,指出靜態文件資源的位置,可以通過使用 Classloader.getResourceAsStream('/static/...')或者在鏈接中嵌入的方法讓TOMCAT去解析絕對路徑, 下面是一個在context.xml中配置的例子:


< ?xml version="1.0" encoding="UTF-8"? >
< Context path="/tomcat7demo" aliases="/static=/home/avneet/temp/static" >
< /Context >

假設/home/avneet/temp/static這個文件夾存放有一張圖片bg.png,如果war文件以tomcat7demo的名字部署,那麼可以通過以下三個方式去訪問這張圖片
1 直接訪問
http://localhost:8080/tomcat7demo/static/bg.png
2 在HTML鏈接中訪問:< img src="/tomcat7demo/static/bg.png" / >
3 通過JAVA代碼訪問: ByteArrayInputStream bais = (ByteArrayInputStream)getServletContext().getResourceAsStream("/static/bg.png");
使用aliases的好處是可以代替Apache的httpd.conf的設置,並且可以在servlet容器範圍內訪問,並且不需要Apache。

TOMCAT 7的增強特性

5對Servlet 3.0,JSP 2.2和JSP-EL 2。2的支持

Servlet 3的增強特性有:
• 可以在POJO或者過濾器filters中使用annotations註釋(在web.xml中不再需要再進行設置了)
• 可以將web.xml分塊進行管理了。也就是說,用戶可以編寫多個xml文件,而最終在web.xml中組裝它們,這將大大降低web.xml的複雜性增 強可讀性。比如, struts.jar和spring-mvc.jar每一個都可以有一個web-fragment.xml。開發者不再需要在web.xml中去配置它們 了,在web-fragment.xml中的jar文件會自動加載,並且struts/spring-mvc servlets和filters也會自動裝配設置。
• 異步處理web的請求----這個特性在tomcat 6 中已經有了,現在在tomcat 7中以Servlet 3標準規範化了,能讓使用異步I/O的web應用程序可以移植到不同的web容器中。異步處理使用非阻塞I/O,每次的HTTP連接都不需要對應一個線 程。更少的線程可以為更多的連接提供服務。這對於需要長時間計算處理才能返回結果的情景來說是很有用的,比如產生報表,Web Servce調用等。
• 安全的增強---Servlet 3.0現在使用SSL 去加強了會話session的跟蹤,代替了原來的cookie和URL重寫。

6 更容易將Tomcat內嵌到應用去中去

Tomcat 7現在可以嵌入到應用程序中去,並可以通過程序去動態設置和啟動。像在CATALINA_HOME/conf/server.xml中的很多配置,現在都 可以用程序動態去設置了。在Tomcat 7前,Tomcat 6提供了一個嵌入類,它能方便地去配置Tomcat。但在TOMCAT 7中,這個類已被廢棄了。這個新的Tomcat 7的類,使用了幾個默認的配置元素,並提供了一個更容易和簡單的方法去嵌入Tomcat。

下面是CATALINA_HOME/conf/server.xml中的一些相關屬性和配置:

< Server >
< Service >
< Connector port="8080 >
< Engine >
< Host appBase="/home/avneet/work/tomcat7demo/dist" / >
< /Engine >
< /Connector >
< /Service >
< /Server >

我們可以通過程序去進行動態設置了:


final String CATALINA_HOME = "/home/avneet/work/temp/tomcat7demo/";
Tomcat tomcat
= new Tomcat();
tomcat.setBaseDir( CATALINA_HOME );
tomcat.setPort(
8080 );
tomcat.addWebapp(
"/tomcat7demo", CATALINA_HOME + "/webapps/tomcat7demo.war");
tomcat.start();
System.out.println(
"Started tomcat");
tomcat.getServer().await();
//Keeps Tomcat running until it is shut down
//Webapp tomcat7demo accessible at http://localhost:8080/tomcat7demo/

7 異步日誌記錄

TOMCAT 7現在包括了一個異步日誌記錄器(AsyncFileHandler)。AsyncFileHandler繼承了FileHandler類並能代替 FileHandler。使用AsyncFileHandler,時,只需要在CATALINA_HOME/conf /logging.properties中把FileHandler全部替換為AsyncFileHandler就可以了。要注意的是異步日誌不能跟 log4一起工作。

當有日誌發向AsyncFileHandler時,日誌被加入到隊列中 (java.util.concurrent.LinkedBlockingDeque)並且方法調用的信息會馬上返回不需要等待I/O寫到磁盤中。當類 加載器加載AsyncFileHandler時,會有一個單獨的線程啟動,這個線程會從隊列中讀取日誌信息並且寫到磁盤中去

這種方法的好處是如果I/O速度很慢(比如日誌要保存在遠端的設備上)時,記錄日誌的請求和處理過程不會顯得很慢。

AsyncFileHandler使用生產者和消費者的關係原理,在隊列中存儲日誌信息。隊列默認大小為10000。為了預防隊列溢出,默認是丟棄最後的信息。默認的隊列大小和溢出的設置都可以通過啟動參數進行設置。

關於TOMCAT 7的示例程序

TOMCAT 7的自帶程序例子有兩個servlets,一個是演示了如何採用隨機數的辦法防止CSRF攻擊,另外一個是描述了使用aliases。更新一下web/META-INF/context.xml,指出圖片的絕對路徑即可順利運行。

通過ant運行build.xml去將它們部署到tomcat 7中,使用如下兩個地址訪問:
• http://localhost:8080/tomcat7demo/csrf/
• http://localhost:8080/tomcat7demo/alias/

2010年12月11日 星期六

[轉載] [FCKeditor] 用 Java Taglib 使用 FCKeditor

FCKeditor 是所見即所得(WYSIWYG)的線上編輯器, 支援多國語言, 多種瀏覽器支援, 可更換SKIN,還可以用JavaScript控制按鈕,功能十分多樣化,外掛的功能也是十分強大,支援瀏覽器管理檔案...等多樣化外掛。

支援語言: ASP.Net, ASP, ColdFusion, PHP, Java, Active-FoxPro, Lasso, Perl, Python
支援流覽器: IE, FireFox, Safari, Opera, Google Chrome, Camino
支援平台: MS Windows , MAC , Linux
版權: under the GPL, LGPL and MPL open source licenses

在 Java 的平台上有一個很好用的工具 Taglib , 可以讓你的 jsp 程式簡單化.配置如下

FCKeditor: FCKeditor_2.6.4.zip
FCKeditor.Java: fckeditor-java-2.4.1-bin.zip
FCKeditor.Java 文件參考: http://java.fckeditor.net/
SLF4j: slf4j-1.5.6.zip
Application Server: Tomcat 6.x.x

step01:
在 WebContent 目錄下建立一個目錄 fckeditor , 並將 FCKeditor_2.6.4.zip 解開的資料放在這個目錄下.

step02:
解 開 fckeditor-java-2.4.1-bin.zip , 將 fckeditor-java-core-2.4.1.jar, 及 lib 目錄下的三個檔案 commons-fileupload-1.2.1.jar, commons-io-1.3.2.jar, slf4j-api-1.5.2.jar , 複製到 WEB-INF\lib

step03:
解開 slf4j-1.5.6.zip , 將slf4j-api-1.5.6.jar, slf4j-simple-1.5.6.jar 複製到 WEB-INF\lib

step04:
在 WEB-INF\web.xml 檔增加下列程式碼
<servlet>
 <servlet-name>Connector</servlet-name>
 <servlet-class>net.fckeditor.connector.ConnectorServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Connector</servlet-name>
  <url-pattern> /fckeditor/editor/filemanager/connectors/*
  </url-pattern>
</servlet-mapping>


step05:
在 WEB-INF 目錄下增加一個檔案 FCKeditor.tld , 內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
 version="2.0">
 <description>
  The FCKeditor Tag Library offers a very convenient way to create
  several FCKeditor instances with different configurations.
  Additionally, you can check for user-based capabilities.
 </description>
 <display-name>FCKeditor Tag Library</display-name>
 <tlib-version>2.4</tlib-version>
 <short-name>FCK</short-name>
 <uri>http://java.fckeditor.net</uri>
 <tag>
  <description>
   Creates a FCKeditor instance with the given parameters. Any
   parameter except instanceName which is empty or contains
   whitespaces only will be ignored.
  </description>
  <display-name>editor</display-name>
  <name>editor</name>
  <tag-class>net.fckeditor.tags.EditorTag</tag-class>
  <body-content>JSP</body-content>
  <attribute>
   <description>
    The unique instance name under which the editor can be
    retrieved through the API.
   </description>
   <name>instanceName</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
  <attribute>
   <description>
    Width of the FCKeditor instance in the browser window.
   </description>
   <name>width</name>
   <rtexprvalue>true</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
  <attribute>
   <description>
    Height of the FCKeditor instance in the browser window.
   </description>
   <name>height</name>
   <rtexprvalue>true</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
  <attribute>
   <description>
    The toolbar set which shall be displayed to the user.
   </description>
   <name>toolbarSet</name>
   <rtexprvalue>true</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
  <attribute>
   <description>
    The path/folder in which the editor is deployed under
    the given context. The context path will be attached
    automatically. (e.g. '/fckeditor')
   </description>
   <name>basePath</name>
   <rtexprvalue>true</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
  <attribute>
   <description>
    Passes any content to the FCKeditor document. Use the
    jsp:attribute tag for large inline content. \r, \n, and
    \t will be truncated.
   </description>
   <name>value</name>
   <rtexprvalue>true</rtexprvalue>
   <type>java.lang.String</type>
  </attribute>
  <example><![CDATA[
<FCK:editor instanceName="editorDefault" height="500px" />]]>
  </example>
 </tag>
 <tag>
  <description>
   Sets a config property of the editor to the supplied value.
   You may provide any attribute you want for the editor. Set
   at least one attribute per tag or several attributes with
   one tag. This tag can only be nested within an editor tag.
   For all configuration options click
   <![CDATA[<a href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options">here</a>]]>.
  </description>
  <display-name>config</display-name>
  <name>config</name>
  <tag-class>net.fckeditor.tags.ConfigTag</tag-class>
  <body-content>empty</body-content>
  <dynamic-attributes>true</dynamic-attributes>
  <example>
   <![CDATA[
<FCK:config SkinPath="/skins/silver/" AutoDetectLanguage="true" />]]>
  </example>
 </tag>
 <tag>
  <description>
   Displays session-dependent and compatibility-related
   information. This tag is intended for developers only.
   Response messages cannot be localized, they are English
   only.
  </description>
  <display-name>check</display-name>
  <name>check</name>
  <tag-class>net.fckeditor.tags.CheckTag</tag-class>
  <body-content>empty</body-content>
  <attribute>
   <description>
    Provide the feature name you want to check. Valid
    features are [FileUpload, FileBrowsing,
    CompatibleBrowser]
   </description>
   <name>command</name>
   <required>true</required>
   <type>java.lang.String</type>
  </attribute>
  <example><![CDATA[
<FCK:check command="FileUpload" />
<FCK:check command="CompatibleBrowser" />]]>
  </example>
 </tag>
</taglib>


step06:
建立一個 fck.jsp 來測試, 程式碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/FCKeditor.tld" prefix="FCK"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="show.jsp" method="post" target="_blank">
<FCK:editor instanceName="fckEdit"  width="700" height="500"  toolbarSet="Default" />
<input type="submit" value="Submit">
</form>


</body>
</html>


fckeditor-java-2.4.1 的設定比較簡便, 就連上載檔案, 也只要在step04: 設定好 servlet : Connector 就可以了. 不需要太繁瑣. 不過若要上載檔案, 不要忘了要在 classpath 建立一個檔案 fckeditor.properties , 內容如下:
fckeditor.toolbarSet=Basic
connector.userActionImpl=net.fckeditor.requestcycle.impl.UserActionImpl
connector.userFilesPath=/userfiles
connector.resourceType.file.extensions.allowed=txt|doc
connector.resourceType.image.extensions.allowed=jpg|png


這樣才不會有問題. 參數說明:
connector.userFilesPath : 是伺服器上要存放檔案的地方.如 /userfiles
connector.resourceType.file.extensions.allowed : 可以限制上傳到/userfiles/file 目錄的附加檔名有那些
connector.resourceType.image.extensions.allowed: 可以限制上傳到/userfiles/image 目錄的附加檔名有那些

因為上載的檔案只能存在這個 application WEBcontent 的目錄內, 所以若將 java 打包成 war 檔在 JBoss 上使用, 則會有問題.

2010年12月10日 星期五

非英數名稱圖片顯示處理方案

這幾天在利用之前寫得上傳套件上傳圖片時遇到了問題(感謝專案組員抓到這個bug)
那就是上傳的圖片若以中文、日文等非英文、數字的名稱上傳遇到麻煩
在WebApplication會顯示找不到檔案的錯誤訊息

我先試著將上傳圖片名稱改成URL上的UTF-8編碼
String fileName = java.net.URLEncoder.encode( file.getName(), "UTF-8");
file.renameTo (new File(file.getParent(),   fileName));

雖然檔名的確與URL上經過編碼的檔案名稱相符,不過還是一樣找不到檔案... = =

既然上傳有問題,那剩下的方法就是禁止上傳檔名有編碼問題的檔案囉
最後做法是用正規表示法協助,讀取上傳檔案的檔名加以判斷
有問題的檔案就直接刪除了,並回覆訊息請求上傳有正確檔名的檔案
// 判斷是否含有非英數編碼的字元
String stringEncodeJudge = "^.*[^0-9a-zA-Z~!@#\\$%\\^&\\*\\(\\)_\\+\\{\\}\\|:\\\"<>\\?\\[\\];',\\.\\/].*$";

    if(!filePart.getFileName().matches(stringEncodeJudge)){
         session.setAttribute(name, saveDirectory + "/" + filePart.getFileName());
         tempMessage = fileName + "上傳成功!!<br />";
         Message += tempMessage;
    }else{
         tempMessage = fileName + "請改成英文、數字組成的檔名!!<br />";
         Message += (tempMessage);
         File disposedFile = new File(saveDirectory + "/" + filePart.getFileName());
         disposedFile.delete();
   }

2010年12月8日 星期三

範例 - 刪除目錄及其底下所有文件

      public void deleteAll(File path){
          if(path.exists()){
              if(path.isFile()){ 
                  path.delete(); 
              }else{ 
                  File[] files = path.listFiles();     
                  for(int i = 0; i < files.length; i++){ 
                        deleteAll(files[i]); 
                  }
 
                  path.delete(); 
              }
          }
      }

範例 - 計算硬碟中的資料大小

int uAppendSize = 0;                                     //store uploaded data size info
                                     
File[] fList =TargetDir.listFiles();

for (int j = 0; j < fList.length; j++){
      FileInputStream in = new FileInputStream(fList[j]);
      uAppendSize += in.available();
      in.close();         //must close FileInputStream after use it
}

這個範例會檢查寫入檔案所在的資料夾,並加該資料夾內的所有檔案大小相加
FileInputStream 開啟後務必要記得關閉
否則檔案的刪除、修改等動作會因為檔案被FileInputStream佔用而失敗

2010年12月7日 星期二

[轉載] 使用response.sendRedirect的注意事項

首先我們要明白用response.sendRedirect做轉向的原理
它其實是向瀏覽器發送一個特殊的Header,然後由瀏覽器來做轉向,轉到指定的頁面
所以用sendRedirect時,瀏覽器的地址欄上可以看到地址的變化
用<jsp:forward page=""/>則不同,它是直接在server做的
瀏覽器並不知道,也不和瀏覽器打交道,這從瀏覽器的地址並不變化可以看出。
所以使用response.sendRedirect時就需要注意以下兩點:

1,在使用response.sendRedirect時,前面不能有HTML輸出
這並不是絕對的,不能有HTML輸出其實是指不能有HTML被送到了瀏覽器
事實上現在的server都有cache機制,一般在8K(我是說JSP SERVER)
這就意味著,除非你關閉了cache,或者你使用了out.flush()強制刷新
那麼在使用sendRedirect之前,有少量的 HTML輸出也是允許的
如果報錯說,「一些信息已經被submitted」(原文忘了)
那麼,你就要注意看了,前面是不是有過多的HTML輸出了

2,在response.sendRedirect之後,應該緊跟一句return;
我們已經知道response.sendRedirect是通過瀏覽器來做轉向的
所以只有在頁面處理完成後,才會有實際的動作
既然你已經要做轉向了,那麼後的輸出還有什麼意義呢?
而且有可能會因為後面的輸出導致轉向失敗