隨筆-31  評論-257  文章-0  trackbacks-0
           
          Smarty 的配置文件

                開發人員一直使用配置文件來存儲確定應用程序行為和操作的數據。例如,php.ini 文件負責確定PHP的大量行為。對于Smarty ,模板設計人員也可以利用配置文件的強大作用。例如,設計人員可以使用配置文件存儲頁面標題、用戶消息以及有必要集中存儲的任何信息。
                以下是一個示例配置文件 (名為 app.config):

          #Global Variables
          appName = "PMNP News Service"
          copyright = "Copyright 2005 PMNP News Service, Inc."

          [Aggregation]
          title = "Recent News"
          warning = "Copyright warning.Use of this information is for personal use only."

          [Detail]
          title = "A Closer Look..."

                中括號中包圍的項稱為節(section)。節之外的項都認為是全局的。這此項應當在定義任何節之前定義。
               
              下面將展示如何使用config_load 函數來加載配置文件,還會解釋如何在模板中引用配置變量。
              配置文件存儲在 configs 目錄中,并使用Smarty函數 config_load 加載。下面是加載配置文件 app.config 的示例:
              {config_load file="app.config"}
          但是要記住,此調用只能加載配置文件的全局變量。如果要加載特定的節,需要使用 section 屬性指定。所以,可以使用以下語法加載 app.config 的節 Aggregation:
                {config_load file="app.config" section="Aggregation"}
                另外兩個可選參數介紹如下:
              scope:確定所加載的配置變量的作用域。默認情況下設置為local,表示變量只能用于本地模板。其它可能的設置包括 parent 和 global 。作用域設置為 parent 時,變量可用于本地模板和調用模板。作用域設為global 時,變量則可以用于所有模板。
              section:指定加載配置文件的特定節。因此,如果只對某個特定節感興趣,可以只加載該節,而非整個文件。

          引用配置變量

                配置文件中變量的引用方式與其它變量的引用方式有所不同。實際上,這些配置變量使用幾種不同的語法來引用,下面將介紹這個內容。
              1、#
                在 Smarty 模板中,可以在變量前面加上#號來引用配置變量。例如:
                {#title}
                2、Smarty的$smarty.config變量
              引用配置變量時,如果喜歡更為正式的語法,可以使用 Smarty 的 $smarty.config 變量。例如:
                {$smarty.config.title}
                3、get_config_vars() 方法
              array get_config_vars([string variablename])
                get_config_vars() 方法返回一個數組,包含加載的所有配置變量值。如果只對某個變量值感興趣,可以通過 variablename 傳入該變量。例如,如果只對以上 app.config  配置文件中 Aggregation 節的 title 感興趣,可以首先使用 config_load 函數加載該節:
                {config_load file="app.config" section="Aggregation"}
          然后,在模板中啟用PHP的節中調用 get_config_vars( ),如下:
                $title = smarty->get_config_vars("title");
          當然,無論選擇哪一種獲取配置參數的語法,都不要忘記首先使用 config_load 函數加載配置文件。
          posted @ 2008-07-29 13:51 姜大叔 閱讀(342) | 評論 (0)編輯 收藏
          Smarty 的表現邏輯

                第一編文章中,只簡單的講述了Smarty里的基本原理,也就傳幾個變量的值而已,而本節中,將會講述Smarty的邏輯表示結構,比如它的分支,修飾符,迭代等結構的表達。

               (1) 注釋:

                中Smarty中,也可以使用注釋,設計人員可以用注釋在模板頁面中傳遞一些說明信息等。在Smarty中的注釋為:{* Hello Jiang! *},大家可以看到,Smarty中的注釋是用{**}來包圍的,可以單行,也可以多行,比如可以這樣寫:
                {* Hello
                     Jiang! *}

               (2)變量修飾符:

                在Smarty中,可以為變量添加修飾符,用于對變量進行一些Smarty已定義好的操作,變量修飾符的寫法是:
                {$var|modifier}
          其中,$var 是變量,modifier 是修飾符的單詞,意為對指定變量進行某種修飾操作。

                1、capitalize 修飾符
                capitalize 修飾符用于對變量內的值中所有單詞的首字母變為大寫,可看示例:
                $smarty = new Smarty;
                $smarty->assign("$title","hello jiang zone");
                $smarty->display("index.tpl");

          index.tpl 內容為:
                {$title|capitalize}

                2、count_words
                count_words 函數統計變量中的單詞總數

                3、date_format
                date_format 函數是PHP strftime() 函數的包裝器,它能將可以被strftime()解析的任何日期/時間格式字符串轉換為某種特殊格式。

                4、default
                default 函數當應用層沒有返回值時,default為指示特定變量的默認值提供了一種簡單的方式。

                5、strip_tags
                strip_tags 函數刪除變量字符串中的標簽符號。如:
                $smarty->assign("name","<b>Jiang</b>");
                模板里這樣寫:{$name|strip_tags}
                會輸入如下name的值:"Jiang",它將<b></b>刪除了。所以,沒有輸出粗體

                6、truncate
                truncate 函數將變量字符串截取為指定數量的字符。]


                (3)控制結構

                1、if-elseif-else
                Smarty 的if語句與PHP語言中的if語句相同,與PHP一樣,可以使用一些條件限定符如下:
                eq            gt            gte            ge
                lt              lte            le              ne
                neq          is even     is not even   is odd
                is not odd  div by     event by    not
                mod         odd by      ==            !=
                >              <              <=            >=
          示例:
                {if $var > 5}
                    <p>Hello JiangZone</p>
                {/if}

                2、foreach
                foreach 標記的作用與PHP語句中的命令相同。但如下所示,其語法大不相同。它有4個參數,其中兩個是必要的:
                form : 這個必要參數指定目標數組的名。
                item : 這個必要參數指定當前元素的名。
                key : 這個可選參數指定當前鍵的名。
                name : 這個可選參數指定節的名。這個名是任意的,應當設置為一個描述性的名字。
          看看如下例子:
          require("Smarty.class.php");
          $smarty = new Smarty;
          $daysofweek = array("Mon","Tues","Weds","Thu","Fri","Sat","Sun");     
          $smarty->assign("daysofweek",$daysofweek);
          $smarty->display("daysofweek.tpl");     

          以下是daysofweek.tpl模板文件:
          {foreach from=$daysofweek item=$day}
                {$day}<br />
          {/foreach}

                3、foreachelse
                foreachelse 標記與 foreach 一起使用,與用于字符串的 default 標記作用類似,數組為空時 foreachelse 標記可以生成某個候選結果。以下是一個使用 foreachelse 的模板示例:
          {foreach key=key item=item from=$titles}
                {$key}: {$item}<br />
          {foreachelse}
                <p>No states matching your query were found.</p>
          {/foreach}
          注意,foreachelse 不使用結束括號:它嵌入到foreach中,這與elseif嵌入到if語句中很類似。


                (4)語句
                Smarty 提供了幾個用于完成特殊任務的語句。
                1、include
                include語句與PHP包中的同名語句相同,只是它只用于將其它模板導入到當前模板。例如,假設希望在Smarty模板中導入兩個文件,header.tpl 和 footer.tpl ,可以如下完成:
          {include file="header.tpl"}
          {include file="footer.tpl"}

                2、insert
                insert 標記與 include 標記的功能相同,只是它要導入不會被緩存的數據。例如,可以使用這個函數插入經常更新的數據,如股票價格,天氣預報或其它在很短時間內就要改變的內容。它也接受幾個參數,一個是必要的,另外三個是可選的:
                name : 這個必要參數確定insert函數的名。
                assign : 這個可選參數可用于將輸出給變量,而不是直接發送到輸出。
                script : 這個可選參數可以指向在導入文件前直接執行的一個PHP腳本。當輸出文件的內容依賴于腳本所完成的某個特定動作時,可以使用此參數。例如,可以執行一個PHP腳本,返回某個默認的股票價格放在不可緩存的輸出中。
                var : 這個可選參數用于傳入所有插入模板使用的其它參數。可以通過這種方式傳遞很多參數。

                3、literal
                literal 標記告訴Smarty :標記中嵌入的任何數據都應當原樣輸出,不需要轉換。這個標記量常用于在模板中嵌入JavaScript 和CSS ,從而不需要擔心與 Smarty 的定界符沖突。

                4、php
                可以使用php函數在模板中嵌入PHP代碼。{php}{/php}標記中的任何代碼都由PHP引擎處理。
          posted @ 2008-07-29 13:49 姜大叔 閱讀(401) | 評論 (0)編輯 收藏
                其實本人也正在學PHP,所以就把學習PHP時的心得體會與所學到的知識分享一下吧,所以這一系列教程(或者是心得吧),將圍繞在初學PHP過程中遇到的問題和需要注意的地方。
                這是關于PHP中Smarty模板技術的第一編,為什么要說模板技術呢?原因很簡單,如果你想做一個合格的PHP程序員的話,如果你想開發一個結構合理、移植方便的系統的話,那就要留意一下PHP的模板技術,而在PHP的模板技術中,Smarty是一個不錯的選擇。
                使用模板化主要有兩個原因:1、可以使用同樣的代碼基為不同的目標生成數據。2、應用程序設計人員(負責創建和維護界面的人)可以與應用程序開發人員獨立工作,因為用表現和邏輯并非密不可分地糾纏在一起。但模板化引擎如何完成這種分離?有趣的是,大多數實現的做法與編程語言非常相似,為完成各種與界面有關的任務提供了良好的定義的語法和命令集。
                Smarty提供了很多強大的功能。
                1、強大的表現邏輯
                2、模板編譯
                3、緩存
                4、高度可配置和可擴展
                5、安全

                如何使用Smarty?
                使用Smarty與使用其它任何類庫一樣。對于初學者,只需要在執行腳本中使Smarty類庫可用。實現這一點非常容易,使用  require()  語句即可:
                require("Smarty.class.php");
          之后,就可以實例化Smarty類:
                $smarty = new Smarty;
          現在,就可以用Smarty來做東西了。下面看看一個小例子:
          以下是模板文件 index.tpl :
           1 <html>
           2     <head>
           3         <title>{$title}</title>
           4     </head>
           5     <body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#800080" alink="#ff0000">
           6         <p>
           7         Hi,{$name}.Welcome to the wonderful world of Smarty.
           8         </p>
           9     </body>
          10 </html>

          以下是PHP頁面方面代碼  index.php:
          <?php
              
          require('Smarty.class.php');
              
          $smarty = new Smarty;
              
          $smarty->assign("name","JiangZone");
              
          $smarty->assign("title","Jiang's Blog");
             
              
          $smarty->display("index.tpl");
          ?>


          從以上兩段代碼可以看得到,index.tpl文件是頁面文件,沒有業務邏輯代碼,只有{$name},{$title},初學者可能覺得怪,不過如果有Java基礎的話,應該看得出,它跟Jsp的EL表達式有點類似,或者跟標簽庫功能有點像。這樣看上去,頁面跟程序邏輯就分開來了,設計師專注于他的頁面設計,需要放入處理后的值的話,就加上個{$name}等標記,而程序員則專注于程序邏輯的實現,將處理結果放到模板頁面那里相應的變量位置。明眼人可能很快看得出,上面PHP代碼里,$smarty->assign("name","JiangZone");就是一個對模板賦值的過程,意為為模板中的變量$name 的值設為字符串“JiangZone”,下面的也是一樣,而最后那句,$smarty->display("index.tpl");則是將上面設置好的值應用到index.tpl模板上,并將應用后的結果輸出到客戶端。
          posted @ 2008-07-29 13:46 姜大叔 閱讀(525) | 評論 (0)編輯 收藏
                我在初學PHP期間,學了點入門文章,學了學語法,就想做點小東西來練練手,做什么好呢?就做個購物車吧,頁面都做好了,現在正寫代碼進去,測試運行,但有個小問題,我在產品列表里明明是選了幾個產品的,即是選中了幾個 Checkbox ,checkbox 的名字都是"prodno" 但怎么在PHP里用 $_POST['prodno'] 來獲取它的值,總是只獲取到最后的那個checkbox 的值,為什么?檢查了form幾遍,沒有錯誤,再檢查了PHP幾遍,也沒錯啊[loo](其實是checkbox里的name錯了,當時不知道PHP要這樣),郁悶了,我以前做Java都是這樣寫的呀,有什么問題?做ASP時,也是這樣寫也沒錯呀,問題出在哪呢?
                后來用 is_array($_POST['prodno']) 得到的是false,不會吧,PHP不會獲取重復名字的表單?唉,后來上網Google了一翻,原來PHP里獲取重復名字的表單值跟JSP/ASP等的都不一樣,JSP的直接用 request.getParameterValues("prodno"); 返回的是一個String[] 數組,但PHP的差別在于,要將form里的 checkbox 的 name 寫成: prodno[] 就是要多了后面那對方括號,之后PHP里 $_POST['prodno'] 獲得的就是一個 array ,唉,這樣都行,不過后來想想,這個可能跟PHP的一個語法有關吧,在PHP里,數組是可以這樣賦值的:

                $arr[] = 'aaa';
                $arr[] = 'bbb';
                $arr[] = 'ccc';

                這樣寫的話,$arr 里就有三個值,key分別是0,1,2,而value分別是'aaa','bbb','ccc',
          就是說在PHP里,你給數組賦值的話,不寫key的話,他會默認用遞增的數字來自動當key,所以,當表單提交到PHP里時,實際上就是

                $prodno[] = 'a';
                $prodno[] = 'b';

                所以,當 $_POST['prodno'] 的值就是$prodno 的值,所以它是一個數組,
          而如果表單里name的值寫成 prodno 的話,就會是

                $prodno = 'a';
                $prodno = 'b';

                所以,大家可以看得出問題所在了,這樣$prodno的值始終會給最后的那個值覆蓋,所以就出現我之前的現像我用$_POST['prodno']獲取到的值總是我最后的那個checkbox的值,所以更不用說is_array()了,當然是得到false了。
          所以,對于一些有其它編程語言基礎的人來說,學PHP的話,要注意這點,跟別的語言都不同。
          posted @ 2008-07-29 13:45 姜大叔 閱讀(1389) | 評論 (2)編輯 收藏
          本文討論的是如何徹底杜絕warning: Cannot add header information - headers already sent in......  這種令人莫明其妙的的錯誤。

          只要你寫過PHP代碼,相信都遇上過這個大多時候都令人莫明其妙的warning吧..今天我們就來搞定它...............

          看了PHP手冊,回答如下:

          消息“Warning: Cannot send session cookie - headers already sent。。。”或者“Cannot add header information - headers already sent。。。”。

          函數 header(),setcookie() 和 session 函數需要在輸出流中增加頭信息。但是頭信息只能在其它任何輸出內容之前發送。在使用這些函數前不能有任何(如 HTML)的輸出。函數 headers_sent() 能夠檢查您的腳本是否已經發送了頭信息。請參閱“輸出控制函數”。

          意思是:不要在使用上面的函數前有任何文字,空行,回車,空格等。但。。。問題是,這答案并不令人滿意。因為往往程序在其他PHP環境下運行卻正常。
           

          首先:這錯誤是怎么產生的呢?讓我們來看看PHP是如何處理HTTP header輸出和主體輸出的。

          PHP 腳本開始執行時,它可以同時發送header(標題)信息和主體信息。 Header信息(來自 header() 或 SetCookie() 函數)并不會立即發送,相反,它被保存到一個列表中。 這樣就可以允許你修改標題信息,包括缺省的標題(例如 Content-Type 標題)。但是,一旦腳本發送了任何非標題的輸出(例如,使用 HTML 或 print() 調用),那么PHP就必須先發送完所有的Header,然后終止 HTTP header。而后繼續發送主體數據。從這時開始,任何添加或修改Header信息的試圖都是不允許的,并會發送上述的錯誤消息之一。

          好!那我們來解決它:

          笨方法:把錯誤警告全不顯示!
          掩耳盜鈴之計,具體方法就不說了 ^_^#

          解決方案:

          1)適用于有權限編輯PHP。INI的人

          打開php。ini文件(你應試比我清楚你的php。ini在哪里),找到

          output_buffering =改為on或者任何數字。如果是IIS6,請一定改為ON,不然你的PHP效率會奇慢。

          2)使用虛擬主機,不能編輯PHP。INI,怎么辦?

          簡單:

          在你的空間根目錄下建立一個。htaccess文件,內容如下:

          AllowOverride All
          PHP_FLAG output_buffering On

          不幸的情況是:還是不行?全部網頁都不能顯示啦?

          那么,你可以打電話罵一通空間商,然后讓他給你把apache的。htaccess AllowOverride打開

          3)在PHP文件里解決

          ob_start()
          啟用output buffering機制。 Output buffering支持多層次 -- 例如,可以多次調用 ob_start() 函數。

          ob_end_flush()
          發送output buffer(輸出緩沖)并禁用output buffering機制。

          ob_end_clean()
          清除output buffer但不發送,并禁用output buffering。

          ob_get_contents()
          將當前的output buffer返回成一個字符串。允許你處理腳本發出的任何輸出。

          原理:

          output_buffering 被啟用時,在腳本發送輸出時,PHP并不發送HTTP header。相反,它將此輸出通過管道(pipe)輸入到動態增加的緩存中(只能在PHP 4。0中使用,它具有中央化的輸出機制)。你仍然可以修改/添加header,或者設置cookie,因為header實際上并沒有發送。當全部腳本終止時,PHP將自動發送HTTP header到瀏覽器,然后再發送輸出緩沖中的內容。
          posted @ 2008-07-29 13:44 姜大叔 閱讀(189) | 評論 (0)編輯 收藏
                真的很久很久沒有寫過文章了,唉,慚愧啊!寒暄的說話就不多說了,直入主題。有人問過我,如何制作一些論壇的自動發言機器人?我說,這很簡單啊,(如果沒有圖片驗證碼的話!)在Java里,有些URL,URLConnection的類啊,這些類可以訪問一個URL獲取數據,可以發送Request,你就可以結合一些類做一個自動發言的了,但用Post發送表單的話,就沒有直接的,比較麻煩,如果還要處理Cookie的話,之后我想了想,想到了可以用Jakarta Commons 下面的開源項目啊,有一個項目名叫“HttpClient”的,這個就是用Java寫的Http客戶端,可以說是一個簡單功能的瀏覽器吧,只是不能解析HTML標簽,寫這個解析可不是易事。既然我們是寫個自動訪問網站的程序,就不用解析顯示HTML啦。朋友說能寫個招聘網站的自動刷新簡歷的程序就好了,那就用51job為例吧。
                首先,你得去下載HttpClient的包。
          http://jakarta.apache.org/commons/httpclient

          代碼不多,我們就先來看看代碼吧:

           1 import java.io.*;
           2 import org.apache.commons.httpclient.*;
           3 import org.apache.commons.httpclient.methods.*;
           4 
           5 public class HttpTest {
           6 
           7     /**
           8      * @param args
           9      * @throws Exception
          10      */
          11     public static void main(String[] args) {
          12         //先建立一個客戶端實例,將模擬一個瀏覽器
          13         HttpClient client = new HttpClient();
          14        
          15         //這個是URL地址,我經過分析51job網站登錄后的跳轉到的地址,并分析得它在JavaScript里提交的URL的參數,不同網站就自已分析了,這個就是登錄后刷新簡歷的URL地址
          16         String url = "http://my.51job.com/my/Pop_RefreshResume.php?en=0&ReSumeID=88888888&Read=0&ID=88888888";
          17        
          18         //之后再建立一個Post方法請求,提交刷新簡歷的表單,因為提交的參數較多,所以用Post請求好了
          19         PostMethod method = new PostMethod(url);
          20 
          21         //下面的就是將要提交的表單的數據填入PostMethod對象里面,以name , value 對加入!
          22         method.addParameter("HPNation""086");
          23         method.addParameter("HPCity","020");
          24         method.addParameter("HPNumber","88888888");
          25         method.addParameter("FPNation","086");
          26         method.addParameter("FPCity","020");
          27         method.addParameter("FPNumber","88888888");
          28         method.addParameter("FPExtension","000");
          29         method.addParameter("MPNation","086");
          30         method.addParameter("Mobile","13888888888");
          31         method.addParameter("EmailAdd","888@888.com");
          32         method.addParameter("ReSumeID","88888888");
          33        
          34         //這里是建立請求時服務器需要用到的Cookie。
          35         Cookie cookie = new Cookie(".51job.com","51job","ccry%3D.0%252FZKBaMTmj82%26%7C%26cconfirmkey%3DcpwWgp7FC9FZM%26%7C%26cresumeid%3D88888888%26%7C%26cresumeids88888888d888826%7C8408ilstatus%3D2%26%7C%26cnickname826cenglis8cautologin%3D","/",null,false);
          36        
          37         //將設置好的Cookie加入模擬的客戶端里。當請求發生時,就會將Cookie寫進請求頭里了
          38         client.getState().addCookie(cookie);
          39         int i=0;
          40 
          41         //開始死循環
          42         while(true){
          43             try{
          44                 //這里是要求客戶端發送一個請求。直接將PostMethod請求出去。
          45                 client.executeMethod(method);
          46                
          47                 //下面是獲取返回的結果
          48                 InputStream in = method.getResponseBodyAsStream();
          49                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
          50                 byte[] buff = new byte[1024];
          51                 int len = -1;
          52                 while((len=in.read(buff))!=-1){
          53                     baos.write(buff, 0, len);
          54                 }
          55                 String result = new String(baos.toByteArray());
          56                
          57                 //釋放資源
          58                 in.close();
          59                 baos.close();
          60 
          61                 //在51job里,刷新簡歷成功的話,會返回一些JavaScript代碼,里面有個alert()輸出“簡歷已刷新”的信息的,你分析結果,如果有這句話,則成功刷新了。之后就讓線程睡眠1分鐘后循環刷新!
          62                 if(result.indexOf("簡歷已刷新")!=-1){
          63                     System.out.println("簡歷已刷新! " + ++i);
          64                 }else{
          65                     System.out.println("刷新失敗!");
          66                 }
          67                 Thread.sleep(60000);
          68             }catch(Exception ex){
          69                 System.out.println("******** Error! ********");
          70                 try{
          71                     //出現錯誤時,再等待20秒后再重新進行刷新。
          72                     Thread.sleep(20000);
          73                 }catch(Exception e){
          74                     System.out.println("******** Thread Error! ********");
          75                 }
          76             }
          77         }
          78     }
          79 
          80 }


          我們再來看看,其實很簡單,我們來說明一下。HttpClient將很多Http協議底層的東西都封裝了,這樣很方便使用,如果自已用Socket寫的話,還有處理很多信息,Http協議的三次握手等等的操作,很是麻煩。現在用HttpClient就一步到位了。但要注意一下,51job里面的簡歷刷新是要先登錄后才可以進行的,而熟悉Web開發的人員都知道,登錄后服務器就會記錄下你的Session,而Session也是基于Cookie的,所以Session ID是以Cookie的方式記錄在客戶機的,這樣每次請求都要將該Cookie發送到服務器驗證,這樣才可以保證Web的狀態。所以,你可以在瀏覽器里先登錄一次。之后找出該網站的Cookie文件,將里面的內容復制出來放上上面代碼的Cookie類里面。你也可以用這個HttpClient寫一個登錄的請求,之后再從ResponseHeader里獲取Cookie。至于表單里的信息,就按自已需要填寫就行了。就是模擬一個瀏覽器,將你的簡歷刷新的表單模擬出來再發送。

          在下面,我給出一本電子書給大家下載參考:《Jakarta Commons Cookbook.chm》
          [down=attachments/month_0803/020083401424.chm]點擊下載此文件[/down]


          posted @ 2008-07-29 13:09 姜大叔 閱讀(1746) | 評論 (2)編輯 收藏
                現在雙核的CPU已經賣到白菜價了,四核也將在08年迎來普及風暴,這樣看來,硬件處理性能是得到很大提高了,但是不是說明程序的效率就可以忽視了呢?肯定不是,程序也將配合硬件的提高,開發出更有效率,更強大,更好的人工智能的程序。多核的趨勢,這不得不提到程序的并發性能,不然的話,100核的CPU也只會英雄無用武之地。如何更大地發揮多核CPU的性能,就要用到軟件的并發處理能力了。但要設計得合理的并發程序也不是這么簡單的事情,線程的控制也是很頭痛的問題,還有安全問題等等,我越來越感覺到并發的重要性,所以這段時間也在找Java并發,線程方面的資料,打算鉆研一番,并在幾天后整理一下,將一些心得放上來。將會是Java并發優化方面的文章!另外,好像聽說Flash Player 10將會支持線程,不知道是不是真的,看現時的AS3里沒有線程的概念,將會出AS4與之配合?不管怎么都好,期待是美好的事情!
          posted @ 2008-07-29 13:07 姜大叔 閱讀(268) | 評論 (0)編輯 收藏
                SVN的好處,不用多說了,當你的項目做到一定規模時,多人開發甚至異地多人協作開發時,可以為你的團隊省去很多麻煩。可能很多人都用過SVN的客戶端工具,如TortoiseSVN或者是Eclipse中的插件,網上有很多開源項目,或者很多源代碼,都會用這種方式發布,稍有關注一下技術的很多時候都會下載別人的源程序結合自已的項目開發或者是學習,比如去Google Code有很多。我們只用客戶端去連接SVN的服務器,之后更新代碼副本到本地。但我們也應該要認識一下SVN的服務器端,比如你是個項目的負責人建立一個項目讓大家協同開發等,就要在你的機子上打開SVN服務器程序放上你的項目,讓其它人用客戶端去連接獲取或更新代碼。

          配置SVN服務器所需要的準備工具:
          SubVersion  可從 http://subversion.tigris.org 下載。這里就是SVN服務器的程序
          SVNService.exe  (非必要)這個是將你的SVN服務端程序注冊成Windows系統服務的,就好比是Tomcat,當你系統啟動時,該SVN服務器會自動啟動并后臺運行,不注冊成服務的話,就要自已手動打開了。

          現在工具都準備好了,動工。
          下載好SubVersion后,就進行安裝,如果你下載的是ZIP包,那就解壓到自定的目錄就可以使用了。
          1.  打開CMD命令行模式,進入到SubVersion目錄下的bin目錄下,輸入如下命令:

          svnadmin create d:\svn_projects\project1   (路徑可自定)

          如圖:



          注:要先在D盤中建立 svn_projects目錄 目錄名稱可以自已定,
          之后打開該目錄,你可以看到,SVN幫你建立了一個project1的目錄,里面生成了幾個方件夾與文件,先不理它

          現在,存放項目的路徑建好了,下面我們要來配置一下該項目的用戶,密碼等信息
          來打開project1/conf/文件夾下的svnserve.conf文件,以記事本打開就行了,你將會看到很多注釋(都是采用Unix風格的 # 注釋)將
          # anon-access = read
          # auth-access = write
          # password-db = passwd
          # realm = My First Repository
          這幾句的的注釋符號去掉找去掉前面的空格如下:
          anon-access = read
          auth-access = write
          password-db = passwd
          realm = My First Repository

          之后打開passwd文件,以記事本打開,在 [users] 下面添加你的用戶名與密碼
          比如我要添加一個 jiang 用戶,密碼是 123456 那么這樣寫
          jiang = 123456
          保存后就OK了,那么現在,可以運行SVN服務器程序了。
          在Cmd命令行下進入到SubVersion目錄下的bin目錄下,輸入如下命令:

          svnserve -d -r d:\svn_projects

          如圖所示:


          這樣服務器就啟動了,它會一直偵聽的,所以不要關閉窗口。像Tomcat一樣一直掛著就行,如果你覺得這樣麻煩,就可以用SVNService.exe這個工具來注冊成系統后臺服務運行。

          注意:你現在的項目的SVN地址就是:svn://localhost/project1  內網就更換你的內網IP就行了,公網也換為你的公網IP就行了

          現在服務器就啟動了,之后你可以用Eclipse的svn工具等將項目文件放到該SVN服務里共享,
          如下圖所示:



          就這樣,SVN的服務器端就搭建好了,現在大家可以用SVN客戶端更新下載下來開發了。

          關于其它SVN客戶工具的登錄,可以參考以下文章
          如何結合使用Subversion和Eclipse

          posted @ 2008-07-29 13:06 姜大叔 閱讀(320) | 評論 (0)編輯 收藏
                在Java運行時環境中,對于任意一個類,能否知道這個類有哪些屬性和方法?對于任意一個對象,能否調用它的任意一個方法?答案是肯定的。這種動態獲取類的信息,以及動態調用對象的方法的功能來自于Java語言的反射(Reflection)機制。Java反射機制主要提供以下功能:

          [*]在運行時判斷任意一個對象所屬的類;
          [*]在運行時構造任意一個類的對象;
          [*]在運行時判斷任意一個類所具有的成員變量和方法;
          [*]在運行時調用任意一個類的方法;
          [*]生成動態代理;


                在JDK中,主要由以下類來實現Java反射機制,這些類都位于 java.lang.reflect 包中。

                [*] Class 類:代表一個類。
                [*] Field 類:代表類的成員變量
                [*] Method 類:代表類的方法
                [*] Constructor 類:代表類的構造方法
                [*] Array 類:提供了動態創建數組,以及訪問數組元素的靜態方法


          看看下面例子:它讀取命令行參數指定的類名,然后打印這個類的所具有的方法信息:
           1 import java.lang.reflect.*;
           2 public class DumpMethods{
           3     public static void main(String[] args)thorws Exception{
           4         //加載并初始化命令行參數指定的類
           5      Class classType = Class.forName(args[0]);
           6         //獲得類的所有方法
           7      Method[] methods = classType.getDeclaredMethods();
           8         for(int i=0;i<methods.length;i++){
           9             System.out.println(methods[i].toString());
          10         }
          11     }
          12 }


          運行命令 “java DumpMethods java.util.Stack”,就會顯示java.util.Stack 類所具有的方法。

          這個只是十分之基本,很簡單的示例,Java的反射還可以做很多東西,可以跟據用戶的輸入就可以得知哪些類,需要做什么操作,就是說動態跟據需要來調用相應的類與相應的方法,我之前也做過,用Struts結合Java反射來實現一些功能,有些時候,別人的接口代碼里只返回一個Object給你,而你就要用反射來得知該Object是屬于哪一個類型,之后根據設置做相應的操作,不知道大家有用過Hibernate沒有,這個框架就是大量用到了Java反射,用戶只需配置一下XML文件,Hibernate運行時,就會讀取解析XML配置文件,之后動態找相應的類,實例化相應的POJO等等,這些都是全動態化的,也就是說,我請求這個表的數據時,就自動實例化該表的POJO實例,這些都是在XML配置文件里定義好映射關系。ORM框架就如此,很多中間件也是大量使用反射,將反射靈活的運用起來,將會得到意想不到的效果,這也是Java的半動態語言吧。使編程工作變得十分靈活。
          posted @ 2008-07-29 13:00 姜大叔 閱讀(292) | 評論 (1)編輯 收藏
               摘要:     不知道大家有沒有用過農業銀行的網上銀行服務,該網上銀行登錄時,輸入密碼時,不可以直接打鍵盤輸入,要用鼠標點擊圖形小鍵盤來輸入,而小鍵盤里面的數字是隨機排列的。     這樣一來,可以防止木馬記錄用戶鍵盤輸入的密碼被盜,確實是挻實用的功能,研究了一翻后,也大根掌握了它的工作原理,現在用Java來實現,大概是這樣的:用Strut...  閱讀全文
          posted @ 2008-07-29 12:47 姜大叔 閱讀(1232) | 評論 (1)編輯 收藏
          僅列出標題
          共4頁: 上一頁 1 2 3 4 下一頁 
          主站蜘蛛池模板: 山丹县| 元阳县| 兴海县| 唐河县| 高清| 纳雍县| 禹城市| 白水县| 佛冈县| 桦川县| 长子县| 增城市| 大港区| 凤冈县| 保山市| 定日县| 同仁县| 兰溪市| 富民县| 莱州市| 南丰县| 孝感市| 峨边| 澄迈县| 博湖县| 佛学| 和静县| 田东县| 盐城市| 泰安市| 崇明县| 扎兰屯市| 资中县| 乌拉特中旗| 长兴县| 五台县| 吉林市| 高雄市| 英德市| 浮梁县| 青岛市|