2008年12月30日 星期二

Servlet3.0 Briefing

Servlet3.0規範新鮮出爐,J2EE陣營實力大增

[IT168專稿]在2005年9月26日,Sun推出了Servlet的最新版API:Servlet2.5。這套Servlet API和以前的Servlet有著很大的不同。最大的區別就是Servlet2.5是完全基於J2SE5.0的。因此,它也理所當然地擁有了 J2SE5.0的所有特性。 Servlet2.5利用J2SE5.0的註釋特性使它的配置更容易。然而,由於在2005年J2SE5.0剛推出不久,支持J2SE5.0的Web服務 器也不多,因此,當時Servlet2.5在使用上並沒有馬上普及。時隔兩年後,Sun又推出了基於J2SE5.0的Servlet的第二個版本 3.0(就是JSR-315)。在這一版本中增加了很多有趣的特性。如可編程的登入登出,通過annotations進行配置,異步通訊等。

下面就讓我們 來看看Servet3.0的主要特性。

一、更靈活的Web框架

現在幾乎所有的基於Java的Web框架都是建立在Servlet之上的。大多數Web構架都是通過Servlets或web.xml來 配置和發布的。而J2SE新加入的註釋功能為我們提供了更好的選擇。我們可以利用註釋來設置Servlets、Listeners、filters等。但 註釋是直接寫在程序中的,無法動態改變配置,因此,JSR同時提供了這兩種方式來操作Servlet。這樣將使Web應用程序具有更大的彈性。

二、EOD的支持

Servlet3.0將使用多種技術來增強API的能力。如使用註釋來聲明編程類型。這將成為EOD的目標之一:使Web程序零配置。也就是說我們將使用 發布描述來覆蓋傳統的配置文章。還有就是泛型的應用,將大大加強程序的Servlet的表現力。在未來的J2SE版本中將加入支持其他語言的能力,這也有 助於增強Servlet API本身的實力。

三、異步通訊的支持

Servlet3.0支持以下異步通訊特性:

1.非阻塞(Non-blocking)輸入:使用這種輸入方式,可以在數據因某種原因暫時未到達時程序不會因此而被阻塞。
2.非阻塞輸出:和非阻塞輸入類似,當由於網絡問題寫入數據緩慢時程序不會受到阻塞。
3.延遲請求處理:在AJAX Web程序中客戶端程序可以向服務端發出異步請求,直到超時或事件返回來處理這個請求。延遲請求在其他的地方也是非常有用的,如我們在處理數據之前必須要 得到一些資源,但這些資源正處在遠程網絡中,而且速度並不快。這就需要異步來處理這種情況。
4.阻塞-非阻塞通知:這個功能是將通知信息放到阻塞或非阻塞事件中。然後由客戶端負責提取。
5.支持通道:通道是JDK1.4及以上版本提供的一種新的通訊API。使用Channel可以更好的進行網絡之間的通訊。也可以增強創建、訂閱、取消等操作的安全性。
6.安全:支持登錄和註銷功能。
7.其他功能
(1)支持歡迎界面。
(2) ServletContentListener排序。
(3)在初始化時可以定制容器的大小。
(4)可以監視文件上傳的進程。

上面只是Servlet3.0的一部分特性。從這些特性可以看出,Servlet3.0 API確實得到了很大的飛越,除了Servlet,EJB3.0也利用J2SE5.0的新特性重獲新生。也許在不久的將來Servlet3.0和 EJB3.0將會成為新的組合,在J2EE應用中起著舉足輕重的作用,就讓我們拭目以待吧!

Source: http://tech.it168.com

2008年12月20日 星期六

為什麼Linux比Windows更不會中毒?

(轉載)本篇文章來源於 IB資訊網

可能不少人持這樣一種觀點,認 為 Linux 病毒少是因為Linux不像Windows那麼普及,其實這種觀點很早已經被人批駁過了,一個最有力的論據是:如果寫病毒的人寫 Windows 病毒是因為 Windows 用戶多而因此破壞性大,那麼 Internet 上大多數服務器都是基於 Unix/Linux 的,攻擊這些服務器,破壞性豈不是更大麼?

對一個二進制的 Linux 病毒,要感染可執行文件,這些可執行文件對啟動這個病毒的用戶一定要是可寫的。而實際情況通常並不是這樣的。實際情況通常是,程序被 root 擁有,用戶通過無特權的帳號運行。而且,越是沒有經驗的用戶,他擁有可執行文件的可能性就越小。因此,越是不瞭解這種危險的用戶的主目錄越不適合病毒繁殖。

即使這個病毒成功地感染了這個用戶擁有的一個程序,由於這個用戶權限受限,它進一步傳播的任務也會非常困難(當然,對於運行單用戶系統的 Linux 新手,這個論證可能不適用。這樣的用戶可能會對 root 帳戶比較粗心)。

Linux 網絡程序構建地很保守,沒有使現在 Windows 病毒如此快速傳播變的可能的高級宏工具。這並不是 Linux 的固有特徵;它僅僅是兩種用戶基礎的不同和這種不同導致的在這兩種市場中的成功產品的不同的反映。通過觀察這些問題學到的經驗也會被用到將來的 Linux 產品中。

Linux的應用軟件和系統軟件幾乎都是開源的。這對病毒有兩方面的影響。首先,病毒很難藏身於開源的代碼中間。其次,對僅有二進制的病毒,一次新的編譯安裝就截斷了病毒一個主要的傳播途徑。雖然 Linux 發行商也提供大量的二進制軟件包,但是用戶大都是從發行商提供的可靠的軟件倉庫中下載這些軟件包,大都具有 md5 驗證機制,安全性極高。

這些障礙每一個都是病毒成功傳播的一個重要阻礙。然而當把他們放在一起考慮的時候,基本的問題才浮現出來。

一個計算機病毒,像生物病毒一樣,要想傳播開來,其繁殖速度必須超過其死亡(被消 滅)的速度。上面提到的障礙有效地降低了 Linux 病毒的繁殖速度。如果它的繁殖速度降到取代原來種群所需要的閾值之下,那麼這個病毒的厄運從一開始就注定了--甚至在潛在受害人意識到它們之前。

我們沒有看到一個真正的 Linux 病毒瘋狂傳播,原因就在於存在的 Linux 病毒中沒有一個能夠在 Linux 提供的敵對的環境中茁壯成長。現在存在的 Linux 病毒僅僅是技術上的好奇;現實是沒有能養得活的 Linux 病毒。

當然,這並不意味著永遠沒有 Linux 病毒能夠流行。然而它確實意味著一個成功的 Linux 病毒要在不適合生存的 Linux 生態系統中存活下來必須是精心製作並具創新的

2008年12月18日 星期四

Jakarta Commons

兩位前輩的總結,寫得很好。
http://www.blogjava.net/sean/articles/Jakarta_Commons_Notes.html
http://www.blogjava.net/sean/archive/2005/08/02/9015.html


據Common BeanUtils的用戶指南學習了很多有用的工具類.

參考:http://commons.apache.org/beanutils/apidocs/org/apache/commons/beanutils/package-summary.html#package_description


1.屬性的存取

簡單式:

PropertyUtils.getSimpleProperty(Object bean, String name)
PropertyUtils.setSimpleProperty(Object bean, String name, Object value)


索引式:
PropertyUtils.getIndexedProperty(Object bean, String name)
PropertyUtils.getIndexedProperty(Object bean, String name, int index)
PropertyUtils.setIndexedProperty(Object bean, String name, Object value)
PropertyUtils.setIndexedProperty(Object bean, String name, int index, Object value)

Map式:

PropertyUtils.getMappedProperty(Object bean, String name)
PropertyUtils.getMappedProperty(Object bean, String name, String key)
PropertyUtils.setMappedProperty(Object bean, String name, Object value)
PropertyUtils.setMappedProperty(Object bean, String name, String key, Object value)


嵌套式:
PropertyUtils.getNestedProperty(Object bean, String name)
PropertyUtils.setNestedProperty(Object bean, String name, Object value)


通用式:
PropertyUtils.getProperty(Object bean, String name)
PropertyUtils.setProperty(Object bean, String name, Object value)


發現通用式最方便,可以替代上面所有的方式(搞不懂為啥還要弄那麼多)。

舉例:
//簡單式
System.out.println(PropertyUtils.getProperty(employee1, "lastName"));

//索引式
System.out.println(PropertyUtils.getProperty(employee1,"addr[0].city"));

//Map式
PropertyUtils.setProperty(employee1, "telphone(tel)", "test1");
System.out.println(PropertyUtils.getProperty(employee1, "telphone(tel)"));

//嵌套式
String address = (String) PropertyUtils.getProperty(employee1, "address.addr");
System.out.println(address);



2.動態Beans

基本式:(需要先定義屬性然後才能使用,不推薦)

BasicDynaBean and BasicDynaClass


包裝ResultSet式:(必須打開數據庫連接可以使用,不推薦)

ResultSetDynaClass


包裝RowSet式:(可以不用打開連接使用,推薦)

RowSetDynaClass

舉例:

try {
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
Connection conn = DriverManager.getConnection(
"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=java",
"sa", "sa");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select code,name from role");
RowSetDynaClass rsdc = new RowSetDynaClass(rs);
rs.close();
stmt.close();

List rows = rsdc.getRows();
for (Object object : rows) {
DynaBean row = (DynaBean) object;
System.out.println("Role code is " +
row.get("code") +
" and name is " + row.get("name"));
}

} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

懶加載式:(方便實用,重點推薦)

LazyDynaBean

舉例:

LazyDynaBean ldb = new LazyDynaBean();
ldb.set("test1", "tt");
ldb.set("test2", null);
ldb.set("test3", new Employee());
System.out.println(ldb.get("test1"));
System.out.println(ldb.get("test2"));//null
System.out.println(ldb.get("test3"));//顯示Employee.toString()信息

並且也具有LazyDynaMap的功能。


3.數據類型的轉換

重點推薦BeanUtils.populate方法。

舉例:

Address bean = new Address();
HashMap map = new HashMap();
map.put("zipCode1", "zipCode");
map.put("addr", new Long(1234));
map.put("city", "");
map.put("country", "country");
System.out.println(bean);
try {
BeanUtils.populate(bean, map);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(bean);

常利用在action填充vo時。

Database外鍵,用還是不用?


對於主/外鍵/索引來說,在一些開發團隊中被認為是處理數據庫關係的利器,也被某些開發團隊認為是處理某些具體業務的魔鬼,您的觀點呢?在實際應用中您會採取哪種方式?

大家共同觀點:
主鍵和索引是不可少的,不僅可以優化數據檢索速度,開發人員還省不其它的工作,

矛盾焦點:數據庫設計是否需要外鍵。這裡有兩個問題:一個是如何保證數據庫數據的完整性和一致性;二是第一條對性能的影響。

正方觀點:
1,由數據庫自身保證數據一致性,完整性,更可靠,因為程序很難100%保證數據的完整性,而用外鍵即使在數據庫服務器當機或者出現其他問題的時候,也能夠最大限度的保證數據的一致性和完整性。
eg:數據庫和應用是一對多的關係,A應用會維護他那部分數據的完整性,系統一變大時,增加了B應用,A和B兩個應用也許是不同的開發團隊來做的。他們如何協調保證數據的完整性,而且一年以後如果又增加了C應用呢?
2,有主外鍵的數據庫設計可以增加ER圖的可讀性,這點在數據庫設計時非常重要。
3,外鍵在一定程度上說明的業務邏輯,會使設計周到具體全面。

反方觀點:
1,可以用觸發器或應用程序保證數據的完整性
2,過分強調或者說使用主鍵/外鍵會平添開發難度,導致表過多等問題
3,不用外鍵時數據管理簡單,操作方便,性能高(導入導出等操作,在insert, update, delete數據的時候更快)
eg:在海量的數據庫中想都不要去想外鍵,試想,一個程序每天要insert數百萬條記錄,當存在外鍵約束的時候,每次要去掃描此記錄是否合格,一般還不 止一個字段有外鍵,這樣掃描的數量是成級數的增長!我的一個程序入庫在3個小時做完,如果加上外鍵,需要28個小時!

結論:
1,在大型系統中(性能要求不高,安全要求高),使用外鍵;在大型系統中(性能要求高,安全自己控制),不用外鍵;小系統隨便,最好用外鍵。
2,用外鍵要適當,不能過分追求
3,不用外鍵而用程序控制數據一致性和完整性時,應該寫一層來保證,然後個個應用通過這個層來訪問數據庫。

2008年12月17日 星期三

軟件發布版本說明

(轉)小草

大型軟件在正式發布前,通常需要執行Alpha和Beta測試,目的是從實際終端用戶的使用角度,對軟件的功能和性能進行測試,以發現可能只有最終用戶才能發現的錯誤。


Alpha測試(α測試)是由一個用戶在開發環境下進行的測試,也可以是公司內部的用戶在模擬實際操作環境下進行的受控測試,Alpha測試不能由程序員或測試員完成。 Alpha測試發現的錯誤,可以在測試現場立刻反饋給開發人員,由開發人員及時分析和處理。目的是評價軟件產品的功能、可使用性、可靠性、性能和支持。尤其註重產品的界面和特色。 Alpha測試可以從軟件產品編碼結束之後開始,或在模塊(子系統)測試完成後開始,也可以在確認測試過程中產品達到一定的穩定和可靠程度之後再開始。有關的手冊(草稿)等應該在Alpha測試前準備好。



Beta測試(β測試)是軟件的多個用戶在一個或多個用戶的實際使用環境下進行的測試。開發者通常不在測試現場,Beta測試不能由程序員或測試員完成。因而,Beta測試是在開發者無法控制的環境下進行的軟件現場應用。在Beta測試中,由用戶記下遇到的所有問題,包括真實的以及主管認定的,定期向開發者報告,開發者在綜合用戶的報告後,做出修改,最後將軟件產品交付給全體用戶使用。 Beta測試著重於產品的支持性,包括文檔、客戶培訓和支持產品的生產能力。只有當Alpha測試達到一定的可靠程度後,才能開始Beta測試。由於 Beta測試的主要目標是測試可支持性,所以Beta測試應該盡可能由主持產品發行的人員來管理。



由於Alpha和Beta測試的組織難度大,測試費用高,測試的隨機性強、測試週期跨度較長,測試質量和測試效率難於保證,所以,很多專業軟件可能不再進行Beta測試。隨著測試技術的提高,以及專業測試服務機構的大量湧現,很多軟件的Beta測試外包給這些專業測試機構進行測試。



α測試和β測試

在軟件交付使用之後,用戶將如何實際使用程序,對於開發者來說是無法預測的.

α測試是由一個用戶在開發環境下進行的測試,也可以是公司內部的用戶在模擬實際操作環境下進行的

測試.

α測試的目的是評價軟件產品的FLURPS(即功能,局域化,可使用性,可靠性,性能和支持).尤其註重產品的

界面和特色.

α測試可以從軟件產品編碼結束之時開始,或在模塊(子系統)測試完成之後開始,也可以在確認測試過程

中產品達到一定的穩定和可靠程度之後再開始.

β測試是由軟件的多個用戶在實際使用環境下進行的測試.這些用戶返回有關錯誤信息給開發者.

測試時,開發者通常不在測試現場.因而,β測試是在開發者無法控制的環境下進行的軟件現場應用.

在β測試中,由用戶記下遇到的所有問題,包括真實的以及主觀認定的,定期向開發者報告.

β測試主要衡量產品的FLURPS.著重於產品的支持性,包括文檔,客戶培訓和支持產品生產能力.

只有當α測試達到一定的可靠程度時,才能開始β測試.它處在整個測試的最後階段.同時,產品的所有手冊

文本也應該在此階段完全定稿.



α、β、λ常用來表示軟件測試過程中的三個階段,α是第一階段,一般只供內部測試使用;β是第二個階段,已經消除了軟件中大部分的不完善之處,但仍有可能還存在缺陷和漏洞,一般只提供給特定的用戶群來測試使用;λ是第三個階段,此時產品已經相當成熟,只需在個別地方再做進一步的優化處理即可上市發行。



其它相關的版本說明:



Trial:試用版,通常都有時間限制,有些試用版軟件還在功能上做了一定的限制。可註冊或購買成為正式版

Unregistered:未註冊版,通常沒有時間限制,在功能上相對於正式版做了一定的限制。可註冊或購買成為正式版。

Demo:演示版,僅僅集成了正式版中的幾個功能,不能升級成正式版。

Lite:精簡版。

Fullversion:完整版,屬於正式版。



開發階段劃分:

α(Alpha)版:內測版,內部交流或者專業測試人員測試用。 Bug較多,普通用戶最好不要安裝。

β(Beta)版:公測版,專業愛好者大規模測試用,存在一些缺陷,該版本也不適合一般用戶安裝。

γ(Gamma)版:相當成熟的測試版,與即將發行的正式版相差無幾。

RC版:ReleaseCandidate。

RC版。是ReleaseCandidate的縮寫,意思是發布倒計時,候選版本,處於Gamma階段,該版本已經完成全部功能並清除大部分的BUG。到了這個階段只會除BUG,不會對軟件做任何大的更改。從Alpha到Beta再到Gamma是改進的先後關係,但RC1、RC2往往是取捨關係。

Final:正式版。



比較少用的:

Enhance:增強版或者加強版屬於正式版1

Free:自由版

Release:發行版有時間限制

Upgrade:升級版

Retail:零售版

Cardware:屬共享軟件的一種,只要給作者回復一封電郵或明信片即可。 (有的作者並由此提供註冊碼等),目前這種形式已不多見。 /S

Plus:屬增強版,不過這種大部分是在程序界面及多媒體功能上增強。

Preview:預覽版

Corporation&Enterprise:企業版

Standard:標準版

Mini:迷你版也叫精簡版只有最基本的功能

Premium:貴價版

Professional:專業版

Express:特別版(但都好mini, e.g. Oracle Database 10g Express Edition)

Deluxe:豪華版

Regged:已註冊版

2008年11月24日 星期一

JDK 6.0自帶web service

JAVA 6.0之後,其中JDK自帶有個輕量級的web service服務器。如果你比較細心一定發現在你安裝java的路徑下,有java webservice的示例代碼。

我 以前也用java開發過web service ,但是當初用了一個apache下axis開源項目。如果axis夜進化了,反正我不認識了。不過java自帶有何必捨近求遠呢。今天我就把自己創建的最 簡單java webservice範例過程記錄下來,與大家分享。

我用的是netbeans 6,首先建立一個java應用程序工程,名為WebServices。建立一個服務端程序。
package WebServices;

import javax.jws. * ;
import javax.xml.ws.Endpoint;

/**
* @author hecm
*/
@WebService(targetNamespace = " http://www.blogjava.net/JAVA-HE " , serviceName = " HelloService " )
public class WSProvider
{

// @WebResult(name = "Greetings") //自定義該方法返回值在WSDL中相關的描述
@WebMethod(action = " sayHi " , operationName = " sayHi " )
public String sayHi(@WebParam(name = " MyName " ) String name)
{
return " Hi, " name; // @WebParam是自定義參數name在WSDL中相關的描述

}

@Oneway //表明該服務方法是單向的,既沒有返回值,也不應該聲明檢查異常

@WebMethod(action = " printSystemTime " , operationName = " printSystemTime " ) //自定義該方法在WSDL中相關的描述
public void printTime()
{
System.out.println(System.currentTimeMillis());
}

public static void main(String[] args)
{
Thread wsPublisher = new Thread( new WSPublisher());
wsPublisher.start();
}

private static class WSPublisher implements Runnable
{

public void run()
{
//發布WSProvider到http: // localhost:8888/hechangmin/WSProvider這個地址,之前必須調用wsgen命令
//生成服務類WSProvider的支持類,命令如下:
// wsgen -cp . WebServices.WSProvider
Endpoint.publish("http://localhost:8888/JAVA-HE/WSProvider", new WSProvider());
}
}
}

當然建立對應的包,就不用說了。
然後編譯文件。
進入命令提示符下,進入classes目錄,運行:wsgen -cp . WebServices.WSProvider

可以看到將剛才的class生成了幾個java文件和class文件。

現在要做的是發布ws到http://localhost:8888/chinajash/WSProvider
而實際上的動作就是:Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new WSProvider());
當然直接運行WSProvider 。

然後輸入http://localhost:8888/JAVA-HE/WSProvider?wsdl

就已經查看到生成的wsdl (webservice描述語言)。

也就是服務端就OK了。

保持運行。編寫一個測試客戶端:

首先選擇項目,右鍵新建web服務客戶端。其中ws url填入剛才生成的wsdl地址:
http://localhost:8888/JAVA-HE/WSProvider?wsdl

(實際上:和wsimport http://localhost:8888/JAVA-HE/WSProvider?wsdl一樣的效果)


產生一個效果:在classes下按照之前指定的名字空間產生的包下(目錄結構)生成了7個幫助class。

然後我們建立一個包client建立測試文件:



/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package client;

import net.blogjava.java_he. * ;
/**
*
*
@author hecm
*/
public class Test {
public static void main(String args[])
{
HelloService hs
= new HelloService();
WSProvider ws
= hs.getWSProviderPort();
System.out.println(ws.sayHi(
" hechangmin " ));
ws.printSystemTime();
}

}







運行這個測試類:
Hi,hechangmin

輸出了。順利完成!

一點個人經驗,你發布的地址最好寫成可配置。還有就是wsdl中會嚴格按照你指定的url來訪問,比如你指定的127.0.0.1那麼你用本機IP的時候也許並不能順利訪問。

Source: http://www.blogjava.net/JAVA-HE

2008年11月16日 星期日

How To Develop iPhone Applications in Java

Phone is a great phone to develop applications for. Unfortunately Apple decided to restrict developing iPhone applications in a less known language called Objective C, which is used pretty much within Apple (and by Apple developers) and almost noweher else. Only Steve Jobs knows the reason behind this strange decision. Java ( J2ME) is the most popular language & platform for mobile development. So Java developers need a way to develop applications for iPhone too by leveraging their core competency.


Previously I have provided two ways how Java developers can install, compile and run iPhone applications on Java. Today I will present a third method.

Apple's SDK for the iPhone, as you know, is based on Objective-C as the development language as well as Cocoa for the GUI.
Unfortunately Apple's super-restrictive license agreement for the iPhone SDK prohibits the porting of the Java virtual machine to the iPhone. Today we will talk about how we can use Open Source Java to run applications which will run on Apple's iPhone. The open source project by
Arno Puder, Associate Professor at the San Francisco State University, uses a cross-compiler to convert Open Source Java code to Objective-C and provide a Java-based implementation of the Cocoa library. With the help of these tools, iPhone applications can be written in pure Java.

Using the Java version of Cocoa, it is possible to run a Java-based iPhone application as a Java desktop/applet application that can be cross-compiled to run natively on the iPhone.

You can find more details about the software from http://www.xmlvm.org/

XmlVM's SourceForge.net Subversion repository can only be checked out through SVN with the following instruction set:

svn co https://xmlvm.svn.sourceforge.net/svnroot/xmlvm xmlvm

Warning: This is a generic Subversion checkout command which will pull all modules, tags and/or branches of the project. In most cases, you will want to add '/trunk' to the HTTPS URL above to check out only trunk (main development line).

Each of the boxes in the diagram above represents an artifact while the arrows denote the various transformations between those artifacts. The input to the XMLVM toolchain is either a Java class file or a .NET executable. A Java class file is translated to XMLVMJVM which is an XML-document describing the contents of that class file. Likewise XMLVMCLR is an XML-document describing the contents of a .NET executable. XMLVMCLR can be cross-compiled to XMLVMJVM with the help of a data flow analysis (DFA) which is shown as XMLVMCLR-DFA in the figure below. XMLVMJVM serves as a canonical representation as it acts as a boundary between the front- and back-end of the cross-compiler. Once XMLVMJVM has been generated, it can be mapped to various high-level programming languages. It is also possible to map XMLVMJVM to a Java class file again.

Check it out. Also don't forget to read the detailed guide on how to install, compile & run Java applications on iPhone.