N長時間沒有來了.......
忙中偷閑,整理點代碼。
/**
* 復制單個文件
* @param oldPath String 原文件路徑 如:c:/fqf.txt
* @param newPath String 復制后路徑 如:f:/fqf.txt
* @return boolean
*/
public void copyFile(String oldPath, String newPath)
{
try {
int bytesum = 0;
int byteread = 0;
File oldfile = new File(oldPath);
if (oldfile.exists()) { //文件存在時
InputStream inStream = new FileInputStream(oldPath); //讀入原文件
FileOutputStream fs = new FileOutputStream(newPath);
byte[] buffer = new byte[1444];
int length;
while ( (byteread = inStream.read(buffer)) != -1) {
bytesum += byteread; //字節(jié)數 文件大小
System.out.println(bytesum);
fs.write(buffer, 0, byteread);
}
inStream.close();
}
}
catch (Exception e) {
System.out.println("復制單個文件操作出錯");
e.printStackTrace();
}
}
//保存文件的方法
public String Savefiles(FormFile file,String path)
{
String fileName= file.getFileName();
String contentType = file.getContentType();
String size = (file.getFileSize() + " bytes");
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream stream = file.getInputStream();
OutputStream bos = new FileOutputStream(path+fileName);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
stream.close();
}
catch (IOException e) {
return e.getMessage();
}
return "1";
}
//生成15位的字符串
public String GenTradeId()
{
String tradeId = "";
RandomStrg.setCharset("a-zA-Z0-9");
RandomStrg.setLength("15");
try
{
RandomStrg.generateRandomObject();
tradeId=RandomStrg.getRandom();
}
catch (Exception e)
{
}
return tradeId;
}
/**
* 刪除字符串中的空格,至多只保留一個空格
*
* @String txt:輸入需要處理的字符串
* @return String :返回處理后的字符串
*
*/
public String deleteWhitespace(String txt){
if((txt!=null)&&(txt.trim().length()>1)){
}
else{
return "";
}
txt = txt.replaceAll("\n"," ").replaceAll("\t"," ");
String temp="";
try{
int flag =0,num=0;
char c = 'x';
StringBuffer sb = new StringBuffer("");
for(int x=0;x<txt.length();x++){
c = txt.charAt(x);
if((c==' ')&&(flag==0)){
sb.append(c);
flag =1;
}
else if((c!=' ')){
sb.append(c);
flag =0;
}
}
temp = sb.toString().trim();
}
catch(Exception e){
;
}
return temp;
}
SQL語句中,IN、EXISTS、NOT IN、NOT EXISTS的效率較低,尤其是后兩種語句,當數據量較大時,更常給人一種死機般的感覺。本文提供一種使用連接的方法代替以上的四種語句,可大副提高SQL語句的運行效率。以NOT
IN為例,當數據量達到一萬時,效率可提高20倍,數據量越大,效率提高的幅度也就越大。
本文所舉的例子在Oracle 7.0下運行通過,但本文所推薦的方法在各種大型數據庫上皆適用。
為了能夠更好的說明問題,我們采用示例的方式來說明問題。下面,我們將創(chuàng)建一些數據庫表和數據,用于在舉例時使用。
下面的語句將創(chuàng)建我們示例中將使用的表,并分別在表1(TAB1)中存入10000條數據,表2(TAB2)中存入5000條數據。
SQL語句如下:
CREATE TABLE TAB1
(
COL1 VARCHAR(20) NOT NULL,
COL2 INTEGER,
PRIMARY KEY(COL1)
);
CREATE TABLE TAB2
(
COL1 VARCHAR(20) NOT NULL,
PRIMARY KEY(COL1)
);
CREATE TABLE TAB3
(
COL1 VARCHAR(20) NOT NULL,
PRIMARY KEY(COL1)
);
CREATE OR REPLACE TRIGGER T_TAB3 BEFORE INSERT ON TAB3 FOR EACH
ROW
DECLARE
NUM1 NUMBER;
BEGIN
NUM1:=1;
LOOP
EXIT WHEN NUM1>10000;
INSERT INTO TAB1 VALUES (NUM1,NUM1);
IF NUM1<=5000 THEN INSERT INTO TAB2 VALUES (NUM1);
END IF;
NUM1:=NUM1+1;
END LOOP;
END;
INSERT INTO TAB3 VALUES('1');
下面,我們將舉2個例子來具體說明使用連接替換IN、NOT IN、EXISTS、NOT EXISTS的方法。
讀取表1中第2列(COL2)數據的總和,且其第1列數據存在于表2的第1列中。
1. 使用IN的SQL語句:
SELECT SUM(COL2) FROM TAB1 WHERE COL1 IN(SELECT COL1 FROM TAB2)
2. 使用EXISTS的SQL語句:
SELECT SUM(COL2) FROM TAB1 WHERE EXISTS(SELECT * FROM TAB2 WHERE
TAB1.COL1=TAB2.COL1)
3. 使用連接的SQL語句:
SELECT SUM(A.COL2) FROM TAB1 A,TAB2 B
WHERE A.COL1=B.COL1
讀取表1中第2列(COL2)數據的總和,且其第1列數據不存在于表2的第1列中。
1. 使用NOT IN的SQL語句:
SELECT SUM(COL2) FROM TAB1 WHERE COL1 NOT IN(SELECT COL1 FROM TAB2)
2. 使用NOT EXISTS的SQL語句:
SELECT SUM(COL2) FROM TAB1 WHERE NOT EXISTS(SELECT * FROM TAB2 WHERE
TAB1.COL1=TAB2.COL1)
3. 使用外連接的SQL語句:
SELECT SUM(A.COL2) FROM TAB1 A,TAB2 B WHERE A.COL1=B.COL1(+) AND
B.COL1 IS NULL
下面介紹IN、NOT IN、EXIST、NOT EXIST在DELETE和UPDATE語句中的效率提高方法。
下面所舉的例子在Microsoft SQL Server
7.0下運行通過,但所推薦的方法在各種大型數據庫上皆適用。下面,我們將創(chuàng)建一些數據庫表和數據,用于舉例說明。我們將分別在表A(TA)中存入
10000條數據,表B(TB)中存入5000條數據。
SQL語句如下:
CREATE TABLE TA
(
CA INT
)
CREATE TABLE TB
(
CA INT
)
CREATE TABLE TC
(
CA INT
)
CREATE TRIGGER TRA ON TC
FOR INSERT
AS
DECLARE @MINT INT
BEGIN
SELECT @MINT=1
WHILE (@MINT<=5000)
BEGIN
INSERT INTO TA VALUES(@MINT)
INSERT INTO TB VALUES(@MINT)
SELECT @MINT=@MINT+1
END
WHILE (@MINT<=10000)
BEGIN
INSERT INTO TA VALUES(@MINT)
SELECT @MINT=@MINT+1
END
END
GO
INSERT INTO TC VALUES(1)
GO
刪除表A中表A和表B相同的數據
1. 用IN的SQL語句:
DELETE FROM TA WHERE TA.CA IN (SELECT CA FROM TB)
2. 用EXISTS的SQL語句:
DELETE FROM TA WHERE EXISTS (SELECT * FROM TB WHERE TB.CA=TA.CA)
3. 使用連接的SQL語句:
DELETE TA FROM TA,TB WHERE TA.CA=TB.CA
刪除表A中表A存在但表B中不存在的數據
1. 使用IN的SQL語句:
DELETE FROM TA WHERE TA.CA NOT IN (SELECT CA FROM TB)
2. 使用EXISTS的SQL語句:
DELETE FROM TA WHERE NOT EXISTS (SELECT CA FROM TB WHERE TB.CA=TA.CA)
3. 使用連接的SQL語句:
DELETE TA FROM TA LEFT OUTER JOIN TB ON TA.CA=TB.CA WHERE TB.CA
IS NULL
更新表A中表A和表B相同的數據
1. 使用IN的SQL語句:
UPDATE TA SET CA=CA+10000 WHERE CA IN (SELECT CA FROM TB)
2. 使用EXISTS的SQL語句:
UPDATE TA SET CA=CA+10000 WHERE EXISTS (SELECT CA FROM TB WHERE
TB.CA=TA.CA)
3. 使用連接的SQL語句:
UPDATE TA SET TA.CA=TA.CA+10000 FROM TA,TB WHERE TA.CA=TB.CA
更新表A中表A存在但表B中不存在的數據
1. 使用IN的SQL語句:
UPDATE TA SET CA=CA+10000 WHERE CA NOT IN (SELECT CA FROM TB)
2. 使用EXISTS的SQL語句:
UPDATE TA SET CA=CA+10000 WHERE NOT EXISTS (SELECT CA FROM TB WHERE
TB.CA=TA.CA)
3. 使用連接的SQL語句:
UPDATE TA SET TA.CA=TA.CA+10000 FROM TA LEFT OUTER JOIN TB ON TA.CA=TB.CA
WHERE TB.CA IS NULL
J2ee(Java 2 Enterprise Edition)是建立在Java 2平臺上的企業(yè)級應用的解決方案。J2EE技術的基礎便是Java 2平臺,不但有J2SE平臺的所有功能,同時還提供了對EJB,Servlet,JSP,XML等技術的全面支持,其最終目標是成為一個支持企業(yè)級應用開發(fā)的體系結構,簡化企業(yè)解決方案的開發(fā),部署和管理等復雜問題。事實上,J2EE已經成為企業(yè)級開發(fā)的工業(yè)標準和首選平臺。
J2EE并非一個產品,而是一系列的標準。市場上可以看到很多實現了J2EE的產品,如BEA WebLogic,IBM WebSphere以及開源的JBoss等等。
?????
J2EE,是sun公司提出的一個標準,符合這個標準的產品叫"實現";其中你下載的sun公司的j2ee開發(fā)包中就有一個這樣的"實現",而
jboss,weblogic,websphere都是j2ee標準的一個"實現"。由于jboss,weblogic,websphere自身帶有
j2ee的api,所以可以不使用sun的j2ee實現。
一. J2EE的概念
????? 目前,Java 2平臺有3個版本,它們是適用于小型設備和智能卡的Java 2平臺Micro版(Java 2 Platform Micro Edition,J2ME)、適用于桌面系統(tǒng)的Java 2平臺標準版(Java 2 Platform Standard Edition,J2SE)、適用于創(chuàng)建服務器應用程序和服務的Java2平臺企業(yè)版(Java 2 Platform Enterprise Edition,J2EE)。
????? J2EE是一種利用Java 2平臺來簡化企業(yè)解決方案的開發(fā)、部署和管理相關的復雜問題的體系結構。J2EE技術的基礎就是核心Java平臺或Java 2平臺的標準版,J2EE不僅鞏固了標準版中的許多優(yōu)點,例如"編寫一次、隨處運行"的特性、方便存取數據庫的JDBC API、CORBA技術以及能夠在Internet應用中保護數據的安全模式等等,同時還提供了對 EJB(Enterprise JavaBeans)、Java Servlets API、JSP(Java Server Pages)以及XML技術的全面支持。其最終目的就是成為一個能夠使企業(yè)開發(fā)者大幅縮短投放市場時間的體系結構。
????? J2EE體系結構提供中間層集成框架用來滿足無需太多費用而又需要高可用性、高可靠性以及可擴展性的應用的需求。通過提供統(tǒng)一的開發(fā)平臺,J2EE降低了開發(fā)多層應用的費用和復雜性,同時提供對現有應用程序集成強有力支持,完全支持Enterprise JavaBeans,有良好的向導支持打包和部署應用,添加目錄支持,增強了安全機制,提高了性能。
二. J2EE的優(yōu)勢
???? J2EE為搭建具有可伸縮性、靈活性、易維護性的商務系統(tǒng)提供了良好的機制:
????? 保留現存的IT資產: 由于企業(yè)必須適應新的商業(yè)需求,利用已有的企業(yè)信息系統(tǒng)方面的投資,而不是重新制定全盤方案就變得很重要。這樣,一個以漸進的(而不是激進的,全盤否定的)方式建立在已有系統(tǒng)之上的服務器端平臺機制是公司所需求的。J2EE架構可
以充分利用用戶原有的投資,如一些公司使用的BEA Tuxedo、IBM CICS, IBM Encina,、Inprise
VisiBroker 以及Netscape Application
Server。這之所以成為可能是因為J2EE擁有廣泛的業(yè)界支持和一些重要的'企業(yè)計算'領域供應商的參與。每一個供應商都對現有的客戶提供了不用廢棄
已有投資,進入可移植的J2EE領域的升級途徑。由于基于J2EE平臺的產品幾乎能夠在任何操作系統(tǒng)和硬件配置上運行,現有的操作系統(tǒng)和硬件也能被保留使用。
????? 高效的開發(fā): J2EE允許公司把一些通用的、很繁瑣的服務端任務交給中間件供應商去完成。這樣開發(fā)人員可以集中精力在如何創(chuàng)建商業(yè)邏輯上,相應地縮短了開發(fā)時間。高級中間件供應商提供以下這些復雜的中間件服務:
????? 狀態(tài)管理服務 -- 讓開發(fā)人員寫更少的代碼,不用關心如何管理狀態(tài),這樣能夠更快地完成程序開發(fā)。
????? 持續(xù)性服務 -- 讓開發(fā)人員不用對數據訪問邏輯進行編碼就能編寫應用程序,能生成更輕巧,與數據庫無關的應用程序,這種應用程序更易于開發(fā)與維護。
????? 分布式共享數據對象CACHE服務 -- 讓開發(fā)人員編制高性能的系統(tǒng),極大提高整體部署的伸縮性。
?????
支持異構環(huán)境:
J2EE能夠開發(fā)部署在異構環(huán)境中的可移植程序。基于J2EE的應用程序不依賴任何特定操作系統(tǒng)、中間件、硬件。因此設計合理的基于J2EE的程序只需開
發(fā)一次就可部署到各種平臺。這在典型的異構企業(yè)計算環(huán)境中是十分關鍵的。J2EE標準也允許客戶訂購與J2EE兼容的第三方的現成的組件,把他們部署到異構環(huán)境中,節(jié)省了由自己制訂整個方案所需的費用。
?????
可伸縮性:
企業(yè)必須要選擇一種服務器端平臺,這種平臺應能提供極佳的可伸縮性去滿足那些在他們系統(tǒng)上進行商業(yè)運作的大批新客戶。基于J2EE平臺的應用程序可被部署
到各種操作系統(tǒng)上。例如可被部署到高端UNIX與大型機系統(tǒng),這種系統(tǒng)單機可支持64至256個處理器。(這是NT服務器所望塵莫及的)J2EE領域的供
應商提供了更為廣泛的負載平衡策略。能消除系統(tǒng)中的瓶頸,允許多臺服務器集成部署。這種部署可達數千個處理器,實現可高度伸縮的系統(tǒng),滿足未來商業(yè)應用的
需要。
????? 穩(wěn)定的可用性:
一個服務器端平臺必須能全天候運轉以滿足公司客戶、合作伙伴的需要。因為INTERNET是全球化的、無處不在的,即使在夜間按計劃停機也可能造成嚴重損
失。若是意外停機,那會有災難性后果。J2EE部署到可靠的操作環(huán)境中,他們支持長期的可用性。一些J2EE部署在WINDOWS環(huán)境中,客戶也可選擇健
壯性能更好的操作系統(tǒng)如Sun Solaris、IBM OS/390。最健壯的操作系統(tǒng)可達到99.999%的可用性或每年只需5分鐘停機時間。這是實時性很強商業(yè)系統(tǒng)理想的選擇。
三. J2EE 的四層模型
????? J2EE使用多層的分布式應用模型,應用邏輯按功能劃分為組件,各個應用組件根據他們所在的層分布在不同的機器上。事實上,sun設計J2EE的初衷正是為了解決兩層模式(client/server)的弊端,在傳統(tǒng)模式中,客戶端擔
當了過多的角色而顯得臃腫,在這種模式中,第一次部署的時候比較容易,但難于升級或改進,可伸展性也不理想,而且經常基于某種專有的協(xié)議――通常是某種數
據庫協(xié)議。它使得重用業(yè)務邏輯和界面邏輯非常困難。現在J2EE
的多層企業(yè)級應用模型將兩層化模型中的不同層面切分成許多層。一個多層化應用能夠為不同的每種服務提供一個獨立的層,以下是 J2EE 典型的四層結構:
????? 運行在客戶端機器上的客戶層組件
????? 運行在J2EE服務器上的Web層組件
????? 運行在J2EE服務器上的業(yè)務邏輯層組件
????? 運行在EIS服務器上的企業(yè)信息系統(tǒng)(Enterprise information system)層軟件
????? J2EE應用程序組件
????? J2EE應用程序是由組件構成的.J2EE組件是具有獨立功能的軟件單元,它們通過相關的類和文件組裝成J2EE應用程序,并與其他組件交互。J2EE說明書中定義了以下的J2EE組件:
????? 應用客戶端程序和applets是客戶層組件.
????? Java Servlet和JavaServer Pages(JSP)是web層組件.
????? Enterprise JavaBeans(EJB)是業(yè)務層組件.
????? 客戶層組件
????? J2EE應用程序可以是基于web方式的,也可以是基于傳統(tǒng)方式的.
????? web 層組件J2EE web層組件可以是JSP 頁面或Servlets.按照J2EE規(guī)范,靜態(tài)的HTML頁面和Applets不算是web層組件。
????? 正如下圖所示的客戶層那樣,web層可能包含某些 JavaBean 對象來處理用戶輸入,并把
輸入發(fā)送給運行在業(yè)務層上的enterprise bean 來進行處理。
????? 業(yè)務層組件
?????
業(yè)務層代碼的邏輯用來滿足銀行,零售,金融等特殊商務領域的需要,由運行在業(yè)務層上的enterprise bean 進行處理.
下圖表明了一個enterprise bean 是如何從客戶端程序接收數據,進行處理(如果必要的話), 并發(fā)送到EIS
層儲存的,這個過程也可以逆向進行。
????? 有三種企業(yè)級的bean: 會話(session) beans, 實體(entity) beans, 和 消息驅
動(message-driven) beans. 會話bean 表示與客戶端程序的臨時交互. 當客戶端程序執(zhí)行完后, 會話bean
和相關數據就會消失. 相反, 實體bean 表示數據庫的表中一行永久的記錄. 當客戶端程序中止或服務器關閉時,
就會有潛在的服務保證實體bean 的數據得以保存.消息驅動 bean 結合了會話bean 和 JMS的消息監(jiān)聽器的特性, 允許一個業(yè)務層組件異步接收JMS 消息.
????? 企業(yè)信息系統(tǒng)層
????? 企業(yè)信息系統(tǒng)層處理企業(yè)信息系統(tǒng)軟件包括企業(yè)基礎建設系統(tǒng)例如企業(yè)資源計劃 (ERP), 大型機事務處理, 數據庫系統(tǒng),和其它的遺留信息系統(tǒng). 例如,J2EE 應用組件可能為了數據庫連接需要訪問企業(yè)信息系統(tǒng)
????? 我們就J2EE的各種組件、服務和API,進行更加詳細的闡述,看看在開發(fā)不同類型的企業(yè)級應用時,根據各自需求和目標的不同,應當如何靈活使用并組合不同的組件和服務。
· Servlet
?????
Servlet是Java平臺上的CGI技術。Servlet在服務器端運行,動態(tài)地生成Web頁面。與傳統(tǒng)的CGI和許多其它類似CGI的技術相比,
Java Servlet具有更高的效率并更容易使用。對于Servlet,重復的請求不會導致同一程序的多次轉載,它是依靠線程的方式來支持并發(fā)訪問的。
· JSP
????? JSP(Java Server Page)是一種實現普通靜態(tài)HTML和動態(tài)頁面輸出混合編碼的技術。從這一點來看,非常類似Microsoft ASP、PHP等
技術。借助形式上的內容和外觀表現的分離,Web頁面制作的任務可以比較方便地劃分給頁面設計人員和程序員,并方便地通過JSP來合成。在運行時態(tài),
JSP將會被首先轉換成Servlet,并以Servlet的形態(tài)編譯運行,因此它的效率和功能與Servlet相比沒有差別,一樣具有很高的效率。
· EJB
????? EJB定義了一組可重用的組件:Enterprise Beans。開發(fā)人員可以利用這些組件,像搭積木一樣建立分布式應用。在裝配組件時,所有的Enterprise Beans都需要配置到EJB服務器(一般的Weblogic、WebSphere等J2EE應用服務器都
是EJB服務器)中。EJB服務器作為容器和低層平臺的橋梁管理著EJB容器,并向該容器提供訪問系統(tǒng)服務的能力。所有的EJB實例都運行在EJB容器
中。EJB容器提供了系統(tǒng)級的服務,控制了EJB的生命周期。EJB容器為它的開發(fā)人員代管了諸如安全性、遠程連接、生命周期管理及事務管理等技術環(huán)節(jié),
簡化了商業(yè)邏輯的開發(fā)。EJB中定義了三種Enterprise Beans:
◆ Session Beans
◆ Entity Beans
◆ Message-driven Beans
· JDBC
????? JDBC(Java Database Connectivity,Java數據庫連接)API是一個標準SQL(Structured Query Language,
結構化查詢語言)數據庫訪問接口,它使數據庫開發(fā)人員能夠用標準Java API編寫數據庫應用程序。JDBC
API主要用來連接數據庫和直接調用SQL命令執(zhí)行各種SQL語句。利用JDBC
API可以執(zhí)行一般的SQL語句、動態(tài)SQL語句及帶IN和OUT參數的存儲過程。Java中的JDBC相當與Microsoft平臺中的ODBC(Open Database Connectivity)。
· JMS
????? JMS(Java Message Service,Java消息服務)
是一組Java應用接口,它提供創(chuàng)建、發(fā)送、接收、讀取消息的服務。JMS
API定義了一組公共的應用程序接口和相應語法,使得Java應用能夠和各種消息中間件進行通信,這些消息中間件包括IBM
MQ-Series、Microsoft MSMQ及純Java的SonicMQ。通過使用JMS
API,開發(fā)人員無需掌握不同消息產品的使用方法,也可以使用統(tǒng)一的JMS
API來操縱各種消息中間件。通過使用JMS,能夠最大限度地提升消息應用的可移植性。 JMS既支持點對點的消息通信,也支持發(fā)布/訂閱式的消息通信。
· JNDI
?????
由于J2EE應用程序組件一般分布在不同的機器上,所以需要一種機制以便于組件客戶使用者查找和引用組件及資源。在J2EE體系中,使用JNDI
(Java Naming and Directory
Interface)定位各種對象,這些對象包括EJB、數據庫驅動、JDBC數據源及消息連接等。JNDI
API為應用程序提供了一個統(tǒng)一的接口來完成標準的目錄操作,如通過對象屬性來查找和定位該對象。由于JNDI是獨立于目錄協(xié)議的,應用還可以使用
JNDI訪問各種特定的目錄服務,如LDAP、NDS和DNS等。
· JTA
????? JTA(Java Transaction
API)提供了J2EE中處理事務的標準接口,它支持事務的開始、回滾和提交。同時在一般的J2EE平臺上,總提供一個JTS(Java
Transaction Service)作為標準的事務處理服務,開發(fā)人員可以使用JTA來使用JTS。
· JCA
????? JCA(J2EE Connector Architecture)是J2EE體系架構的一部分,為開發(fā)人員提供了一套連接各種企業(yè)信息系統(tǒng)(EIS,包括ERP、SCM、CRM等)的體系架構,對于EIS開發(fā)商而言,它們只需要開發(fā)一套基于JCA的EIS連接適配器,開發(fā)人員就能夠在任何的J2EE應用服務器中連接并使用它。基于JCA的連接適配器的實現,需要涉及J2EE中的事務管理、安全管理及連接管理等服務組件。
· JMX
????? JMX(Java Management Extensions)的前身是JMAPI。JMX致力于解決分布式系統(tǒng)管理的問題。JMX是一種應用編程接口、
可擴展對象和方法的集合體,可以跨越各種異構操作系統(tǒng)平臺、系統(tǒng)體系結構和網絡傳輸協(xié)議,開發(fā)無縫集成的面向系統(tǒng)、網絡和服務的管理應用。JMX是一個完
整的網絡管理應用程序開發(fā)環(huán)境,它同時提供了廠商需要收集的完整的特性清單、可生成資源清單表格、圖形化的用戶接口;訪問SNMP的網絡API;主機間遠程過程調用;數據庫訪問方法等。
· JAAS
????? JAAS(Java Authentication and
Authorization Service)實現了一個Java版本的標準Pluggable Authentication
Module(PAM)的框架。JAAS可用來進行用戶身份的鑒定,從而能夠可靠并安全地確定誰在執(zhí)行Java代碼。同時JAAS還能通過對用戶進行授
權,實現基于用戶的訪問控制。
· JACC
????? JACC(Java Authorization Service Provider
Contract for
Containers)在J2EE應用服務器和特定的授權認證服務器之間定義了一個連接的協(xié)約,以便將各種授權認證服務器插入到J2EE產品中去。
· JAX-RPC
????? 通過使用JAX-RPC(Java API for XML-based
RPC),已有的Java類或Java應用都能夠被重新包裝,并以Web
Services的形式發(fā)布。JAX-RPC提供了將RPC參數(in/out)編碼和解碼的API,使開發(fā)人員可以方便地使用SOAP消息來完成RPC
調用。同樣,對于那些使用EJB(Enterprise
JavaBeans)的商業(yè)應用而言,同樣可以使用JAX-RPC來包裝成Web服務,而這個Web
Servoce的WSDL界面是與原先的EJB的方法是對應一致的。JAX-RPC為用戶包裝了Web服務的部署和實現,對Web服務的開發(fā)人員而言,
SOAP/WSDL變得透明,這有利于加速Web服務的開發(fā)周期。
· JAXR
????? JAXR(Java API for XML
Registries)提供了與多種類型注冊服務進行交互的API。JAXR運行客戶端訪問與JAXR規(guī)范相兼容的Web
Servcices,這里的Web Services即為注冊服務。一般來說,注冊服務總是以Web
Services的形式運行的。JAXR支持三種注冊服務類型:JAXR Pluggable Provider、Registry-specific
JAXR Provider、JAXR Bridge Provider(支持UDDI Registry和ebXML
Registry/Repository等)。
· SAAJ
????? SAAJ(SOAP with Attachemnts API for Java)是JAX-RPC的一個增強,為進行低層次的SOAP消息操縱提供了支持。
四. J2EE 的結構
????? 這種基于組件,具有平臺無關性的J2EE 結構使得J2EE 程序的編寫十分簡單,因為業(yè)務邏輯被封裝成可復用的組件,并且J2EE 服務器以容器的形式為所有的組件類型提供后臺服務. 因為你不用自己開發(fā)這種服務, 所以你可以集中精力解決手頭的業(yè)務問題.
????? 容器和服務
????? 容器設置定制了J2EE服務器所提供得內在支持,包括安全,事務管理,JNDI(Java Naming and Directory Interface)尋址,遠程連接等服務,以下列出最重要的幾種服務:
????? J2EE安全(Security)模型可以讓你配置 web
組件或enterprise bean ,這樣只有被授權的用戶才能訪問系統(tǒng)資源.
每一客戶屬于一個特別的角色,而每個角色只允許激活特定的方法。你應在enterprise
bean的布置描述中聲明角色和可被激活的方法。由于這種聲明性的方法,你不必編寫加強安全性的規(guī)則。
????? J2EE 事務管理(Transaction
Management)模型讓你指定組成一個事務中所有方法間的關系,這樣一個事務中的所有方法被當成一個單一的單元.
當客戶端激活一個enterprise bean中的方法,容器介入一管理事務。因有容器管理事務,在enterprise
bean中不必對事務的邊界進行編碼。要求控制分布式事務的代碼會非常復雜。你只需在布置描述文件中聲明enterprise
bean的事務屬性,而不用編寫并調試復雜的代碼。容器將讀此文件并為你處理此enterprise bean的事務。
????? JNDI 尋址(JNDI Lookup)服務向企業(yè)內的多重名字和目錄服務提供了一個統(tǒng)一的接口,這樣應用程序組件可以訪問名字和目錄服務.
????? J2EE遠程連接(Remote Client Connectivity)模型管理客戶端和enterprise bean間的低層交互. 當一個enterprise bean創(chuàng)建后, 一個客戶端可以調用它的方法就象它和客戶端位于同一虛擬機上一樣.
????? 生存周期管理(Life Cycle
Management)模型管理enterprise bean的創(chuàng)建和移除,一個enterprise
bean在其生存周期中將會歷經幾種狀態(tài)。容器創(chuàng)建enterprise
bean,并在可用實例池與活動狀態(tài)中移動他,而最終將其從容器中移除。即使可以調用enterprisebean的create及remove方法,容
器也將會在后臺執(zhí)行這些任務。
五、企業(yè)級應用示例
????? 下面我們通過假設一個企業(yè)應用的J2EE實現,來了解各種組件和服務的應用。假設應用對象是計算機產品的生產商/零售商的銷售系統(tǒng),這個銷售系統(tǒng)能夠通過自己的網站發(fā)布產品信息,同時也能將產品目錄傳送給計算機產品交易市場。銷售系統(tǒng)能夠在線接受訂單(來自自己的Web網站或者來自計算機產品交易市場),并隨后轉入內部企業(yè)管理系統(tǒng)進行相關的后續(xù)處理。
????? 參見圖1,這個企業(yè)應用可以這種方式架構。該企業(yè)應用的核心是產品目錄管理和產品定購管理這兩個業(yè)務邏輯,使用EJB加以實現,并部署在EJB容器中。由于產品目錄和定購信息都需要持久化,因此使用JDBC連接數據庫,并使用JTA來完成數據庫存取事務。
圖1 J2EE應用示例
?????
然后使用JSP/Servlet來實現應用的Web表現:在線產品目錄瀏覽和在線定購。為了將產品目錄發(fā)送給特定的交易市場,使用JMS實現異步的基于消
息的產品目錄傳輸。為了使得更多的其它外部交易市場能夠集成產品目錄和定購業(yè)務,需要使用Web
Services技術包裝商業(yè)邏輯的實現。由于產品定購管理需要由公司內部雇員進行處理,因此需要集成公司內部的用戶系統(tǒng)和訪問控制服務以方便雇員的使
用,使用JACC集成內部的訪問控制服務,使用JNDI集成內部的用戶目錄,并使用JAAS進行訪問控制。由于產品訂購事務會觸發(fā)后續(xù)的企業(yè)ERP系統(tǒng)的
相關操作(包括倉儲、財務、生產等),需要使用JCA連接企業(yè)ERP。
????? 最后為了將這個應用納入到企業(yè)整體的系統(tǒng)管理體系中去,使用Application Client架構了一個管理客戶端(與其它企業(yè)應用管理應用部署在一臺機器上),并通過JMX管理這個企業(yè)應用。
????????????????????????????? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (
摘自中科永聯(lián)
高級技術培訓中心
)
//數據庫中對于時間的查詢操作
public static String getDateSql(Date sDate, String dateType) {
?? ??? ?String start = sDate.getYear() + 1900 + "-" + (sDate.getMonth() + 1)
?? ??? ??? ??? ?+ "-" + sDate.getDate() + " 00:00:00";
?? ??? ?String end = sDate.getYear() + 1900 + "-" + (sDate.getMonth() + 1)
?? ??? ??? ??? ?+ "-" + sDate.getDate() + " 23:59:59";
?? ??? ?String sql = " and " + dateType + " >= TO_DATE('" + start
?? ??? ??? ??? ?+ "','YYYY-MM-DD HH24:MI:SS') and " + dateType
?? ??? ??? ??? ?+ " <= TO_DATE('" + end
?? ??? ??? ??? ?+ "','YYYY-MM-DD HH24:MI:SS') order by " + dateType;
?? ??? ?return sql;
?? ?}
//Java SWT中對于文本框只能輸入數字的限制
/**
??? ?* 數字校驗
??? ?*
??? ?* @param text
??? ?*/
??? private void checkNumber(Text text) {
??? ??? text.addVerifyListener(new VerifyListener() {
??? ??? ??? public void verifyText(VerifyEvent e) {
??? ??? ??? ??? e.doit = ("0123456789.".indexOf(e.text) >= 0);
??? ??? ??? ??? if (e.keyCode == SWT.BS || e.keyCode == SWT.DEL
??? ??? ??? ??? ??? ??? || e.keyCode == SWT.HOME || e.keyCode == SWT.END)
??? ??? ??? ??? ??? e.doit = true;
??? ??? ??? }
??? ??? });
??? }
//對于一些復雜的查詢時可以用HashMap來處理
private String getHql(List<Long> respList,List<Long> customerList, Map<String, Object> map){
??? ??? String hql = " from CrmFeedBack t where 1=1";
??? ??? Object key, value;
??? ??? if (respList != null && respList.size() > 0) {
??? ??? ??? hql += " and t.resp_Idx in (";
??? ??? ??? for (Long id : respList) {
??? ??? ??? ??? hql += id + ",".trim();
??? ??? ??? }
??? ??? ??? hql += ")";
??? ??? ??? hql = hql.replace(",)", ")");
??? ??? }
??? ??? if (customerList != null && customerList.size() > 0) {
??? ??? ??? hql += " and t.client_Name in (";
??? ??? ??? for (Long id : customerList) {
??? ??? ??? ??? hql += id + ",".trim();
??? ??? ??? }
??? ??? ??? hql += ")";
??? ??? ??? hql = hql.replace(",)", ")");
??? ??? }
??? ??? if (map != null && map.size() > 0) {
??? ??? ??? Iterator it = map.entrySet().iterator();
??? ??? ??? while (it.hasNext()) {
??? ??? ??? ??? Map.Entry entry = (Map.Entry) it.next();
??? ??? ??? ??? key = entry.getKey();
??? ??? ??? ??? value = entry.getValue();
??? ??? ??? ??? if (key.equals("resp_Idx") || key.equals("priority")) {
??? ??? ??? ??? ??? hql += " and t." + key + "= " + value;
??? ??? ??? ??? } else {
??? ??? ??? ??? ??? hql += " and t." + key + " like '%" + value + "%'";
??? ??? ??? ??? }
??? ??? ??? }
??? ??? }
??? ??? return hql;
}
///////////////
?? /**
??? ?* Creates the initial layout for a page.
??? ?*/
??? public void createInitialLayout(IPageLayout layout) {
??? ??? String editorArea = layout.getEditorArea();
??? ??? layout.setEditorAreaVisible(false);
??? ??? IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
??? ??? ??? ??? 0.2f, editorArea);
??? ??? left.addView(MyTreeView.ID);
??? ??? left.addView(NavigationView.ID);
??? ??? IFolderLayout right = layout.createFolder("right", IPageLayout.RIGHT,
??? ??? ??? ??? 0.8f, editorArea);
??? ??? right.addView(MyTableView.ID);
??? ??? addFastViews(layout);
??? ??? addViewShortcuts(layout);
??? ??? addPerspectiveShortcuts(layout);
??? }
//得到系統(tǒng)文件夾的方法
??? Image image=PlatformUI.getWorkbench().getSharedImages().getImage(
??? ??? ??? ??? ISharedImages.IMG_OBJ_FOLDER);
private?bool IsNumeric(string str)?
{??
?? System.Text.RegularExpressions.Regex reg
?????? = new System.Text.RegularExpressions.Regex(@"^[-]?\d+[.]?\d*$");??
?? return reg.IsMatch(str);?
}
MarQuee的用法
基本語法
<marquee> ... </marquee>
移動屬性的設置 ,這種移動不僅僅局限于文字,也可以應用于圖片,表格等等
方向
<direction=#> #=left, right ,up ,down <marquee
direction=left>從右向左移!</marquee>
方式
<bihavior=#> #=scroll, slide, alternate <marquee
behavior=scroll>一圈一圈繞著走!</marquee>
<marquee behavior=slide>只走一次就歇了!</marquee>
<marquee behavior=alternate>來回走</marquee>
循環(huán)
<loop=#> #=次數;若未指定則循環(huán)不止(infinite) <marquee loop=3 width=50%
behavior=scroll>只走 3 趟</marquee> <P>
<marquee loop=3 width=50% behavior=slide>只走 3 趟</marquee>
<marquee loop=3 width=50% behavior=alternate>只走 3 趟!</marquee>
速度
<scrollamount=#> <marquee scrollamount=20>啦啦啦,我走得好快喲!</marquee>
延時
<scrolldelay=#> <marquee scrolldelay=500
scrollamount=100>啦啦啦,我走一步,停一停!</marquee>
外觀(Layout)設置
對齊方式(Align)
<align=#> #=top, middle, bottom <font size=6>
<marquee align=# width=400>啦啦啦,我會移動耶!</marquee>
</font>
底色
<bgcolor=#> #=rrggbb 16 進制數碼,或者是下列預定義色彩:
Black, Olive, Teal, Red, Blue, Maroon, Navy, Gray, Lime,
Fuchsia, White, Green, Purple, Silver, Yellow, Aqua <marquee
bgcolor=aaaaee>顏色!</marquee>
面積
<height=# width=#> <marquee height=40 width=50%
bgcolor=aaeeaa>面積!</marquee>
空白
(Margins)<hspace=# vspace=#>
<marquee hspace=20 vspace=20 width=150 bgcolor=ffaaaa
align=middle>面積!</marquee>
?? ?public void dndBuilder() {
?? ??? ?Transfer[] type = new Transfer[] { TextTransfer.getInstance() };
?? ??? ?int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK
?? ??? ??? ??? ?| DND.DROP_NONE;
?? ??? ?final DragSource source = new DragSource(tree, operations);
?? ??? ?source.setTransfer(type);
?? ??? ?final TreeItem[] dragSourceItem = new TreeItem[1];
?? ??? ?source.addDragListener(new DragSourceListener() {
?? ??? ??? ?public void dragStart(DragSourceEvent event) {
?? ??? ??? ??? ?TreeItem[] selection = tree.getSelection();
?? ??? ??? ??? ?if (selection.length > 0) {
?? ??? ??? ??? ??? ?event.doit = true;
?? ??? ??? ??? ??? ?dragSourceItem[0] = selection[0];
?? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ?event.doit = false;
?? ??? ??? ??? ?}
?? ??? ??? ?};
?? ??? ??? ?public void dragSetData(DragSourceEvent event) {
?? ??? ??? ??? ?event.data = dragSourceItem[0].getText();
?? ??? ??? ?}
?? ??? ??? ?public void dragFinished(DragSourceEvent event) {
?? ??? ??? ??? ?if (event.detail == DND.DROP_MOVE) {
?? ??? ??? ??? ??? ?dragSourceItem[0].dispose();
?? ??? ??? ??? ??? ?dragSourceItem[0] = null;
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?});
?? ??? ?DropTarget target = new DropTarget(tree, operations);
?? ??? ?target.setTransfer(type);
?? ??? ?target.addDropListener(new DropTargetAdapter() {
?? ??? ??? ?private TreeItem initTreeItem(TreeItem sitem, TreeItem ditem) {
?? ??? ??? ??? ?ditem.setText(sitem.getText());
?? ??? ??? ??? ?ditem.setData(sitem.getData());
?? ??? ??? ??? ?for (int i = 0; i < sitem.getItemCount(); i++) {
?? ??? ??? ??? ??? ?TreeItem subitem = new TreeItem(ditem, SWT.NONE);
?? ??? ??? ??? ??? ?try {
?? ??? ??? ??? ??? ??? ?subitem = initTreeItem(sitem.getItem(i), subitem);
?? ??? ??? ??? ??? ?} catch (Exception e) {
?? ??? ??? ??? ??? ??? ?// e.printStackTrace();
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ??? ?return ditem;
?? ??? ??? ?}
?? ??? ??? ?private boolean checkValidate(TreeItem sitem, TreeItem ditem) {
?? ??? ??? ??? ?if (ditem.equals(sitem))
?? ??? ??? ??? ??? ?return false;
?? ??? ??? ??? ?TreeItem titem = ditem.getParentItem();
?? ??? ??? ??? ?while (titem != null) {
?? ??? ??? ??? ??? ?if (sitem.equals(titem))
?? ??? ??? ??? ??? ??? ?return false;
?? ??? ??? ??? ??? ?titem = titem.getParentItem();
?? ??? ??? ??? ?}
?? ??? ??? ??? ?return true;
?? ??? ??? ?}
?? ??? ??? ?public void dragOver(DropTargetEvent event) {
?? ??? ??? ??? ?event.feedback = DND.FEEDBACK_NONE | DND.FEEDBACK_SCROLL;
?? ??? ??? ??? ?if (event.item != null) {
?? ??? ??? ??? ??? ?TreeItem item = (TreeItem) event.item;
?? ??? ??? ??? ??? ?if (!checkValidate(dragSourceItem[0], item)) {
?? ??? ??? ??? ??? ??? ?event.detail = DND.DROP_NONE;
?? ??? ??? ??? ??? ??? ?return;
?? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ?event.detail = DND.DROP_MOVE;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?Point pt = shell.getDisplay().map(null, tree, event.x,
?? ??? ??? ??? ??? ??? ??? ?event.y);
?? ??? ??? ??? ??? ?Rectangle bounds = item.getBounds();
?? ??? ??? ??? ??? ?if (pt.y < bounds.y + bounds.height / 3) {
?? ??? ??? ??? ??? ??? ?event.feedback |= DND.FEEDBACK_INSERT_BEFORE;
?? ??? ??? ??? ??? ?} else if (pt.y > bounds.y + 2 * bounds.height / 3) {
?? ??? ??? ??? ??? ??? ?event.feedback |= DND.FEEDBACK_INSERT_AFTER;
?? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ?event.feedback |= DND.FEEDBACK_SELECT;
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?public void drop(DropTargetEvent event) {
?? ??? ??? ??? ?if (event.data == null) {
?? ??? ??? ??? ??? ?event.detail = DND.DROP_NONE;
?? ??? ??? ??? ??? ?return;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?if (event.item == null) {
?? ??? ??? ??? ??? ?TreeItem item = new TreeItem(tree, SWT.NONE);
?? ??? ??? ??? ??? ?item = initTreeItem(dragSourceItem[0], item);
?? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ?TreeItem item = (TreeItem) event.item;
?? ??? ??? ??? ??? ?Point pt = shell.getDisplay().map(null, tree, event.x,
?? ??? ??? ??? ??? ??? ??? ?event.y);
?? ??? ??? ??? ??? ?Rectangle bounds = item.getBounds();
?? ??? ??? ??? ??? ?TreeItem parent = item.getParentItem();
?? ??? ??? ??? ??? ?if (parent != null) {
?? ??? ??? ??? ??? ??? ?TreeItem[] items = parent.getItems();
?? ??? ??? ??? ??? ??? ?int index = 0;
?? ??? ??? ??? ??? ??? ?for (int i = 0; i < items.length; i++) {
?? ??? ??? ??? ??? ??? ??? ?if (items[i] == item) {
?? ??? ??? ??? ??? ??? ??? ??? ?index = i;
?? ??? ??? ??? ??? ??? ??? ??? ?break;
?? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?if (pt.y < bounds.y + bounds.height / 3) {
?? ??? ??? ??? ??? ??? ??? ?TreeItem newItem = new TreeItem(parent, SWT.NONE,
?? ??? ??? ??? ??? ??? ??? ??? ??? ?index);
?? ??? ??? ??? ??? ??? ??? ?newItem = initTreeItem(dragSourceItem[0], newItem);
?? ??? ??? ??? ??? ??? ?} else if (pt.y > bounds.y + 2 * bounds.height / 3) {
?? ??? ??? ??? ??? ??? ??? ?TreeItem newItem = new TreeItem(parent, SWT.NONE,
?? ??? ??? ??? ??? ??? ??? ??? ??? ?index + 1);
?? ??? ??? ??? ??? ??? ??? ?newItem = initTreeItem(dragSourceItem[0], newItem);
?? ??? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ??? ?TreeItem newItem = new TreeItem(item, SWT.NONE);
?? ??? ??? ??? ??? ??? ??? ?newItem = initTreeItem(dragSourceItem[0], newItem);
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ?TreeItem[] items = tree.getItems();
?? ??? ??? ??? ??? ??? ?int index = 0;
?? ??? ??? ??? ??? ??? ?for (int i = 0; i < items.length; i++) {
?? ??? ??? ??? ??? ??? ??? ?if (items[i] == item) {
?? ??? ??? ??? ??? ??? ??? ??? ?index = i;
?? ??? ??? ??? ??? ??? ??? ??? ?break;
?? ??? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?if (pt.y < bounds.y + bounds.height / 3) {
?? ??? ??? ??? ??? ??? ??? ?TreeItem newItem = new TreeItem(tree, SWT.NONE,
?? ??? ??? ??? ??? ??? ??? ??? ??? ?index);
?? ??? ??? ??? ??? ??? ??? ?newItem = initTreeItem(dragSourceItem[0], newItem);
?? ??? ??? ??? ??? ??? ?} else if (pt.y > bounds.y + 2 * bounds.height / 3) {
?? ??? ??? ??? ??? ??? ??? ?TreeItem newItem = new TreeItem(tree, SWT.NONE,
?? ??? ??? ??? ??? ??? ??? ??? ??? ?index + 1);
?? ??? ??? ??? ??? ??? ??? ?newItem = initTreeItem(dragSourceItem[0], newItem);
?? ??? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ??? ?TreeItem newItem = new TreeItem(item, SWT.NONE);
?? ??? ??? ??? ??? ??? ??? ?newItem = initTreeItem(dragSourceItem[0], newItem);
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ??? ?tree.redraw();
?? ??? ??? ?}
?? ??? ?});
?? ?}