問題一:我聲明了什么!
String s = "Hello world!";
許多人都做過這樣的事情,但是,我們到底聲明了什么?回答通常是:一個String,內容是“Hello world!”。這樣模糊的回答通常是概念不清的根源。如果要準確的回答,一半的人大概會回答錯誤。
這個語句聲明的是一個指向對象的引用,名為“s”,可以指向類型為String的任何對象,目前指向"Hello world!"這個String類型的對象。這就是真正發生的事情。我們并沒有聲明一個String對象,我們只是聲明了一個只能指向String對象的引用變量。所以,如果在剛才那句語句后面,如果再運行一句:
String string = s;
我們是聲明了另外一個只能指向String對象的引用,名為string,并沒有第二個對象產生,string還是指向原來那個對象,也就是,和s指向同一個對象。
問題二:"=="和equals方法究竟有什么區別?
==操作符專門用來比較變量的值是否相等。比較好理解的一點是:
int a=10;
int b=10;
則a==b將是true。
但不好理解的地方是:
String a=new String("foo");
String b=new String("foo");
則a==b將返回false。
根據前一帖說過,對象變量其實是一個引用,它們的值是指向對象所在的內存地址,而不是對象本身。a和b都使用了new操作符,意味著將在內存中產生兩個內容為"foo"的字符串,既然是“兩個”,它們自然位于不同的內存地址。a和b的值其實是兩個不同的內存地址的值,所以使用"=="操作符,結果會是false。誠然,a和b所指的對象,它們的內容都是"foo",應該是“相等”,但是==操作符并不涉及到對象內容的比較。
對象內容的比較,正是equals方法做的事。
看一下Object對象的equals方法是如何實現的:
boolean equals(Object o){
return this==o;
}
Object對象默認使用了==操作符。所以如果你自創的類沒有覆蓋equals方法,那你的類使用equals和使用==會得到同樣的結果。同樣也可以看出,Object的equals方法沒有達到equals方法應該達到的目標:比較兩個對象內容是否相等。因為答案應該由類的創建者決定,所以Object把這個任務留給了類的創建者。
看一下一個極端的類:
Class Monster{
private String content;
...
boolean equals(Object another){ return true;}
}
我覆蓋了equals方法。這個實現會導致無論Monster實例內容如何,它們之間的比較永遠返回true。
所以當你是用equals方法判斷對象的內容是否相等,請不要想當然。因為可能你認為相等,而這個類的作者不這樣認為,而類的equals方法的實現是由他掌握的。如果你需要使用equals方法,或者使用任何基于散列碼的集合(HashSet,HashMap,HashTable),請察看一下java doc以確認這個類的equals邏輯是如何實現的。
問題三:String到底變了沒有?
沒有。因為String被設計成不可變(immutable)類,所以它的所有對象都是不可變對象。請看下列代碼:
String s = "Hello";
s = s + " world!";
s所指向的對象是否改變了呢?從本系列第一篇的結論很容易導出這個結論。我們來看看發生了什么事情。在這段代碼中,s原先指向一個String對象,內容是"Hello",然后我們對s進行了+操作,那么s所指向的那個對象是否發生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另一個String對象,內容為"Hello world!",原來那個對象還存在于內存之中,只是s這個引用變量不再指向它了。
通過上面的說明,我們很容易導出另一個結論,如果經常對字符串進行各種各樣的修改,或者說,不可預見的修改,那么使用String來代表字符串的話會引起很大的內存開銷。因為String對象建立之后不能再改變,所以對于每一個不同的字符串,都需要一個String對象來表示。這時,應該考慮使用StringBuffer類,它允許修改,而不是每個不同的字符串都要生成一個新的對象。并且,這兩種類的對象轉換十分容易。
同時,我們還可以知道,如果要使用內容相同的字符串,不必每次都new一個String。例如我們要在構造器中對一個名叫s的String引用變量進行初始化,把它設置為初始值,應當這樣做:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
后者每次都會調用構造器,生成新對象,性能低下且內存開銷大,并且沒有意義,因為String對象不可改變,所以對于內容相同的字符串,只要一個String對象來表示就可以了。也就說,多次調用上面的構造器創建多個對象,他們的String類型屬性s都指向同一個對象。
上面的結論還基于這樣一個事實:對于字符串常量,如果內容相同,Java認為它們代表同一個String對象。而用關鍵字new調用構造器,總是會創建一個新的對象,無論內容是否相同。
至于為什么要把String類設計成不可變類,是它的用途決定的。其實不只String,很多Java標準類庫中的類都是不可變的。在開發一個系統的時候,我們有時候也需要設計不可變類,來傳遞一組相關的值,這也是面向對象思想的體現。不可變類有一些優點,比如因為它的對象是只讀的,所以多線程并發訪問也不會有任何問題。當然也有一些缺點,比如每個不同的狀態都要一個對象來代表,可能會造成性能上的問題。所以Java標準類庫還提供了一個可變版本,即StringBuffer。
問題四:final關鍵字到底修飾了什么?
final使得被修飾的變量"不變",但是由于對象型變量的本質是“引用”,使得“不變”也有了兩種含義:引用本身的不變,和引用指向的對象不變。
引用本身的不變:
final StringBuffer a=new StringBuffer("immutable");
final StringBuffer b=new StringBuffer("not immutable");
a=b;//編譯期錯誤
引用指向的對象不變:
final StringBuffer a=new StringBuffer("immutable");
a.append(" broken!"); //編譯通過
可見,final只對引用的“值”(也即它所指向的那個對象的內存地址)有效,它迫使引用只能指向初始指向的那個對象,改變它的指向會導致編譯期錯誤。至于它所指向的對象的變化,final是不負責的。這很類似==操作符:==操作符只負責引用的“值”相等,至于這個地址所指向的對象內容是否相等,==操作符是不管的。
理解final問題有很重要的含義。許多程序漏洞都基于此----final只能保證引用永遠指向固定對象,不能保證那個對象的狀態不變。在多線程的操作中,一個對象會被多個線程共享或修改,一個線程對對象無意識的修改可能會導致另一個使用此對象的線程崩潰。一個錯誤的解決方法就是在此對象新建的時候把它聲明為final,意圖使得它“永遠不變”。其實那是徒勞的。
問題五:到底要怎么樣初始化!
本問題討論變量的初始化,所以先來看一下Java中有哪些種類的變量。
1. 類的屬性,或者叫值域
2. 方法里的局部變量
3. 方法的參數
對于第一種變量,Java虛擬機會自動進行初始化。如果給出了初始值,則初始化為該初始值。如果沒有給出,則把它初始化為該類型變量的默認初始值。
int類型變量默認初始值為0
float類型變量默認初始值為0.0f
double類型變量默認初始值為0.0
boolean類型變量默認初始值為false
char類型變量默認初始值為0(ASCII碼)
long類型變量默認初始值為0
所有對象引用類型變量默認初始值為null,即不指向任何對象。注意數組本身也是對象,所以沒有初始化的數組引用在自動初始化后其值也是null。
對于兩種不同的類屬性,static屬性與instance屬性,初始化的時機是不同的。instance屬性在創建實例的時候初始化,static屬性在類加載,也就是第一次用到這個類的時候初始化,對于后來的實例的創建,不再次進行初始化。這個問題會在以后的系列中進行詳細討論。
對于第二種變量,必須明確地進行初始化。如果再沒有初始化之前就試圖使用它,編譯器會抗議。如果初始化的語句在try塊中或if塊中,也必須要讓它在第一次使用前一定能夠得到賦值。也就是說,把初始化語句放在只有if塊的條件判斷語句中編譯器也會抗議,因為執行的時候可能不符合if后面的判斷條件,如此一來初始化語句就不會被執行了,這就違反了局部變量使用前必須初始化的規定。但如果在else塊中也有初始化語句,就可以通過編譯,因為無論如何,總有至少一條初始化語句會被執行,不會發生使用前未被初始化的事情。對于try-catch也是一樣,如果只有在try塊里才有初始化語句,編譯部通過。如果在catch或finally里也有,則可以通過編譯。總之,要保證局部變量在使用之前一定被初始化了。所以,一個好的做法是在聲明他們的時候就初始化他們,如果不知道要出事化成什么值好,就用上面的默認值吧!
其實第三種變量和第二種本質上是一樣的,都是方法中的局部變量。只不過作為參數,肯定是被初始化過的,傳入的值就是初始值,所以不需要初始化。
問題六:instance of是什么東東?
instance of是Java的一個二元操作符,和==,>,<是同一類東東。由于它是由字母組成的,所以也是Java的保留關鍵字。它的作用是測試它左邊的對象是否是它右邊的類的實例,返回boolean類型的數據。舉個例子:
String s = "I AM an Object!";
boolean is Object = s instance of Object;
我們聲明了一個String對象引用,指向一個String對象,然后用instanc of來測試它所指向的對象是否是Object類的一個實例,顯然,這是真的,所以返回true,也就是isObject的值為True。
instance of有一些用處。比如我們寫了一個處理賬單的系統,其中有這樣三個類:
public class Bill {//省略細節}
public class PhoneBill extends Bill {//省略細節}
public class GasBill extends Bill {//省略細節}
在處理程序里有一個方法,接受一個Bill類型的對象,計算金額。假設兩種賬單計算方法不同,而傳入的Bill對象可能是兩種中的任何一種,所以要用instanceof來判斷:
public double calculate(Bill bill) {
if (bill instanceof PhoneBill) {
//計算電話賬單
}
if (bill instanceof GasBill) {
//計算燃氣賬單
}
...
}
這樣就可以用一個方法處理兩種子類。
然而,這種做法通常被認為是沒有好好利用面向對象中的多態性。其實上面的功能要求用方法重載完全可以實現,這是面向對象變成應有的做法,避免回到結構化編程模式。只要提供兩個名字和返回值都相同,接受參數類型不同的方法就可以了:
public double calculate(PhoneBill bill) {
//計算電話賬單
}
public double calculate(GasBill bill) {
//計算燃氣賬單
}
所以,使用instanceof在絕大多數情況下并不是推薦的做法,應當好好利用多態。
posted @
2007-06-02 20:02 CHUANDAOJUN|
編輯 收藏
1 針對性
文檔編制以前應分清讀者對象,按不同的類型、不同層次的讀者,決定怎樣適應他們的需要。
① 對于面向管理人員和用戶的文檔,不應像開發文檔(面向軟件開發人員)那樣過多地使用軟件的專業術語。 難以避免使用的詞匯,應在文檔中添加詞匯表,進行解釋。
② 開發文檔使用的專業詞匯未被廣泛認知的,應添加注釋進行說明。
③ 縮寫詞未被廣泛認知的,應在其后跟上完整的拼寫。
2 正確性
① 沒有錯字,漏字。
② 文檔間引用關系正確。
③ 文檔細節(Title/History)正確。
3 準確性
① 意思表達準確清晰,沒有二義性。
② 正確使用標點符號,避免產生歧義。
4 完整性
① 意思表達完整,能找到主語、謂語、賓語,沒有省略主語,特別是謂語。
② 一句話中不能出現幾個動詞一個賓語的現象。
③ 不遺漏要求和必需的信息。
5 簡潔性
① 盡量不要采用較長的句子來描述,無法避免時,應注意使用正確的標點符號。
② 簡潔明了,不累贅冗余,每個意思只在文檔中表達一次。
③ 每個陳述語句,只表達一個意思。
④ 力求簡明,如有可能,配以適當的圖表,以增強其清晰性。
6 統一性
① 統一采用專業術語和項目規定的術語集。
② 同一個意思和名稱,前后描述的用語要一致。
③ 文檔前后使用的字體要統一。
④ 同一課題若干文檔內容應該協調一致,沒有矛盾。
7 易讀性
① 文字描述要通俗易懂。
② 前后文關聯詞使用恰當。
③ 文檔變更內容用其他顏色與上個版本區別開來。
④ 測試步驟要采用列表的方式,用1)、2)、3)…等數字序號標注。
posted @
2007-05-27 08:21 CHUANDAOJUN 閱讀(886) |
評論 (0) |
編輯 收藏
RMI,遠程方法調用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java應用程序的方便途徑。RMI是非常容易使用的,但是它非常的強大。
RMI的基礎是接口,RMI構架基于一個重要的原理:定義接口和定義接口的具體實現是分開的。下面我們通過具體的例子,建立一個簡單的遠程計算服務和使用它的客戶程序
一個正常工作的RMI系統由下面幾個部分組成:
遠程服務的接口定義
遠程服務接口的具體實現
Stub 和 Skeleton 文件
一個運行遠程服務的服務器
一個RMI命名服務,它允許客戶端去發現這個遠程服務
類文件的提供者(一個HTTP或者FTP服務器)
一個需要這個遠程服務的客戶端程序
下面我們一步一步建立一個簡單的RMI系統。首先在你的機器里建立一個新的文件夾,以便放置我們創建的文件,為了簡單起見,我們只使用一個文件夾存放客戶端和服務端代碼,并且在同一個目錄下運行服務端和客戶端。
如果所有的RMI文件都已經設計好了,那么你需要下面的幾個步驟去生成你的系統:
1、 編寫并且編譯接口的Java代碼
2、 編寫并且編譯接口實現的Java代碼
3、 從接口實現類中生成 Stub 和 Skeleton 類文件
4、 編寫遠程服務的主運行程序
5、 編寫RMI的客戶端程序
6、 安裝并且運行RMI系統
我的程序是在NetBeans IDE 5.5和JDK1.6下編寫的,當然運行是在命令提示符下進行的
1、接口
第一步就是建立和編譯服務接口的Java代碼。這個接口定義了所有的提供遠程服務的功能,在這里我們所有完成的就是加減乘除,下面是源程序:
- package rmiDemo;
- //Calculator.java
- //define the interface
- import java.rmi.Remote;
-
- public interface Calculator extends Remote
- {
- public long add(long a, long b)
- throws java.rmi.RemoteException;
-
- public long sub(long a, long b)
- throws java.rmi.RemoteException;
-
- public long mul(long a, long b)
- throws java.rmi.RemoteException;
-
- public long div(long a, long b)
- throws java.rmi.RemoteException;
- }
注意:這個接口繼承自Remote,每一個定義的方法都必須拋出一個RemoteException異常對象。
建立這個文件,把它存放在剛才的目錄下,并且編譯。
2、接口的具體實現
下一步,我們就要寫遠程服務的具體實現,這是一個CalculatorImpl類文件:
- package rmiDemo;
- //CalculatorImpl.java
- //Implementation
- import java.rmi.server.UnicastRemoteObject;
-
- public class CalculatorImpl extends UnicastRemoteObject implements Calculator
- {
-
- // 這個實現必須有一個顯式的構造函數,并且要拋出一個RemoteException異常
- public CalculatorImpl()
- throws java.rmi.RemoteException {
- super();
- }
-
- public long add(long a, long b)
- throws java.rmi.RemoteException {
- return a + b;
- }
-
- public long sub(long a, long b)
- throws java.rmi.RemoteException {
- return a - b;
- }
-
- public long mul(long a, long b)
- throws java.rmi.RemoteException {
- return a * b;
- }
-
- public long div(long a, long b)
- throws java.rmi.RemoteException {
- return a / b;
- }
- }
這個實現類使用了UnicastRemoteObject去聯接RMI系統。在我們的例子中,我們是直接的從UnicastRemoteObject這個類上繼承的,事實上并不一定要這樣做,如果一個類不是從UnicastRmeoteObject上繼承,那必須使用它的exportObject()方法去聯接到RMI。
如果一個類繼承自UnicastRemoteObject,那么它必須提供一個構造函數并且聲明拋出一個RemoteException對象。當這個構造函數調用了super(),它久激活UnicastRemoteObject中的代碼完成RMI的連接和遠程對象的初始化。
3、Stubs 和Skeletons
下一步就是要使用RMI編譯器rmic來生成樁和框架文件,這個編譯運行在遠程服務實現類文件上。
在IDE中build所有程序
>rmic rmiDemoCalculatorImpl
在你的目錄下運行上面的命令,成功執行完上面的命令你可以發現一個Calculator_stub.class文件,如果你是使用的Java2SDK,那么你還可以發現Calculator_Skel.class文件。
4、主機服務器
遠程RMI服務必須是在一個服務器中運行的。CalculatorServer類是一個非常簡單的服務器。
- package rmiDemo;
- //CalculatorServer.java
- import java.rmi.Naming;
-
- public class CalculatorServer {
-
- public CalculatorServer() {
- try {
- Calculator c = new CalculatorImpl();
- Naming.rebind("rmi://localhost:1099/CalculatorService", c);
- } catch (Exception e) {
- System.out.println("Trouble: " + e);
- }
- }
-
- public static void main(String args[]) {
- new CalculatorServer();
- }
- }
5、客戶端
客戶端源代碼如下:
- package rmiDemo;
- //CalculatorClient.java
-
- import java.rmi.Naming;
- import java.rmi.RemoteException;
- import java.net.MalformedURLException;
- import java.rmi.NotBoundException;
-
- public class CalculatorClient {
-
- public static void main(String[] args) {
- try {
- Calculator c = (Calculator)
- Naming.lookup(
- "rmi://localhost
- /CalculatorService");
- System.out.println( c.sub(4, 3) );
- System.out.println( c.add(4, 5) );
- System.out.println( c.mul(3, 6) );
- System.out.println( c.div(9, 3) );
- }
- catch (MalformedURLException murle) {
- System.out.println();
- System.out.println(
- "MalformedURLException");
- System.out.println(murle);
- }
- catch (RemoteException re) {
- System.out.println();
- System.out.println(
- "RemoteException");
- System.out.println(re);
- }
- catch (NotBoundException nbe) {
- System.out.println();
- System.out.println(
- "NotBoundException");
- System.out.println(nbe);
- }
- catch (
- java.lang.ArithmeticException
- ae) {
- System.out.println();
- System.out.println(
- "java.lang.ArithmeticException");
- System.out.println(ae);
- }
- }
- }
保存這個客戶端程序到你的目錄下(注意這個目錄是一開始建立那個,所有的我們的文件都在那個目錄下)。
在IDE中build所有程序。
6、運行RMI系統
現在我們建立了所有運行這個簡單RMI系統所需的文件,現在我們終于可以運行這個RMI系統啦!來享受吧。
我們是在命令控制臺下運行這個系統的,你必須開啟三個控制臺窗口,一個運行服務器,一個運行客戶端,還有一個運行RMIRegistry。
首先運行注冊程序RMIRegistry,你必須在包含你剛寫的類的那么目錄下運行這個注冊程序。
>rmiregistry
好,這個命令成功的話,注冊程序已經開始運行了,不要管他,現在切換到另外一個控制臺,在第二個控制臺里,我們運行服務器CalculatorService,因為RMI的安全機制將在服務端發生作用,所以你必須增加一條安全策略。以下是對應安全策略的例子
grant {
permission java.security.AllPermission "", "";
};
注意:這是一條最簡單的安全策略,它允許任何人做任何事,對于你的更加關鍵性的應用,你必須指定更加詳細安全策略。
現在為了運行服務端,你需要除客戶類(CalculatorClient.class)之外的所有的類文件。確認安全策略在policy.txt文件之后,使用如下命令來運行服務器。
> java -Djava.security.policy=C:\Documents and Settings\Administrator\RMI\build\classes\ rmiDemo.CalculatorServer
這個服務器就開始工作了,把接口的實現加載到內存等待客戶端的聯接。好現在切換到第三個控制臺,啟動我們的客戶端。
為了在其他的機器運行客戶端程序你需要一個遠程接口(Calculator.class) 和一個stub(CalculatorImpl_Stub.class)。 使用如下命令運行客戶端
> java -Djava.security.policy=C:\Documents and Settings\Administrator\RMI\build\classes\ rmiDemo. CalculatorClient
如果所有的這些都成功運行,你應該看到下面的輸出:
1
9
18
3
posted @
2007-05-22 20:08 CHUANDAOJUN 閱讀(6545) |
評論 (2) |
編輯 收藏
(當前地址是:
http://localhost:8080/foo/stuff.html)
重定向: URL地址不是以“/”開頭:
response.sendRedirect(
http://www.google.com);
現在的地址是:
http://www.google.com
URL地址是以“/”開頭:
response.sendRedirect(/
http://www.google.com);
現在的地址是:
http://localhost:8080/http://www.google.com(當讓這樣的地址你會看到一個404錯誤,在這我只是為了理解更方便一點)
總結:從上面的內容我們看到,
通過sendRedirect后url 的地址發生了變化, 我們通常叫他客戶端跳轉。
請求分派:RequestDispatcher有兩種方法得到:
1、request.getRequestDispatcher("/result.jsp");或request.getRequestDispatcher("result.jsp");
如果是由request引導的,那么“/”可有可無
2、getServletContext().getRequestDispatcher("/result.jsp");
如果是由getServletContext()引導的,那么必須讓“/”開頭
總結:嘗試后,你會發現,通過getRequestDispatcher后url 的地址沒有發生變化, 我們通常叫他服務器端跳轉。
另外再多嘴一句:ServletContext 接口下有一個getNamedDispatcher("name");name是Servlet或jsp的名字而不是路徑(需要在web.xml中定義他們的路徑)是為了以后修改方便
posted @
2007-05-21 21:21 CHUANDAOJUN 閱讀(430) |
評論 (0) |
編輯 收藏
提交頁面demo.htm
<html>
<body>
<form action="demo.jsp" method="post">
用戶名:<input type="text" name="uname"><br>
密碼:<input type="password" name="upass"><br>
興趣:
<input type="checkbox" name="**inst" value="籃球">籃球
<input type="checkbox" name="**inst" value="游泳">游泳
<input type="checkbox" name="**inst" value="唱歌">唱歌
<input type="checkbox" name="**inst" value="跳舞">跳舞
<input type="checkbox" name="**inst" value="看書">看書
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
數據處理頁面demo.jsp(精華部分)
<%@ page contentType="text/html;charset=gbk"%>
<%@ page import="java.util.*"%>
<html>
<body>
<%
// 接收內容
request.setCharacterEncoding("GBK") ;
Enumeration enu = request.getParameterNames() ;
%>
<%=request.getMethod()%>
<%
while(enu.hasMoreElements())
{
String name = (String)enu.nextElement() ;
if(name.startsWith("**"))
{
String temp[] = request.getParameterValues(name) ;
%>
<h1><%=new StringBuffer(name).replace(0,2,"")%> -->
<%
for(int i=0;i<temp.length;i++)
{
%>
<%=temp[i]%>、
<%
}
%>
</h1>
<%
}
else
{
%>
<h1><%=name%> --> <%=request.getParameter(name)%></h1>
<%
}
}
%>
</h1>
</body>
</html>
posted @
2007-05-21 20:21 CHUANDAOJUN 閱讀(234) |
評論 (0) |
編輯 收藏
摘要: 以上內容,如有問題和不妥的地方請給與評論
大家一起相互學習
閱讀全文
posted @
2007-05-18 23:52 CHUANDAOJUN 閱讀(636) |
評論 (0) |
編輯 收藏
<jsp:param name="" value=""/>定義一個屬性 通常與<jsp:include>、<jsp:forward>和<jsp:plugin>一起使用
<jsp:include page="" flush="True"/>把另一個網頁導入到當前網頁
<%@include%>與 <jsp:include>的區別?
如果,被包含的頁面是靜態的<%@include%>先將其導入,如頁面中有jsp代碼,導入后處理;<jsp:include>則是把其導入不做任何處理,直接顯示。
如果,被包含的頁面是動態的<%@include%>先將其導入,讓后處理;<jsp:include>則是先處理讓后導入。
在<jsp:include page="" flush="True"/>中我們還可以通過<jsp:param name="" value="">給被包含頁面傳值,格式如下:
<jsp:include page="" flush="True">
<jsp:param name="" value=""/>
<jsp:param name="" value=""/>
.
.
.
<jsp:param name="" value=""/>
</jsp:include>
<jsp:forward page=""/>頁面內容轉向目標頁面,url內容還是保持原頁面的狀況(屬于服務器端跳轉)
在<jsp:forward page="">中我們還可以通過<jsp:param name="" value="">給被指向頁面傳值,格式如下:
<jsp:forward page="" flush="True">
<jsp:param name="" value="">
<jsp:param name="" value="">
.
.
.
<jsp:param name="" value="">
</jsp:forward>
posted @
2007-05-18 14:29 CHUANDAOJUN 閱讀(1053) |
評論 (0) |
編輯 收藏
a、 page(有屬性import、session、contentType和isELgnored)
b、include
c、taglib
具體格式如下:
<
%@page import="" session= "" contentType = "" isELgnored= ""%>
<
%@include file= ""%>
<
%@taglib>
posted @
2007-05-18 13:30 CHUANDAOJUN|
編輯 收藏
以下配置環境是SQL Server 2000、Tomcat5.0.28
1、把msbase.jar、sqlserver.jar、msutil.jar三個文件拷貝到%TOMMCAT_HOME%\common\lib 目錄下
2、在webapp下新建一個文檔,再在%TOMCAT_HOME%\conf\Catalina\localhost\ 新建一個與webapp下文檔名相同的.xml
3、把一下文件拷貝到上面新建的.xml中(注:也可以把以下內容拷貝到%TOMCAT_HOME%\conf、servlet.xml中,第2步新建.xml就可以省略[不過有個弊端參閱:5])
<?xml version="1.0" encoding="GB2312"?>
<Context path="/(webapp下新建的文檔)">
<Logger className="org.apache.catalina.logger.FileLogger"prefix="localhost_admin_log." suffix=".txt" timestamp="true"/>
<Resource type="javax.sql.DataSource" auth="Container" name="(數據源名字)"/>
<ResourceParams name="(數據源名字)"/>
<parameter>
<name>maxWait</name> //最大等待時間
<value>5000</value>
</parameter>
<parameter>
<name>maxActive</name>//最大連接數:達到這個數字時候 就不要在連接
<value>4</value>
</parameter>
<parameter>
<name>maxIdle</name> ///最大的維持數:如果沒有用戶連接時候 連接池中保持 這么多個連接
<value>2</value>
</parameter>
<parameter>
<name>username</name>
<value>sa</value>
</parameter>
<parameter>
<name>password</name>
<value></value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:microsoft:sqlserver://localhost:1433;databaseName=(數據庫名)</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</parameter>
</ResourceParams>
</Context>
4、如果你在Eclipse或JBuilder 中開發的話,你需要在你的Web應用程序的WEB- INF\Web.xml文件中注冊數據源,文件添加如下內容:
<resource-ref>
<res-ref-name>jdbc/northwind</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
5、忠告在做任何配置時最好不要修改Tomcat服務器的任何文件,如servel.xml或web.xml文件,而所有的操作和配置都可以在你自己的應用配置文件中來完成,這樣即使培植錯誤也不至于服務器的崩潰。
6、撰寫測試文檔
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
<%!
final String JNDINAME="java:comp/env/(數據源名字)"
%>
<%
Connection conn =null;
try
{
//初始化查找命名空間
Context ctx = new InitialContext();
//找到DataSourse
DataSource ds = (DataSourse)ctx.lookup(數據庫名);
conn = ds.getConnection();
}
catch(Exception e){
System.out.println(e);
}
%>
備注:在Tomcat 5.5.xx中使用以前的配置方式,會出現以下問題:“Cannot create JDBC driver of class '' for connect URL 'null'”。
解決方法是,把如下格式的Resource描述插入server.xml 的<Context></Context>中:
<Resource name="jdbc/db" type="javax.sql.DataSource" username="sa" password=""
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
maxIdle="2"maxWait="5000" url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=jspdev" maxActive="4"/>
用以取代以上的配置方式。
在Tomcat中配置數據源很復雜 但在weblogic和websphere中 會給出特定的界面 給你配置 比較方便
posted @
2007-05-15 13:39 CHUANDAOJUN 閱讀(905) |
評論 (0) |
編輯 收藏
方法一: 啟動服務
安裝后在windows的服務選項中,選中mysql的服務,然后雙擊啟動即可。。。。具體操作(右擊我的電腦->管理->彈出計算機管理,選服務和應用程序->服務->MYSQL4->雙擊啟動即可。)
方法二: 命令行操作
開始->運行->cmd 打開DOS窗口,在窗口中輸入net start mysql 即啟動了mysql .
方法三:使用winmysqladmin
1)、進入d::\mysql\bin目錄,運行winmysqladmin.exe,在屏幕右下角的任務欄內會有一個帶紅色的圖符
2)、鼠標左鍵點擊該圖符,選擇“show me”,出現“WinMySQLAdmin”操作界面;首次運行時會中間會出現一個對話框要求輸入并設置你的用戶名和口令
3)、選擇“My.INI setup”
4)、在“mysqld file”中選擇“mysqld-opt”(win9x)或“mysqld-nt”(winNT)
5)、選擇“Pick-up or Edit my.ini values”可以在右邊窗口內對你的my.ini文件進行編輯
6)、選擇“Save Modification”保存你的my.ini文件
7)、如果你想快速使用winmysqladmin(開機時自動運行),選擇“Create ShortCut on Start Menu”
8)、測試:
進入DOS界面;
在d:\mysql\bin目錄下運行mysql,進入mysql交互操作界面
輸入show databases并回車,屏幕顯示出當前已有的兩個數據庫mysql和test
方法四:不使用winmysqladmin
1)、在DOS窗口下,進入d:/mysql/bin目錄
2)、win9X下)運行:
mysqld
在NT下運行:
mysqld-nt --standalone
3)、此后,mysql在后臺運行
4)、測試mysql:(在d:/mysql/bin目錄下)
a)、mysqlshow
正常時顯示已有的兩個數據庫mysql和test
b)、mysqlshow -u root mysql
正常時顯示數據庫mysql里的五個表:
columns_priv
db
host
tables_priv
user
c)、mysqladmin version status proc
顯示版本號、狀態、進程信息等
d)、mysql test
進入mysql操作界面,當前數據庫為test
5)、mysql關閉方法:
mysqladmin -u root shutdown
posted @
2007-05-15 13:32 CHUANDAOJUN|
編輯 收藏