2009年4月24日 星期五

在Ubuntu打造Tomcat+Apache+Mysql WEB服務器

1.默認安裝好ubuntu8.04 TLS Server版本(此版本支持到2013年04月)

2.安裝ssh
#sudo apt-get install ssh

3.安裝vsftpd
#sudo apt-get install vsftp
設置/etc/vsftpd.conf,由於不需要對外開放FTP,只是內網訪問,相關設置如下.
#拒絕匿名用戶,將其註釋掉
#anonymous_enable=YES
#接受本地用戶
local_enable=YES
#可以上傳
write_enable=YES
#允許上傳Ascii文件
ascii_upload_enable=YES
ascii_download_enable=YES
啟動vsftpd
/etc/init.d vsftpd start

4.安裝JDK5
apt-get install sun-java5-jdk
通過apt得安裝JAVA環境自動會設置好.

5.安裝TOMCAT6.018
自己去Tomcat官網下載好,通過FTP傳上去
解壓
tar zxvf apache-tomcat-6.0.18.tar.gz
複製到/usr/lib下面
#sudo cp /home/kejun/upload/apache-tomcat-6.0.18 /usr/lib/apache-tomcat-6.0.18

6.安裝Apache2
sudo apt-get install apache2
通過apt安裝的,apache的目錄會有很多不同,這裡安裝完後並沒有改動其中的配置文件.

7.安裝JK(用於整合Tomcat和Apache)
#sudo apt-get install libapache2-mod-jk
查看一下在apache2的啟動模塊中是否有jk.load
#sudo ls /etc/apache2/mods-enabled/
配置workers.properties
#sudo vi /etc/libapache2-mod-jk/workers.properties
將下面兩項改為自己的目錄
workers.tomcat_home=/usr/lib/apache-tomcat-6.0.18
workers.java_home=/usr/lib/jvm/java-1.5.0-sun
接下來配置在apache2.conf
#sudo vi /usr/share/doc/libapache2-mod-jk/httpd_example_apache2.conf
複製裡面的內容到apache2.conf
增加監聽端口8081
#sudo vi /etc/apache2/ports.conf
增加一行
Listen 8081
修改虛擬主機
#sudo vi /etc/apache2/sites-available/default
根據自己設置,以下是我的設置
NameVirtualHost *:80
NameVirtualHost *:8081

ServerAdmin webmaster@localhost

DocumentRoot /var/www/

Options FollowSymLinks
AllowOverride None


Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all

ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog /var/log/apache2/access.log combined
ServerSignature On

Alias /doc/ "/usr/share/doc/"

Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128





ServerAdmin webmaster@localhost
DocumentRoot /usr/lib/apache-tomcat-6.0.18/webapps/idealshop
ErrorLog /var/log/apache2/idealerror.log
LogLevel warn
CustomLog /var/log/apache2/idealaccess.log combined

Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all


在tomcat的conf文件下增加文件jk2.properties
內容如下
handler.list=channelSocket,request
channelSocket.port=8009

8.安裝Mysql5
apt-get install mysql5
在Ubuntu下MySQL缺省是只允許本地訪問的,如果你要其他機器也能遠程夠訪問這台Mysql數據庫的話,需要做些設置

配置文件的修改
#sudo vi /etc/mysql/my.conf
找到 bind-address = 127.0.0.1 註釋掉這句話
Mysql數據庫的修改
1)[root@etc etc]# mysql -uroot -p
Enter password:
2)mysql> use mysql;
3)mysql> select host,user,password from user;
4)mysql>grant all privileges on *.* to root@192.168.15.101 identified by 'password'
(1)192.168.15.101是欲連接到此Mysql數據庫的客戶端的IP地址,而不是Mysql數據庫所在數據庫服務器的IP地址,
切記.
(2)password就是Mysql數據庫root用戶的password,根據實際情況需要修改
如果要在任何主機地址都可登陸mysql數據庫的話,那麼把地址換成」%」即可。
mysql> grant all privileges on *.* to root@」%」 identified by 'password'

9.一切OK,啟動服務
啟動mysql
sudo /etc/init.d mysql start
啟動tomcat
sudo /usr/lib/apache-tomcat-6.0.18/bin/./startup.sh
啟動apache
sudo /etc/init.d apache2 start

一個簡單的tomcat+apache+mysql的服務器就起來了,其中詳細設置還需要根據自己的情況進行設置.

Ubuntu定時備份Mysql

1.cron介紹

cron是系統主要的調度進程,可以在無需人工干預的情況下運行作業。有一個叫做crontab的命令允許用戶提交、編輯或刪除相應的作業。下面是crontab的格式:
分< >時< >日< >月< >星期< >要運行的命令

crontab命令的一般形式為:
crontab[-u user] -e -l -r
其中:
-u 用戶名。
-e 編輯crontab文件。
-l 列出crontab文件中的內容。
-r 刪除crontab文件。

2.mysqldump介紹

--add-drop-table
這個選項將會在每一個表的前面加上DROP TABLE IF EXISTS語句,這樣可以保證導回MySQL數據庫的時候不會出錯,因為每次導回的時候,都會首先檢查表是否存在,存在就刪除。

--add-locks
這個選項會在INSERT語句中捆上一個LOCK TABLE和UNLOCK TABLE語句。這就防止在這些記錄被再次導入數據庫時其他用戶對表進行的操作

-c
這個選項使得mysqldump命令給每一個產生INSERT語句加上列(field)的名字。當把數據導出導另外一個數據庫時這個選項很有用。

--delayed-insert
在INSERT命令中加入DELAY選項

-F
使用這個選項,在執行導出之前將會刷新MySQL服務器的log.

-f
使用這個選項,即使有錯誤發生,仍然繼續導出

-l
使用這個選項,導出表的時候服務器將會給表加鎖。

-t
這個選項使的mysqldump命令不創建CREATE TABLE語句,這個選項在您只需要數據而不需要DDL(數據庫定義語句)時很方便。

-d
這個選項使的mysqldump命令不創建INSERT語句。

--opt
此選項將打開所有會提高文件導出速度和創造一個可以更快導入的文件的選項。

-q
這個選項使得MySQL不會把整個導出的內容讀入內存再執行導出,而是在讀到的時候就寫入導文件中。

-T path
這個選項將會創建兩個文件,一個文件包含DDL語句或者表創建語句,另一個文件包含數據。DDL文件被命名為table_name.sql,數據 文件被命 名為table_name.txt.路徑名是存放這兩個文件的目錄。目錄必須已經存在,並且命令的使用者有對文件的特權。

-w "WHERE Clause" or -where = "Where clause "
使用這一選項來過篩選將要放到 導出文件的數據

3.進行備份

建立備份文件夾 /mysqlbak

在 /usr/sbin 文件下建立bakmysql腳本
#!/bin/sh
name=$(date +%Y-%m-%d)
mysqldump database -ubackup -p123456 |gzip>/mysqldata/mysql$name.gz

在ubuntu下下可以選擇兩種任務方案
第一:
查看 /etc/crontab 文件
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
第一個是指每天0點17分執行/etc/cron.hourly下的所有任務,後面的都類似。
m 分鐘
h 小時
dom 即day of month吧,就是日期
mon 即month,月份
dow 即day of week 星期
run-parts 是執行後面指定的目錄下的任務,不指定這個參數則為執行單個指定的文件。
根據這些我們就可以很輕鬆的進行任務,直接把我們的腳本根據自己的需求放入到其中的文件夾中即可。

第二:
1.crontab -e 編輯增加任務。
0 0 * * * /usr/sbin/bakmysql
表示在每天的0點0分執行/usr/sbin/bakmysql腳本。
2.crontab -l 查看我們的任務。
3./etc/init.d/cron restart 重啟crond

java string特性

要理解 java中String的運作方式,必須明確一點:String是一個非可變類(immutable)。什麼是非可變類呢?簡單說來,非可變類的實例是不 能被修改的,每個實例中包含的信息都必須在該實例創建的時候就提供出來,並且在對象的整個生存週期內固定不變。java為什麼要把String設計為非可 變類呢?你可以問問 james Gosling :)。但是非可變類確實有著自身的優勢,如狀態單一,對象簡單,便於維護。其次,該類對象對象本質上是線程安全的,不要求同步。此外用戶可以共享非可變對 象,甚至可以共享它們的內部信息。(詳見 《Effective java》item 13)。String類在java中被大量運用,甚至在class文件中都有其身影,因此將其設計為簡單輕便的非可變類是比較合適的。

一、創建。
好了,知道String是非可變類以後,我們可以進一步瞭解String的構造方式了。創建一個Stirng對象,主要就有以下兩種方式:

java 代碼
  1. String str1 = new String("abc");
  2. Stirng str2 = "abc";

雖然兩個語句都是返回一個String對象的引用,但是jvm對兩者的處理方式是不一樣的。對於第一種,jvm會馬上在heap中創建一個String對 象,然後將該對象的引用返回給用戶。對於第二種,jvm首先會在內部維護的strings pool中通過String的 equels 方法查找是對象池中是否存放有該String對象,如果有,則返回已有的String對象給用戶,而不會在heap中重新創建一個新的String對象; 如果對象池中沒有該String對象,jvm則在heap中創建新的String對象,將其引用返回給用戶,同時將該引用添加至strings pool中。注意:使用第一種方法創建對象時,jvm是不會主動把該對象放到strings pool裡面的,除非程序調用 String的intern方法。看下面的例子:

java 代碼
  1. String str1 = new String("abc"); //jvm 在堆上創建一個String對象

  2. //jvm 在strings pool中找不到值為「abc」的字符串,因此
  3. //在堆上創建一個String對象,並將該對象的引用加入至strings pool中
  4. //此時堆上有兩個String對象
  5. Stirng str2 = "abc";

  6. if(str1 == str2){
  7. System.out.println("str1 == str2");
  8. }else{
  9. System.out.println("str1 != str2");
  10. }
  11. //打印結果是 str1 != str2,因為它們是堆上兩個不同的對象

  12. String str3 = "abc";
  13. //此時,jvm發現strings pool中已有「abc」對象了,因為「abc」equels 「abc」
  14. //因此直接返回str2指向的對象給str3,也就是說str2和str3是指向同一個對象的引用
  15. if(str2 == str3){
  16. System.out.println("str2 == str3");
  17. }else{
  18. System.out.println("str2 != str3");
  19. }
  20. //打印結果為 str2 == str3

再看下面的例子:

java 代碼
  1. String str1 = new String("abc"); //jvm 在堆上創建一個String對象

  2. str1 = str1.intern();
  3. //程序顯式將str1放到strings pool中,intern運行過程是這樣的:首先查看strings pool
  4. //有沒「abc」對象的引用,沒有,則在堆中新建一個對象,然後將新對象的引用加入至
  5. //strings pool中。執行完該語句後,str1原來指向的String對象已經成為垃圾對象了,隨時會
  6. //被GC收集。

  7. //此時,jvm發現strings pool中已有「abc」對象了,因為「abc」equels 「abc」
  8. //因此直接返回str1指向的對象給str2,也就是說str2和str1引用著同一個對象,
  9. //此時,堆上的有效對象只有一個。
  10. Stirng str2 = "abc";

  11. if(str1 == str2){
  12. System.out.println("str1 == str2");
  13. }else{
  14. System.out.println("str1 != str2");
  15. }
  16. //打印結果是 str1 == str2


為什麼jvm可以這樣處理String對象呢?就是因為String的非可變性。既然所引用的對象一旦創建就永不更改,那麼多個引用共用一個對象時互不影響。


二、串接(Concatenation)。
java程序員應該都知道濫用String的串接操作符是會影響程序的性能的。性能問題從何而來呢?歸根結底就是String類的非可變性。既然 String對象都是非可變的,也就是對象一旦創建了就不能夠改變其內在狀態了,但是串接操作明顯是要增長字符串的,也就是要改變String的內部狀 態,兩者出現了矛盾。怎麼辦呢?要維護String的非可變性,只好在串接完成後新建一個String 對象來表示新產生的字符串了。也就是說,每一次執行串接操作都會導致新對象的產生,如果串接操作執行很頻繁,就會導致大量對象的創建,性能問題也就隨之而 來了。
為瞭解決這個問題,jdk為String類提供了一個可變的配套類,StringBuffer。使用StringBuffer對象,由於該類是可變的,串 接時僅僅時改變了內部數據結構,而不會創建新的對象,因此性能上有很大的提高。針對單線程,jdk 5.0還提供了StringBuilder類,在單線程環境下,由於不用考慮同步問題,使用該類使性能得到進一步的提高。

三、String的長度
我們可以使用串接操作符得到一個長度更長的字符串,那麼,String對象最多能容納多少字符呢?查看String的源代碼我們可以得知類String中 是使用域 count 來記錄對象字符的數量,而count 的類型為 int,因此,我們可以推測最長的長度為 2^32,也就是4G。
不過,我們在編寫源代碼的時候,如果使用 Sting str = "aaaa";的形式定義一個字符串,那麼雙引號裡面的ASCII字符最多只能有 65534 個。為什麼呢?因為在class文件的規範中, CONSTANT_Utf8_info表中使用一個16位的無符號整數來記錄字符串的長度的,最多能表示 65536個字節,而java class 文件是使用一種變體UTF-8格式來存放字符的,null值使用兩個字節來表示,因此只剩下 65536- 2 = 65534個字節。也正是變體UTF-8的原因,如果字符串中含有中文等非ASCII字符,那麼雙引號中字符的數量會更少(一個中文字符佔用三個字節)。 如果超出這個數量,在編譯的時候編譯器會報錯。

=============================================================

String a="Hello World!";
String b="Hello World!";
a==b? a和b是否相等 ? 為什麼?

String a=new String("Hello World!");
String b="Hello World!";
a==b? a和b是否相等 ? 為什麼?
解釋:
1. 首先String不屬於8種基本數據類型,String是一個對象。
因為對象的默認值是null,所以String的默認值也是null;但它又是一種特殊的對象,有其它對象沒有的一些特性。

2. new String()和new String(「」)都是申明一個新的空字符串,是空串不是null;

3. String str="kvill";和String str=new String (「kvill」);的區別:
在這裡,我們不談堆,也不談棧,只先簡單引入常量池這個簡單的概念。
常量池(constant pool)指的是在編譯期被確定,並被保存在已編譯的.class文件中的
一些數據。它包括了關於類、方法、接口等中的常量,也包括字符串常量。
看例1:
String s0="kvill";
String s1="kvill";
String s2="kv" + "ill";
System.out.println( s0==s1 );
System.out.println( s0==s2 );
結果為:
true
true
首先,我們要知道Java會確保一個字符串常量只有一個拷貝。
因為例子中的s0和s1中的」kvill」都是字符串常量,它們在編譯期就被確定了,所以
s0==s1為true;而」kv」和」ill」也都是字符串常量,當一個字符串由多個字符串常量連
接而成時,它自己肯定也是字符串常量,所以s2也同樣在編譯期就被解析為一個字符串常量,所以s2也是常量池中」kvill」的一個引用。所以我們得出s0==s1==s2;

用new String() 創建的字符串不是常量,不能在編譯期就確定,所以new String()
創建的字符串不放入常量池中,它們有自己的地址空間。

看例2:
String s0="kvill";
String s1=new String("kvill");
String s2="kv"+ new String("ill");
System.out.println( s0==s1 );
System.out.println( s0==s2 );
System.out.println( s1==s2 );
結果為:
false
false
false
例2中s0還是常量池中」kvill」的應用,s1因為無法在編譯期確定,所以是運行時創
建的新對象」kvill」的引用,s2因為有後半部分new String(「ill」)所以也無法在編譯
期確定,所以也是一個新創建對象」kvill」的應用;明白了這些也就知道為何得出此結果了。

4. String.intern():
再補充介紹一點:存在於.class文件中的常量池,在運行期被JVM裝載,並且可以擴充。String的intern()方法就是擴充常量池的 一個方法;當一個String實例str調用intern()方法時,Java查找常量池中是否有相同Unicode的字符串常量,如果有,則返回其的引 用,如果沒有,則在常量池中增加一個Unicode等於str的字符串並返回它的引用;看例3就清楚了。

例3:
String s0= "kvill";
String s1=new String("kvill");
String s2=new String("kvill");
System.out.println( s0==s1 );
System.out.println( 「**********」 );
s1.intern();
s2=s2.intern(); //把常量池中"kvill"的引用賦給s2
System.out.println( s0==s1);
System.out.println( s0==s1.intern() );
System.out.println( s0==s2 );
結果為:
false
**********
false //雖然執行了s1.intern(),但它的返回值沒有賦給s1
true //說明s1.intern()返回的是常量池中」kvill」的引用
true

最後我再破除一個錯誤的理解:
有人說,「使用String.intern()方法則可以將一個String類的保存到一個全局Strin
g表中,如果具有相同值的Unicode字符串已經在這個表中,那麼該方法返回表中已有字符串的地址,如果在表中沒有相同值的字符串,則將自己的 地址註冊到表中「如果我把他說的這個全局的String表理解為常量池的話,他的最後一句話,「如果在表中沒有相同值的字符串,則將自己的地址註冊到表 中」是錯的:

看例4:
String s1=new String("kvill");
String s2=s1.intern();
System.out.println( s1==s1.intern() );
System.out.println( s1+" "+s2 );
System.out.println( s2==s1.intern() );
結果:
false
kvill kvill
true
在這個類中我們沒有聲名一個"kvill"常量,所以s1.intern()同new String("kvill")是不同的,當我們調用s1.intern()後就在常量池中新添加了一個"kvill"常量,原來的不在常量池中 的"kvill"仍然存在,也就不是「將自己的地址註冊到常量池中」了。
s1==s1.intern()為false說明原來的「kvill」仍然存在;
s2現在為常量池中「kvill」的地址,所以有s2==s1.intern()為true。

5. 關於equals()和==:

這個對於String簡單來說就是比較兩字符串的Unicode序列是否相當,如果相等返回true;而==是比較兩字符串的地址是否相同,也就是是否是同一個字符串的引用。

6. 關於String是不可變的

這一說又要說很多,大家只要知道String的實例一旦生成就不會再改變了,比如說:
String str=」kv」+」ill」+」 「+」ans」;
就是有4個字符串常量,首先」kv」和」ill」生成了」kvill」存在內存中,然後」kvill」又和」 「 生成 」kvill 「存在內存中,最後又和生成了」kvill ans」;並把這個字符串的地址賦給了str,就是因為String的「不可變」產生了很多臨時變量,這也就是為什麼建議用StringBuffer的原 因了,因為StringBuffer是可改變的。
7.注意
 看下面例子:
 public class StringTest
{

public static void main(String[] args)
{
String str1 = "hello";
String str2 = "hel";
str2 = str2 + "lo";
System.out.println("str1 == str2 :" + (str1 == str2));
}
}

實際會打出false
為什麼呢,關鍵就在於str2=str2+"lo"是不能能編譯期就確定的
str1是在內存池沒錯,但str2不是~
用反編譯工具反編譯一下class文件就會發現
str2 =str2+"lo";
實際上是:
str2 = (new StringBuilder()).append(str2).append("lo").toString();
顯然,str2是new出來的(不信去看看StringBuilder的源代碼)


पथ 與 CLASSPATH

設定 path 是告訴系統, 執行檔程式位於什麼地方
主要是在執行 javac 跟 java 這兩個程式時使用的
也就是當你在命令列打入 javac xxx.java 和 java xxx 時
系統要去那裡找 javac 和 java 這兩個執行檔

設定 classpath 是告訴 Java
要使用或執行的 class 檔所在的路徑
比如說: 我們輸入 "java A" 命令 要求 Java 執行 A.class 這個類別檔時
Java 會由 classpath 所設定的路徑位置開始尋找 A.class
所以如果你沒有設定, 那 Java 就會跟你說他找不到
就算你是在 A.class 所在的路徑執行這個命令
也要在 classpath 裡面跟 Java 說 要到目前所在的路徑尋找 A.class
否則 Java 還是找不到的
另外 如果 A.class 裡面用到 B.class 時
在 classpath 設定中也要包含 B.class 所在的路徑

在較新版本的 SDK 中
並不需要在 classpath 裡面設定 SDK 原有的 class 檔或 jar 檔路徑
程式已經將路徑預設好了
你只需要設定額外的類別檔路徑就可以了

設定如下:

在 Windows 95/98 平台中

設定的方法為 用文字編輯器 (如小作家, notepad 等等)
編輯 c:\autoexec.bat
在裡面加入
SET PATH=C:\jdk\bin\
SET CLASSPATH=.;C:\java\class\;C:\java\jar\b.jar

如果這個檔案裡面原來就有 SET PATH 或 SET CLASSPATH
那就將路徑加在原來那行後面 並用 ; 隔開
( 在 J2SDK1.3 版之後的 Windows 版本
如果 CLASSPATH 沒有設定的話
Java 會預設為 CLASSPATH=.;
如果你有設定 則以設定的為主)

如果不設定
則可以用
c:\> c:\jdk\bin\java -cp c:\java\class\;c:\java\jar\b.class;c:\java\test\ xxx
來執行

設定好之後就可以簡化成
c:\> java xxx

Linux設定

在Linux下設定Path會比Windows簡單,

請先在終端機底下輸入vim /etc/profile

並在最後面加上

export JAVA_HOME="/usr/java/jdk1.6.0_05":

export PATH="$JAVA_HOME/bin":$PATH":

export CLASSPATH="$JAVA_HOME/lib":

※ 在Linux底下 : 跟Windows的 ; 功能是一樣的

在輸入完後按ESC並輸入wq即可離開,

若要馬上驗證設定是否有成功,在終端機下

source /etc/profile接著輸入

java -version以及javac -version

但這邊要特別說明,在從新開機之前,每次使用java前都必須source一次,

所以還是建議設定完成後馬上重開機。



在 Linux 底下
若路徑為
/usr/local/java/bin/java
/usr/local/java/bin/javac
/usr/local/class/a.class
/usr/local/jar/b.jar
/home/test/java/xxx.java
/home/test/java/xxx.class

則需在 /etc/profile (所有帳號共用) 加入
PATH=/usr/local/bin/:$PATH
CLASSPATH=./:/usr/local/class/:/usr/local/jar/b.jar
export PATH CLASSPATH

PS:
1. 以上設定好之後, 最好重新開機, 或重新登入,
反正就是要系統重新執行這個檔案
2. = 號兩側不可以有空白
3. Java 是會區分大小寫的, 不要把類別檔的大小寫 寫錯了
4. 設定中的 . 是代表使用者目前所在目錄

安裝其他套件之 ClassPath 設定

一般來說 當下載新的套件時
需要將新套件的路徑設定到 CLASSPATH 中
比如說
下載 JavaMail 裡面有 mail.jar 放在
c:\javamail\mail.jar 或是 /usr/local/javamail/mail.jar
那原來的 CLASSPATH 後面就要加上
;c:\javamail\mail.jar 或是 :/usr/local/javamail/mail.jar

還有要注意的是
如果安裝的是 server
如 JServ 或 Tomcat 這一類的程式
那也要把原來 classpath 設定的路徑
寫入到 Jserv 或 Tomcat 這些程式的設定檔中
這樣這些 server 才知道要去哪裡找 class

如果有用過 DOS 系統的人 應該可以瞭解 PATH 是在幹嘛的
這個 PATH 並不是給 Java 用的
早在沒有 Windows 的 DOS 時代 就有這個東西了.....
因為 DOS 沒有所謂的 "捷徑"
所以如果你要執行程式 那你必須給他 "完整路徑"
除非那個程式是在使用者的正處於的目錄

比如說 c:\windows\commands\edit.exe
如果你在
C:\windows\commands> edit
這樣當然可以
如果你是在
C:\> edit
他就會跟你說 找不到這個 edit.exe
因為這檔案不在 C:\ 底下
你也不能期望電腦會把你所有硬碟目錄全部都搜尋一遍 找出可能的檔案
如果這樣 那過不了多久你的硬碟可以就開始壞軌了
所以你必須打完整路徑
C:> c:\windows\commands\edit
但是每次都這樣打實在太麻煩∼∼
所以就發明了一個 "系統變數",也就是 OS 會去使用的設定
只要這樣設定 PATH=C:\windows\commands\
那不論你在哪裡打 edit,他會先去找目前目錄底下有沒有這個程式
如果沒有 就去 PATH 的路徑找....
當然 不只有 edit,只要是打任何指令 在目前目錄底下找不到的
他就會去 PATH 設定的地方找
所以你瞭解為什麼要設定到 JDK 的 bin 目錄底下嗎?
因為 java.exe 跟 javac.exe 等等指令都在這目錄底下
所以你安裝完 JDK 之後有三種選擇可以執行命令
1. 直接到 javac.exe java.exe 所在的目錄底下去打指令 (麻煩...)
2. 每次打命令都打完整路徑 (通常很長....)
3. 設定系統變數 PATH 到 JDK 的 bin 目錄

同樣的所謂的 JVM 就好像是 OS 上面再啟動一個 OS
對 JVM 來說 CLASSPATH 就好像是對 OS 來說的 PATH
JVM 是由 java.exe 這個程式啟動的
而且別忘了 java.exe 並不是在使用者的路徑下
所以他會去 java.exe 所在的目錄底下去找 .class 檔
除非你的 .class 檔放在跟 java.exe 同一個目錄
否則他是找不到 .class 在哪裡的....
所以我們要設定一個路徑 讓 JVM 可以去這個路徑尋找你要他執行的 .class
所以你一樣有三種方法可以執行
1. 把所有的 .class 都放到 java.exe 的相對目錄底下 ( 很難管理... )
2. 每次都打完整路徑, 也就是使用 -cp 的選項
比如 java -cp .;c:\myclass\ Test
(其中那個句點 . 表示使用者打這個指令時 所在的目錄)
(常打的話很煩 ... )
3. 設定系統變數 CLASSPATH 到你的 class 的位置

至於系統變數怎麼設定 那要看你在那個平台 依據平台的設定
( 當然 系統變數不只這兩個, 就算你都沒有去設定
通常安裝完 OS, OS 就會預設一堆系統變數
你只是多手動的加了兩個 )

當然你都不設定也是可以∼∼
只是很麻煩
比如說你安裝的路徑是
C:\JDK1.3.1\
D:\myclass\Test.class
其中 Test 用到 E:\extclass\Util.class
那你每次執行要打
c:\JDK1.3.1\bin\java -cp e:\extclass;d:\myclass Test
如果你不嫌煩的話 不用設定也是無所謂啦

2009年4月22日 星期三

得到用戶的瀏覽器名

String Agent = request.getHeader("User-Agent");
StringTokenizer st = new StringTokenizer(Agent,";");
st.nextToken();
//得到用戶的瀏覽器名
String userbrowser = st.nextToken();
//得到用戶的操作系統名
String useros = st.nextToken();

取得本機的信息也可以這樣:

操作系統信息
System.getProperty("os.name"); //win2003竟然是win XP?
System.getProperty("os.version");
System.getProperty("os.arch");
瀏覽器:
request.getHeader("User-Agent")

request.getHeader(「User-agent」)返回客戶端瀏覽器的版本號、類型

getHeader(String name):獲得http協議定義的傳送文件頭信息,

request. getMethod():獲得客戶端向服務器端傳送數據的方法有GET、POST、PUT等類型

request. getRequestURI():獲得發出請求字符串的客戶端地址

request. getServletPath():獲得客戶端所請求的腳本文件的文件路徑

request. getServerName():獲得服務器的名字

request.getServerPort():獲得服務器的端口號

request.getRemoteAddr():獲得客戶端的IP地址

request.getRemoteHost():獲得客戶端電腦的名字,若失敗,則返回客戶端電腦的IP地址

request.getProtocol():

request.getHeaderNames():返回所有request header的名字,結果集是一個Enumeration(枚舉)類的實例

request.getHeaders(String name):返回指定名字的request header的所有值,結果集是一個Enumeration(枚舉)類的實例

2009年4月19日 星期日

Ubuntu常用指令與技巧

Ubuntu常用命令與技巧
sudo apt-get install 軟體名 安裝軟體命令
sudo nautilus 打開文件(有root權限)
su root 切換到“root”

ls 列出當前目錄文件(不包括隱含文件)
ls -a 列出當前目錄文件(包括隱含文件)
ls -l 列出當前目錄下文件的詳細資訊

cd .. 回當前目錄的上一級目錄
cd - 回上一次所在的目錄
cd ~ 或 cd 回當前使用者的宿主目錄
mkdir 目錄名 創建一個目錄
rmdir 空目錄名 刪除一個空目錄
rm 文件名 文件名 刪除一個文件或多個文件
rm -rf 非空目錄名 刪除一個非空目錄下的一切

mv 路經/文件 /經/文件 移動相對路經下的文件到絕對路經下
mv 文件名 新名稱 在當前目錄下改名
find 路經 -name “字符串” 搜尋路經所在範圍內滿足字符串匹配的文件和目錄

fdisk fdisk -l 查看系統分區資訊
fdisk fdisk /dev/sdb 為一塊新的SCSI硬碟進行分區
chown chown root /home 把/home的屬主改成root使用者
chgrp chgrp root /home 把/home的屬組改成root組

Useradd 創建一個新的使用者
Groupadd 組名 創建一個新的組
Passwd 使用者名 為使用者創建密碼
Passwd -d使用者名 刪除使用者密碼也能登陸
Passwd -S使用者名 查詢賬號密碼
Usermod -l 新使用者名 老使用者名 為使用者改名
Userdel–r 使用者名 刪除使用者一切

tar -c 創建包 –x 釋放包 -v 顯示命令過程 –z 代表壓縮包
tar –cvf benet.tar /home/benet 把/home/benet目錄打包
tar –zcvf benet.tar.gz /mnt 把目錄打包並壓縮
tar –zxvf benet.tar.gz 壓縮包的文件解壓恢復
tar –jxvf benet.tar.bz2 解壓縮

make 編譯
make install 安裝編譯好的源碼包
reboot Init 6 重啟LINUX系統
Halt Init 0 Shutdown –h now 關閉LINUX系統

uname -a 查看內核版本
cat /etc/issue 查看ubuntu版本
lsusb 查看usb設備
sudo ethtool eth0 查看網卡狀態
cat /proc/cpuinfo 查看cpu資訊
lshw 查看當前硬體資訊
sudo fdisk -l 查看磁盤資訊
df -h 查看硬碟剩余空間
free -m 查看當前的記憶體使用情況
ps -A 查看當前有哪些進程
kill 進程號(就是ps -A中的第一列的數字)或者 killall 進程名( 殺死一個進程)
kill -9 進程號 強制殺死一個進程

常用apt命令:

apt-cache search package 搜索包
apt-cache show package 獲取包的相關資訊,如說明、大小、版本等
sudo apt-get install package 安裝包
sudo apt-get install package - - reinstall 重新安裝包
sudo apt-get -f install 修復安裝”-f = –fix-missing”
sudo apt-get remove package 刪除包
sudo apt-get remove package - - purge 刪除包,包括刪除配置文件等
sudo apt-get update 更新源
sudo apt-get upgrade 更新已安裝的包
sudo apt-get dist-upgrade 昇級系統
sudo apt-get dselect-upgrade 使用 dselect 昇級
apt-cache depends package 了解使用依賴
apt-cache rdepends package 是查看該包被哪些包依賴
sudo apt-get build-dep package 安裝相關的編譯環境
apt-get source package 下載該包的源代碼
sudo apt-get clean && sudo apt-get autoclean 清理無用的包
sudo apt-get check 檢查是否有損坏的依賴

清理所有軟體緩存(即緩存在/var/cache/apt/archives目錄里的deb包 )
sudo apt-get clean

刪除系統不再使用的孤立軟體
sudo apt-get autoremove

資料來源:http://www.busfly.cn/post/Ubuntu-cmd.html