第3節 使用java語言來開發NAGIOS股價監視插件

「第3節 使用java語言來開發NAGIOS股價監視插件」の編集履歴(バックアップ)一覧はこちら

第3節 使用java語言來開發NAGIOS股價監視插件」(2006/02/23 (木) 23:25:56) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

<p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">在體驗完這個簡單的插件之後,接下來要登場的就是難度比較高一點的插件了。插件可以被任何語言所寫成,只要它是能被執行,並且反回特定格式的訊息,它的內容是</span><span lang="EN-US"><font face="Century">c</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">也好,</span><span lang="EN-US"><font face= "Century">java</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">也好,</span><span lang="EN-US"><font face= "Century">perl</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">也好,都是被允許的。用什麼語言來實作並不是一件重要的事,只要能夠達成我們想要的目的,就算及格,所以對java不熟的讀者,看到這一章也不用灰心,因為只要你懂了觀念,你可以用你所會的語言,來將這一個插件,進行改寫。</span></font></p> <div class="java" align="left"> <hr></div> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">●需求定義與設計</span></font></p> <p class="java" align="left"> 所有的插件的產生,都是來自於需求。</p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">假設,有一天,在上班的時後,專案經理對小明提出了一個要求,希望小明能夠利用nagios完美的性能,開發出一個定期監視台積電的股價的插件,並且在股價發生變動時,發一封信通知專案經理進場護盤。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">接到這一個要求的小明馬上就列出了下面這一個規格書,並且請經理作確認:</span></font></p> <div class="java" align="left"> <table style="WIDTH: 505px; HEIGHT: 38px" border="1"> <tbody> <tr> <td> <p><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">輸入:股票代碼目標價 停損價</span></p> <p><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">輸出:當股票現值超過目標價,則輸出警告,低於停損價,則發出危急</span></p> </td> </tr> </tbody> </table> </div> <div class="java" align="left"> 雖然經理只對台積電的股價有興趣,但是身為工程師的小明,總是想到軟體工程的一大守則,原件的重用性,所以,小明決定不要把程式碼寫死,留下空間讓專案經理來自行設定。</div> <div class="java" align="left"> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">在這個簡單的介面定義書裡,我們也提供了高值與低值的設定選項,因為我們不曉得專案經理對於股價的企圖心在那裡,所以我們把這個設定值空出來讓經裡自行設定。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">與專案經理進行確認之後,就開始要準備進行開發的工作。</span></font></span></font></p> <hr> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">●開發</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">小明評估了需求,以及時間,決定爭取時效,使用有很多方便的程式庫的</span><span lang="EN-US"><font face="Century">java語言,來作為開發的工具。</font></span></font></p> <hr> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US">第一步:取得即時的股價:</span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US">為了要知道股票目前最近的股價,唯一的來源就是一些入口網站提供的服務了。所以小明決定到yahoo財經,來取得即時的股價。比方說,台積電的股價,只要訪問下列這一個網站,就可以得到所需的資料了。</span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US"><a href= "http://tw.stock.yahoo.com/q/q?s=2330">http://tw.stock.yahoo.com/q/q?s=2330</a></span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US">為了要能夠及時的去把這一個網頁的資料抓回來,小明決定使用由JakartaCommons所提供的HttpClient程式庫。這一個專案的網頁位在</span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US"><a href= "http://jakarta.apache.org/commons/httpclient/">http://jakarta.apache.org/commons/httpclient/</a></span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US">在下載回來之後,小明使用了這個程式庫,寫了一段抓取網頁的程式碼:</span></font></p> <table border="1"> <tbody> <tr> <td><br> <p>程式碼:</p> <font face="Courier New">String url="<a href= "http://tw.stock.yahoo.com/q/q?s=2330"><font color= "#2A00FF">http://tw.stock.yahoo.com/q/q?s=2330</font></a>";<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//生成一個httpclient的物件</font><br> <font color="#FFFFFF">  </font>HttpClient client=<font color= "#7F0055"><b>new</b></font> HttpClient();<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//生成一個get方法的物件</font><br> <font color="#FFFFFF">  </font>GetMethod method = <font color= "#7F0055"><b>new</b></font> GetMethod(url);<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>statusCode = client.executeMethod(method);<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(statusCode != HttpStatus.SC_OK) {<br> <font color="#FFFFFF">   </font><font color= "#3F7F5F">//如果訪問失敗時的處理;</font><br> <font color="#FFFFFF">   </font> <font color= "#3F7F5F">System.out.println("失敗:"+method.getStatusLine());</font><br> <font color="#FFFFFF">  </font>}<br> <font color= "#3F7F5F">//網頁連線成功,開始取得網頁的資料  </font></font> <p><font face="Courier New"><font color= "#FFFFFF">  </font>InputStream responseBody=method.getResponseBodyAsStream();<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//使用中文的編碼,準備將網頁讀進來</font><br> <font color="#FFFFFF">  </font>BufferedReader br=<font color= "#7F0055"><b>new</b></font> BufferedReader(<font color= "#7F0055"><b>new</b></font> InputStreamReader(responseBody, <font color= "#2A00FF">"Big5"</font>) );</font><br> <br></p> <br></td> </tr> </tbody> </table> <p class="java" align="left"> 網頁讀取進來之後,一大段的文字並沒有什麼實用的價值,小明必須要想辦法在這一大段的文字裡,找到一個專案經裡所關心的資訊,也就是當時的股價。此時考慮到時效性,小明決定不採用由另外一個專案所提供的html解析套件,改採暴力破解法。</p> <p class="java" align="left"> 小明使用了文字編輯器,將取得的html原始碼一行一行的往下數下來時,發現當前的股價所記載的位置,正好是在第164行的位置。於是,小明寫了一個回圈,來將取得的大段文章裡,找到164行的內容。正可謂是,股海淘淘,只取一飄呀!</p> <table border="1"> <tbody> <tr> <td> <p>程式碼:</p> <font face="Courier New"><font color= "#FFFFFF"> </font>BufferedReaderbr=<font color= "#7F0055"><b>new</b></font>BufferedReader(<font color= "#7F0055"><b>new</b></font>InputStreamReader(responseBody, <font color= "#2A00FF">"Big5"</font>) );<br> <font color="#FFFFFF">  </font>String line=<font color= "#7F0055"><b>null</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>line_no=<font color="#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>while</b></font>((line = br.readLine())!= <font color= "#7F0055"><b>null</b></font> ){<br> <font color="#FFFFFF">   </font>line_no++;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>if</b></font>(line_no ==<font color="#990000">164</font>){<br> <font color="#FFFFFF">  </font></font><br> <br></td> </tr> </tbody> </table> </div> <div class="java" align="left"></div> <div class="java" align="left"> 取回來的這一飄,長的像這個樣子:</div> <div class="java" align="left"></div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <td> &lt;tdalign="center"bgcolor="#FFFfff"nowrap&gt;&lt;b&gt;<strong>54.00</strong>&lt;/b&gt;&lt;/td&gt;</td> </tr> </tbody> </table> </div> <div class="java" align="left"></div> <div class="java" align="left"> 在重重包圍之下的那個54.00,就是我們最終想要得到的結果了。</div> <div class="java" align="left"></div> <div class="java" align="left"> 此時只好在對這一行文字進行第二次的加工,將不需要的部分去除,只留下我們想要的。</div> <div class="java" align="left"></div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <th>程式碼 3</th> </tr> <tr> <td>#</td> </tr> </tbody> </table> </div> <div class="java" align="left"></div> <div class="java" align="left"></div> <div class="java" align="left"> 進行到這裡,小明已經將取得股價的原件給制作完成了,把他整合成一個method,程式碼如下方所示:</div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <th>程式碼 4:用來取得即時股價的方法</th> </tr> <tr> <td>#</td> </tr> </tbody> </table> </div> <div class="java" align="left"> 小明程式寫到這裡,覺得松了一口氣,因為核心的部份已經完成了一大部份了。他決定到樓下的starbuck買杯咖啡,順便上個廁所,在回來寫下面的一段。</div> <div class="java" align="left"></div> <div class="java" align="left"> <hr></div> <div class="java" align="left">第二部:比較股價,產生輸出</div> <div class="java" align="left"></div> <div class="java" align="left"> 回到位子上之後,小明開始進行第二階段的開發,也就是將剛剛所得到的即時價格,來與設定的高值,低值,作一個比較,如果高值大於現在值,則反回警告,如果現在值小於低值,則發出危險訊號,通知專案經理作停損。</div> <div class="java" align="left">代碼如下所示:</div> <div class="java" align="left"></div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <td>程式碼:價何比較的方法</td> </tr> <tr> <td><font face="Courier New"><strong><font color= "#7F0055">privatestatic</font></strong> String compareValues(<font color= "#7F0055"><b>int</b></font>code , <font color= "#7F0055"><b>float</b></font>current, <font color= "#7F0055"><b>float</b></font>target_price , <font color= "#7F0055"><b>float</b></font> low_price ) {<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>status =-<font color="#990000">1</font>;<br> <font color="#FFFFFF">  </font>String result=<font color= "#2A00FF">"UNKNOWN"</font>;<br> <font color="#FFFFFF">  </font>String message=<font color= "#2A00FF">"["</font>+code +<font color= "#2A00FF">"]current:"</font>+current+<font color= "#2A00FF">",targetis"</font>+target_price+<font color= "#2A00FF">",lowis"</font>+low_price;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(current &gt; target_price ) status =<font color= "#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>elseif</b></font>(current &gt; low_price ) status =<font color= "#990000">1</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>elseif</b></font>(current &lt; low_price ) status =<font color= "#990000">2</font>;<br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>switch</b></font>(status) {<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">0</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"WARNING;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">1</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"OK;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">2</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"CRITICAL;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font>-<font color="#990000">1</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"UNKNOWN;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>return</b></font>result+message;<br> <font color="#FFFFFF"> </font>}</font><br></td> </tr> </tbody> </table> </div> <div class="java" align="left"></div> <div class="java" align="left"></div> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">在以上的方法裡我們作了二件事情,一件事是價格比較,另一件事將結果以nagios所規定的格式與以反回,並且報知目前的價格,以便讓使用者可以在cgi的畫面上得到更多的資訊。</span></font></p> <p class="java" align="left">?</p> <p class="java" align="left">?</p> <hr> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">三、選項的讀取</span></font></p> <p class="java" align="left"> 在前面的二個步驟之後,接下來所剩下的,就是讀取外部的選項了。在之前的介面定義書裡,我們知道這個程式需要接受三個選項,而且我們也決定要遵守開發的原則,在使用者輸入了錯誤的選項之時,能夠回送出適當的提示訊息,所以我們決定,使用由<font face="Century">由JakartaCommons所提供的<a name="CLI : Command Line Interface"><font face="Times New Roman">CLI: Command Line Interface</font></a>程式庫。這一個專案的網頁位在</font></p> <p class="java" align="left"><a href= "http://jakarta.apache.org/commons/cli/">http://jakarta.apache.org/commons/cli/</a></p> <p class="java" align="left"> 在參照了文件的說明之後,小明依照需求,寫出了如下的程式碼:</p> <p class="java" align="left">?</p> <p class="java" align="left">?</p> <table border="1"> <tbody> <tr> <th>程式碼:</th> </tr> <tr> <td><font face="Courier New"><font color="#FFFFFF"> </font>Options options = <font color="#7F0055"><b>new</b></font> Options();<br> <font color="#FFFFFF">  </font><font color="#3F7F5F">//option 1</font><br> <font color="#FFFFFF">  </font>Option target_price_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color="#2A00FF">"tp"</font>, true,<br> <font color="#FFFFFF">    </font><font color= "#2A00FF">"TargetPrice,forexample -tp=58.5 "</font>);<br> <font color="#FFFFFF">  </font>target_price_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//  option2</font><br> <font color="#FFFFFF">  </font>options.addOption(target_price_opt);<br> <font color="#FFFFFF">  </font>Option low_price_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color="#2A00FF">"lp"</font>, true,<br> <font color="#FFFFFF">    </font><font color= "#2A00FF">"LowPrice,forexample -lp=58.5 "</font>);<br> <font color="#FFFFFF">  </font>low_price_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//  option3</font><br> <font color="#FFFFFF">  </font>options.addOption(low_price_opt);<br> <font color="#FFFFFF">  </font>Option code_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color= "#2A00FF">"c"</font>,true,<font color= "#2A00FF">"code,forexample-c=2330"</font>);<br> <font color="#FFFFFF">  </font>code_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font>options.addOption(code_opt);<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//3.然後parseinput</font><br> <br> <font color="#FFFFFF">  </font>CommandLineParser parser = <font color= "#7F0055"><b>new</b></font> BasicParser();<br> <br> <font color="#FFFFFF">  </font>CommandLine cmd;<br> <br> <font color="#FFFFFF">  </font><font color="#7F0055"><b>try</b></font>{<br> <br> <font color="#FFFFFF">   </font>cmd = parser.parse(options, args);<br> <br> <font color="#FFFFFF">  </font>}<br> <br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>catch</b></font>(ParseException pe) {<br> <br> <font color="#FFFFFF">   </font><font color= "#3F7F5F">//4.發生錯誤就用usage() method給使用這提示</font><br> <br> <font color="#FFFFFF">   </font>usage(options);</font><br></td> </tr> </tbody> </table> <p>上面我們預先設定了code,top price,low price的三個選項,當使用者有輸入三個值的時後,才讓程式運行,沒有輸入或是輸入不正確,少了那些項目之時,則列印出錯誤的訊息,來提醒使用者。這一個程式庫有一個好處是,我們定義好選項之後,其他的事情我們都不用多寫程式碼,比方說我們要印出輔助訊息的method,程式碼只有下面這幾行:</p> <br> <table border="1"> <tbody> <tr> <th>程式碼:</th> </tr> <tr> <td><font face="Courier New"><font color="#FFFFFF"> </font><b><font color= "#7F0055">private static</font></b></font> <font face= "Courier New"><font color="#7F0055"><b>void</b></font>usage(Optionsoptions) {<br> <font color="#FFFFFF">  </font>HelpFormatter formatter = <font color= "#7F0055"><b>new</b></font> HelpFormatter();<br> <br> <font color="#FFFFFF">  </font>formatter.printHelp(<font color= "#2A00FF">"CommandLineUI"</font>, options);<br> <br> <font color="#FFFFFF"> </font>}</font><br></td> </tr> </tbody> </table> <p>是不是相當的簡單呢?</p> <p> 接下來,我們要把在使用者所輸入的這三個值,一一的傳給之前所開發的程式,傳遞的方法,分別是:</p> <p>將code 傳給 網頁取得method</p> <p>將tp,lp傳給價格比較method</p> <p>程式碼如下所示:</p> <table border="1"> <tbody> <tr> <th>程式碼:</th> </tr> <tr> <td><font face="Courier New"><font color="#FFFFFF">  </font><b><font color= "#7F0055">if</font></b></font><font face= "Courier New">(cmd.hasOption(<font color="#2A00FF">"tp"</font>)){<br> <font color= "#FFFFFF">   </font>target_price=Float.parseFloat(cmd.getOptionValue(<font color="#2A00FF">"tp"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"lp"</font>)){<br> <font color= "#FFFFFF">   </font>low_price=Float.parseFloat(cmd.getOptionValue(<font color="#2A00FF">"lp"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"c"</font>)){<br> <font color= "#FFFFFF">   </font>code=Integer.parseInt(cmd.getOptionValue(<font color= "#2A00FF">"c"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//System.out.println("code = "+code);</font><br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">  </font><font color="#7F0055"><b>try</b></font>{<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>current= getCurrentValue(code);<br> <font color= "#FFFFFF">  </font>System.out.println(compareValues(code,current,target_price,low_price));<br> <font color="#FFFFFF">  </font>} <font color= "#7F0055"><b>catch</b></font>(Exception e) {<br> <font color="#FFFFFF">   </font>System.out.println(<font color= "#2A00FF">"Critical;"</font>+e.getMessage() );<br> <font color="#FFFFFF">  </font>}</font><br></td> </tr> </tbody> </table> <p> 在這個式裡我們將比較的結果利用system.out來作輸出,這結果會直接被傳送到stdout上,然後由nagios所接受。</p> <br> <br> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">還有也作出了下列的元件部屬圖</span></font></p> <div class="java" align="left"> <table border="1"> <tbody> <tr> <th>#元件部屬圖</th> </tr> </tbody> </table> </div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <th>#</th> <th>元件部屬圖</th> <th>#</th> </tr> <tr> <td>#</td> <td>#</td> <td>#</td> </tr> <tr> <td>#</td> <td> 由以上的圖可以看出,在黑盒子的部份是主要開發的原件,這個原件,而由於在server上要運行java的程式,需要設定一些路徑,所以為了簡單起見,小明寫了一個shell語言,來將執行時的複雜部份包裝起來。</td> <td>#</td> </tr> </tbody> </table> </div> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">我們將可以進行設定的部份以</span><span lang="EN-US"><font face="Century">java</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">語言來實作,將會是如以下的部份:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">因為需要接受語多的命令,所以採用了</span><span lang="EN-US"><font face="Century">common</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">之下的</span><span lang="EN-US"><font face= "Century">getopt</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這一個方便精巧的功具:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">程式碼如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這個工具可以幫助我們產生一些命令行,提示使用者該如何使用命令,以及讀取使用者的命令,非常的方便。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">還有,我們也知道股價的變動是一天不會超過或低於百分之七的,所以如果經裡的設定值,與現在的股價比起來,如果低於這個範圍,那我們就可以使得這一個插件休兵一天,不用一直去查詢網站。而相反的,如果說這一天的股價,很有可能到達這一個設定值,則我們就要希望能夠增加我們訪問這個股價的數量。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">將這一個邏輯以</span><span lang= "EN-US"><font face="Century">java</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">語言來作表示的話,將會是如下的範例:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">接下來是這個程式核心的邏輯部份,也就是我們要從網站上得到股價:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這個時候我們使用的是</span><span lang= "EN-US"><font face="Century">commons</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">程式庫的</span><span lang="EN-US"><font face= "Century">httpclient</font></span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">我們始我下面這一段程式碼來存取網站:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">程式碼將如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這個程式碼送出一個</span><span lang= "EN-US"><font face="Century">get</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">要求,從</span><span lang="EN-US"><font face= "Century">yahoo</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">網站上得到了台積電網頁。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這一個網頁,裡的第一行是股價,所以我們試著取得網頁上的第一行。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">程式碼如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">然後這一個股價的位置位於這一行的第三個</span><span lang="EN-US"><font face="Century">TDTAG</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">之間,所以我們利用一個簡單的</span><span lang="EN-US"><font face="Century">regexp</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">,來取得這一個股價的位置。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">到目前為止,我們已經完成了這一個插件的大半部份,接下來就是將它們組合起來,成為一個完整的程式:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">將這個程式放到</span><span lang= "EN-US"><font face="Century">nagios</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">的</span><span lang="EN-US"><font face= "Century">server</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">上,接著,進行編譯及測式:</span></font></p> <p class="java" align="left"><span lang="EN-US"><font face= "Century"><font size="3">javacxxxx</font></font></span></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">執行這個程式:</span></font></p> <p class="java" align="left"><span lang="EN-US"><font face= "Century"><font size="3">java–cpxxxxxxxxx</font></font></span></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">結果我們發現這一個結果:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">依照這一個命令所是示的,我們假設我們的股價是</span><span lang="EN-US"><font face="Century">100</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">元,作出以下的設定:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">結果</span><span lang="EN-US"><font face= "Century">nagios</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">反回了這一個結果:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">因為現在台積電的股價還低於設定值,所以</span><span lang="EN-US"><font face="Century">ok</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">接著我們假設我們的目標股價是</span><span lang="EN-US"><font face="Century">50</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">元</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">出現了下列這一個訊息:</span></font></p> <p class="java" align="left"><span lang="EN-US"><font face= "Century"><font size="3">critical</font></font></span></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">果然台積電的股價以經有點危險了。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">看來沒什麼問題了。接下來我們將這個</span><span lang="EN-US"><font face="Century">plugin</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">安裝到</span><span lang="EN-US"><font face= "Century">nagios</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">上。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">然後,如果這個股價超過了這一個臨界值之後,通當會超過之後就一直超過,或是超過之後又低回來,當股價超過之後,如果一直不停的發送信息也不是辦法。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">所以我們要對這個細節,來對</span><span lang="EN-US"><font face="Century">nagios</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">作出設定:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">設定檔如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">一切就緒之後,接下來我們打開畫面,出現了以下的場景:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">接下來的問題,如果要將這個</span><span lang="EN-US"><font face="Century">plug</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">擴充成不只讓台責電能夠使用,該怎麼作好?</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">我想很多程式高手們早就發覺該怎麼做了,不過我還是雞婆一下把這個程式碼給出來,看了這個程式完成之後,我們就可以將我們所想要注意的股票一隻一隻的登入上去:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">設定檔如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">畫面如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">不過,這一個程式還有一個問題,那就是程式股價如果到了設定值了,就會一直呈現緊急的狀態,當然,此時我們可以從新的設定我們的目標,或者是經由</span><span lang="EN-US"><font face="Century">cgi</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">來關閉股價的通知。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">或者,你也可以提供一個到達目標之後,自動再設定目標的超強大機能,不過這一個內容,就交由讀者來自行發揮了。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU"><br></span></font></p> <div class="java" align="left"><br> <br></div> <div class="java" align="left"> <table cellspacing="0" cellpadding="3" bgcolor="#FFFFFF" border="0"> <tbody> <tr><!-- start source code --> <td valign="top" align="left"><code><font color= "#7F0055"><b>package</b></font>com.kbmj.someproject;<br> <br> <font color="#7F0055"><b>import</b></font> java.io.BufferedReader;<br> <font color="#7F0055"><b>import</b></font> java.io.IOException;<br> <font color="#7F0055"><b>import</b></font> java.io.InputStream;<br> <font color="#7F0055"><b>import</b></font> java.io.InputStreamReader;<br> <br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.BasicParser;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.CommandLine;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.CommandLineParser;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.HelpFormatter;<br> <font color="#7F0055"><b>import</b></font> org.apache.commons.cli.Option;<br> <font color="#7F0055"><b>import</b></font> org.apache.commons.cli.Options;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.ParseException;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.httpclient.HttpClient;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.httpclient.HttpException;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.httpclient.HttpStatus;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.httpclient.methods.GetMethod;<br> <br> <font color="#7F0055"><b>public class</b></font> App {<br> <font color="#FFFFFF"> </font><font color= "#7F0055"><b>publicstatic</b></font> <font color= "#7F0055"><b>void</b></font>main(String args[]){<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>target_price = <font color="#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>low_price = <font color="#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>code=<font color="#990000">2330</font>;<br> <br> <font color="#FFFFFF">  </font>Options options = <font color= "#7F0055"><b>new</b></font> Options();<br> <font color="#FFFFFF">  </font><font color="#3F7F5F">//option 1</font><br> <font color="#FFFFFF">  </font>Option target_price_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color="#2A00FF">"tp"</font>, true,<br> <font color="#FFFFFF">    </font><font color= "#2A00FF">"TargetPrice,forexample -tp=58.5 "</font>);<br> <font color="#FFFFFF">  </font>target_price_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//  option2</font><br> <font color="#FFFFFF">  </font>options.addOption(target_price_opt);<br> <font color="#FFFFFF">  </font>Option low_price_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color="#2A00FF">"lp"</font>, true,<br> <font color="#FFFFFF">    </font><font color= "#2A00FF">"LowPrice,forexample -lp=58.5 "</font>);<br> <font color="#FFFFFF">  </font>low_price_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//  option3</font><br> <font color="#FFFFFF">  </font>options.addOption(low_price_opt);<br> <font color="#FFFFFF">  </font>Option code_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color= "#2A00FF">"c"</font>,true,<font color= "#2A00FF">"code,forexample-c=2330"</font>);<br> <font color="#FFFFFF">  </font>code_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font>options.addOption(code_opt);<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//3.然後parseinput</font><br> <br> <font color="#FFFFFF">  </font>CommandLineParser parser = <font color= "#7F0055"><b>new</b></font> BasicParser();<br> <br> <font color="#FFFFFF">  </font>CommandLine cmd;<br> <br> <font color="#FFFFFF">  </font><font color="#7F0055"><b>try</b></font>{<br> <br> <font color="#FFFFFF">   </font>cmd = parser.parse(options, args);<br> <br> <font color="#FFFFFF">  </font>}<br> <br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>catch</b></font>(ParseException pe) {<br> <br> <font color="#FFFFFF">   </font><font color= "#3F7F5F">//4.發生錯誤就用usage() method給使用這提示</font><br> <br> <font color="#FFFFFF">   </font>usage(options);<br> <br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>return</b></font>;<br> <br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color="#3F7F5F">//</font><br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"tp"</font>)){<br> <font color= "#FFFFFF">   </font>target_price=Float.parseFloat(cmd.getOptionValue(<font color="#2A00FF">"tp"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"lp"</font>)){<br> <font color= "#FFFFFF">   </font>low_price=Float.parseFloat(cmd.getOptionValue(<font color="#2A00FF">"lp"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"c"</font>)){<br> <font color= "#FFFFFF">   </font>code=Integer.parseInt(cmd.getOptionValue(<font color= "#2A00FF">"c"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//System.out.println("code = "+code);</font><br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">  </font><font color="#7F0055"><b>try</b></font>{<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>current= getCurrentValue(code);<br> <font color= "#FFFFFF">  </font>System.out.println(compareValues(code,current,target_price,low_price));<br> <font color="#FFFFFF">  </font>} <font color= "#7F0055"><b>catch</b></font>(Exception e) {<br> <font color="#FFFFFF">   </font>System.out.println(<font color= "#2A00FF">"Critical;"</font>+e.getMessage() );<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF"> </font>}<br> <br> <font color="#FFFFFF"> </font><font color= "#7F0055"><b>privatestatic</b></font> String compareValues(<font color= "#7F0055"><b>int</b></font>code , <font color= "#7F0055"><b>float</b></font>current, <font color= "#7F0055"><b>float</b></font>target_price , <font color= "#7F0055"><b>float</b></font> low_price ) {<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>status =-<font color="#990000">1</font>;<br> <font color="#FFFFFF">  </font>String result=<font color= "#2A00FF">"UNKNOWN"</font>;<br> <font color="#FFFFFF">  </font>String message=<font color= "#2A00FF">"["</font>+code +<font color= "#2A00FF">"]current:"</font>+current+<font color= "#2A00FF">",targetis"</font>+target_price+<font color= "#2A00FF">",lowis"</font>+low_price;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(current &gt; target_price ) status =<font color= "#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>elseif</b></font>(current &gt; low_price ) status =<font color= "#990000">1</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>elseif</b></font>(current &lt; low_price ) status =<font color= "#990000">2</font>;<br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>switch</b></font>(status) {<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">0</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"WARNING;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">1</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"OK;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">2</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"CRITICAL;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font>-<font color="#990000">1</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"UNKNOWN;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>return</b></font>result+message;<br> <font color="#FFFFFF"> </font>}<br> <br> <font color="#FFFFFF"> </font><font color= "#7F0055"><b>privatestatic</b></font> <font color= "#7F0055"><b>void</b></font>usage(Optionsoptions) {<br> <font color="#FFFFFF">  </font>HelpFormatter formatter = <font color= "#7F0055"><b>new</b></font> HelpFormatter();<br> <br> <font color="#FFFFFF">  </font>formatter.printHelp(<font color= "#2A00FF">"CommandLineUI"</font>, options);<br> <br> <font color="#FFFFFF"> </font>}<br> <font color="#FFFFFF"> </font><font color= "#7F0055"><b>privatestatic</b></font> <font color= "#7F0055"><b>float</b></font>getCurrentValue(<font color= "#7F0055"><b>int</b></font> code) <font color= "#7F0055"><b>throws</b></font>HttpException, IOException{<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>p=-<font color="#990000">1</font>;<br> <font color="#FFFFFF">  </font>String url=<font color= "#2A00FF">"http://tw.stock.yahoo.com/q/q?s="</font>+code;<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//HttpClientの生成</font><br> <font color="#FFFFFF">  </font>HttpClient client=<font color= "#7F0055"><b>new</b></font> HttpClient();<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//methodインスタンスの生成</font><br> <font color="#FFFFFF">  </font>GetMethod method = <font color= "#7F0055"><b>new</b></font> GetMethod(url);<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>statusCode = client.executeMethod(method);<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(statusCode != HttpStatus.SC_OK) {<br> <font color="#FFFFFF">   </font><font color="#3F7F5F">//notok;</font><br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>return</b></font> p;<br> <font color="#FFFFFF">   </font><font color= "#3F7F5F">//System.out.println("失敗:"+method.getStatusLine());</font><br> <font color="#FFFFFF">  </font>}<br> <font color="#3F7F5F">//  HTMLソースを取得</font><br> <font color= "#FFFFFF">  </font>InputStream responseBody=method.getResponseBodyAsStream();<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//getdatainnoXXX</font><br> <font color="#FFFFFF">  </font>BufferedReader br=<font color= "#7F0055"><b>new</b></font> BufferedReader(<font color= "#7F0055"><b>new</b></font> InputStreamReader(responseBody, <font color= "#2A00FF">"Big5"</font>) );<br> <font color="#FFFFFF">  </font>String line=<font color= "#7F0055"><b>null</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>line_no=<font color="#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>while</b></font>((line = br.readLine())!= <font color= "#7F0055"><b>null</b></font> ){<br> <font color="#FFFFFF">   </font>line_no++;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>if</b></font>(line_no ==<font color="#990000">164</font>){<br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">   </font><br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>return</b></font>p;<br> <font color="#FFFFFF"> </font>}<br> }</code></td> <!-- end source code --></tr> </tbody> </table> </div> <!-- = END of automatically generated HTML code = --> <!-- ======================================================== -->
<p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">在體驗完這個簡單的插件之後,接下來要登場的就是難度比較高一點的插件了。插件可以被任何語言所寫成,只要它是能被執行,並且反回特定格式的訊息,它的內容是</span><span lang="EN-US"><font face="Century">c</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">也好,</span><span lang="EN-US"><font face= "Century">java</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">也好,</span><span lang="EN-US"><font face= "Century">perl</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">也好,都是被允許的。用什麼語言來實作並不是一件重要的事,只要能夠達成我們想要的目的,就算及格,所以對java不熟的讀者,看到這一章也不用灰心,因為只要你懂了觀念,你可以用你所會的語言,來將這一個插件,進行改寫。</span></font></p> <div class="java" align="left"> <hr></div> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">●需求定義與設計</span></font></p> <p class="java" align="left"> 所有的插件的產生,都是來自於需求。</p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">假設,有一天,在上班的時後,專案經理對小明提出了一個要求,希望小明能夠利用nagios完美的性能,開發出一個定期監視台積電的股價的插件,並且在股價發生變動時,發一封信通知專案經理進場護盤。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">接到這一個要求的小明馬上就列出了下面這一個規格書,並且請經理作確認:</span></font></p> <div class="java" align="left"> <table style="WIDTH: 505px; HEIGHT: 38px" border="1"> <tbody> <tr> <td> <p><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">輸入:股票代碼目標價 停損價</span></p> <p><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">輸出:當股票現值超過目標價,則輸出警告,低於停損價,則發出危急</span></p> </td> </tr> </tbody> </table> </div> <div class="java" align="left"> 雖然經理只對台積電的股價有興趣,但是身為工程師的小明,總是想到軟體工程的一大守則,原件的重用性,所以,小明決定不要把程式碼寫死,留下空間讓專案經理來自行設定。</div> <div class="java" align="left"> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">在這個簡單的介面定義書裡,我們也提供了高值與低值的設定選項,因為我們不曉得專案經理對於股價的企圖心在那裡,所以我們把這個設定值空出來讓經裡自行設定。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">與專案經理進行確認之後,就開始要準備進行開發的工作。</span></font></span></font></p> <hr> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">●開發</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">小明評估了需求,以及時間,決定爭取時效,使用有很多方便的程式庫的</span><span lang="EN-US"><font face="Century">java語言,來作為開發的工具。</font></span></font></p> <hr> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US">第一步:取得即時的股價:</span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US">為了要知道股票目前最近的股價,唯一的來源就是一些入口網站提供的服務了。所以小明決定到yahoo財經,來取得即時的股價。比方說,台積電的股價,只要訪問下列這一個網站,就可以得到所需的資料了。</span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US"><a href= "http://tw.stock.yahoo.com/q/q?s=2330">http://tw.stock.yahoo.com/q/q?s=2330</a></span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US">為了要能夠及時的去把這一個網頁的資料抓回來,小明決定使用由JakartaCommons所提供的HttpClient程式庫。這一個專案的網頁位在</span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US"><a href= "http://jakarta.apache.org/commons/httpclient/">http://jakarta.apache.org/commons/httpclient/</a></span></font></p> <p class="java" align="left"><font face="Century" size="3"><span lang= "EN-US">在下載回來之後,小明使用了這個程式庫,寫了一段抓取網頁的程式碼:</span></font></p> <table border="1"> <tbody> <tr> <td><br> <p>程式碼:</p> <font face="Courier New">String url="<a href= "http://tw.stock.yahoo.com/q/q?s=2330"><font color= "#2A00FF">http://tw.stock.yahoo.com/q/q?s=2330</font></a>";<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//生成一個httpclient的物件</font><br> <font color="#FFFFFF">  </font>HttpClient client=<font color= "#7F0055"><b>new</b></font> HttpClient();<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//生成一個get方法的物件</font><br> <font color="#FFFFFF">  </font>GetMethod method = <font color= "#7F0055"><b>new</b></font> GetMethod(url);<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>statusCode = client.executeMethod(method);<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(statusCode != HttpStatus.SC_OK) {<br> <font color="#FFFFFF">   </font><font color= "#3F7F5F">//如果訪問失敗時的處理;</font><br> <font color="#FFFFFF">   </font> <font color= "#3F7F5F">System.out.println("失敗:"+method.getStatusLine());</font><br> <font color="#FFFFFF">  </font>}<br> <font color= "#3F7F5F">//網頁連線成功,開始取得網頁的資料  </font></font> <p><font face="Courier New"><font color= "#FFFFFF">  </font>InputStream responseBody=method.getResponseBodyAsStream();<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//使用中文的編碼,準備將網頁讀進來</font><br> <font color="#FFFFFF">  </font>BufferedReader br=<font color= "#7F0055"><b>new</b></font> BufferedReader(<font color= "#7F0055"><b>new</b></font> InputStreamReader(responseBody, <font color= "#2A00FF">"Big5"</font>) );</font><br> <br></p> <br></td> </tr> </tbody> </table> <p class="java" align="left"> 網頁讀取進來之後,一大段的文字並沒有什麼實用的價值,小明必須要想辦法在這一大段的文字裡,找到一個專案經裡所關心的資訊,也就是當時的股價。此時考慮到時效性,小明決定不採用由另外一個專案所提供的html解析套件,改採暴力破解法。</p> <p class="java" align="left"> 小明使用了文字編輯器,將取得的html原始碼一行一行的往下數下來時,發現當前的股價所記載的位置,正好是在第164行的位置。於是,小明寫了一個回圈,來將取得的大段文章裡,找到164行的內容。正可謂是,股海淘淘,只取一飄呀!</p> <table border="1"> <tbody> <tr> <td> <p>程式碼:</p> <font face="Courier New"><font color= "#FFFFFF"> </font>BufferedReaderbr=<font color= "#7F0055"><b>new</b></font>BufferedReader(<font color= "#7F0055"><b>new</b></font>InputStreamReader(responseBody, <font color= "#2A00FF">"Big5"</font>) );<br> <font color="#FFFFFF">  </font>String line=<font color= "#7F0055"><b>null</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>line_no=<font color="#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>while</b></font>((line = br.readLine())!= <font color= "#7F0055"><b>null</b></font> ){<br> <font color="#FFFFFF">   </font>line_no++;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>if</b></font>(line_no ==<font color="#990000">164</font>){<br> <font color="#FFFFFF">  </font></font><br> <br></td> </tr> </tbody> </table> </div> <div class="java" align="left"></div> <div class="java" align="left"> 取回來的這一飄,長的像這個樣子:</div> <div class="java" align="left"></div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <td> &lt;tdalign="center"bgcolor="#FFFfff"nowrap&gt;&lt;b&gt;<strong>54.00</strong>&lt;/b&gt;&lt;/td&gt;</td> </tr> </tbody> </table> </div> <div class="java" align="left"></div> <div class="java" align="left"> 在重重包圍之下的那個54.00,就是我們最終想要得到的結果了。</div> <div class="java" align="left"></div> <div class="java" align="left"> 此時只好在對這一行文字進行第二次的加工,將不需要的部分去除,只留下我們想要的。</div> <div class="java" align="left"></div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <th>程式碼 3</th> </tr> <tr> <td>#</td> </tr> </tbody> </table> </div> <div class="java" align="left"></div> <div class="java" align="left"></div> <div class="java" align="left"> 進行到這裡,小明已經將取得股價的原件給制作完成了,把他整合成一個method,程式碼如下方所示:</div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <th>程式碼 4:用來取得即時股價的方法</th> </tr> <tr> <td>#</td> </tr> </tbody> </table> </div> <div class="java" align="left"> 小明程式寫到這裡,覺得松了一口氣,因為核心的部份已經完成了一大部份了。他決定到樓下的starbuck買杯咖啡,順便上個廁所,在回來寫下面的一段。</div> <div class="java" align="left"></div> <div class="java" align="left"> <hr></div> <div class="java" align="left">第二部:比較股價,產生輸出</div> <div class="java" align="left"></div> <div class="java" align="left"> 回到位子上之後,小明開始進行第二階段的開發,也就是將剛剛所得到的即時價格,來與設定的高值,低值,作一個比較,如果高值大於現在值,則反回警告,如果現在值小於低值,則發出危險訊號,通知專案經理作停損。</div> <div class="java" align="left">代碼如下所示:</div> <div class="java" align="left"></div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <td>程式碼:價何比較的方法</td> </tr> <tr> <td><font face="Courier New"><strong><font color= "#7F0055">privatestatic</font></strong> String compareValues(<font color= "#7F0055"><b>int</b></font>code , <font color= "#7F0055"><b>float</b></font>current, <font color= "#7F0055"><b>float</b></font>target_price , <font color= "#7F0055"><b>float</b></font> low_price ) {<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>status =-<font color="#990000">1</font>;<br> <font color="#FFFFFF">  </font>String result=<font color= "#2A00FF">"UNKNOWN"</font>;<br> <font color="#FFFFFF">  </font>String message=<font color= "#2A00FF">"["</font>+code +<font color= "#2A00FF">"]current:"</font>+current+<font color= "#2A00FF">",targetis"</font>+target_price+<font color= "#2A00FF">",lowis"</font>+low_price;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(current &gt; target_price ) status =<font color= "#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>elseif</b></font>(current &gt; low_price ) status =<font color= "#990000">1</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>elseif</b></font>(current &lt; low_price ) status =<font color= "#990000">2</font>;<br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>switch</b></font>(status) {<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">0</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"WARNING;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">1</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"OK;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">2</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"CRITICAL;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font>-<font color="#990000">1</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"UNKNOWN;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>return</b></font>result+message;<br> <font color="#FFFFFF"> </font>}</font><br></td> </tr> </tbody> </table> </div> <div class="java" align="left"></div> <div class="java" align="left"></div> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">在以上的方法裡我們作了二件事情,一件事是價格比較,另一件事將結果以nagios所規定的格式與以反回,並且報知目前的價格,以便讓使用者可以在cgi的畫面上得到更多的資訊。</span></font></p> <p class="java" align="left">?</p> <p class="java" align="left">?</p> <hr> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">三、選項的讀取</span></font></p> <p class="java" align="left"> 在前面的二個步驟之後,接下來所剩下的,就是讀取外部的選項了。在之前的介面定義書裡,我們知道這個程式需要接受三個選項,而且我們也決定要遵守開發的原則,在使用者輸入了錯誤的選項之時,能夠回送出適當的提示訊息,所以我們決定,使用由<font face="Century">由JakartaCommons所提供的<a name="CLI : Command Line Interface"><font face="Times New Roman">CLI:Command LineInterface</font></a>程式庫。這一個專案的網頁位在</font></p> <p class="java" align="left"><a href= "http://jakarta.apache.org/commons/cli/">http://jakarta.apache.org/commons/cli/</a></p> <p class="java" align="left"> 在參照了文件的說明之後,小明依照需求,寫出了如下的程式碼:</p> <p class="java" align="left">?</p> <p class="java" align="left">?</p> <table border="1"> <tbody> <tr> <th>程式碼:</th> </tr> <tr> <td><font face="Courier New"><font color="#FFFFFF"> </font>Options options =<font color="#7F0055"><b>new</b></font> Options();<br> <font color="#FFFFFF">  </font><font color="#3F7F5F">//option 1</font><br> <font color="#FFFFFF">  </font>Option target_price_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color="#2A00FF">"tp"</font>, true,<br> <font color="#FFFFFF">    </font><font color= "#2A00FF">"TargetPrice,forexample -tp=58.5 "</font>);<br> <font color="#FFFFFF">  </font>target_price_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//  option2</font><br> <font color="#FFFFFF">  </font>options.addOption(target_price_opt);<br> <font color="#FFFFFF">  </font>Option low_price_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color="#2A00FF">"lp"</font>, true,<br> <font color="#FFFFFF">    </font><font color= "#2A00FF">"LowPrice,forexample -lp=58.5 "</font>);<br> <font color="#FFFFFF">  </font>low_price_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//  option3</font><br> <font color="#FFFFFF">  </font>options.addOption(low_price_opt);<br> <font color="#FFFFFF">  </font>Option code_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color= "#2A00FF">"c"</font>,true,<font color= "#2A00FF">"code,forexample-c=2330"</font>);<br> <font color="#FFFFFF">  </font>code_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font>options.addOption(code_opt);<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//3.然後parseinput</font><br> <br> <font color="#FFFFFF">  </font>CommandLineParser parser = <font color= "#7F0055"><b>new</b></font> BasicParser();<br> <br> <font color="#FFFFFF">  </font>CommandLine cmd;<br> <br> <font color="#FFFFFF">  </font><font color="#7F0055"><b>try</b></font>{<br> <br> <font color="#FFFFFF">   </font>cmd = parser.parse(options, args);<br> <br> <font color="#FFFFFF">  </font>}<br> <br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>catch</b></font>(ParseException pe) {<br> <br> <font color="#FFFFFF">   </font><font color= "#3F7F5F">//4.發生錯誤就用usage() method給使用這提示</font><br> <br> <font color="#FFFFFF">   </font>usage(options);</font><br></td> </tr> </tbody> </table> <p>上面我們預先設定了code,top price,lowprice的三個選項,當使用者有輸入三個值的時後,才讓程式運行,沒有輸入或是輸入不正確,少了那些項目之時,則列印出錯誤的訊息,來提醒使用者。這一個程式庫有一個好處是,我們定義好選項之後,其他的事情我們都不用多寫程式碼,比方說我們要印出輔助訊息的method,程式碼只有下面這幾行:</p> <br> <table border="1"> <tbody> <tr> <th>程式碼:</th> </tr> <tr> <td><font face="Courier New"><font color="#FFFFFF"> </font><b><font color= "#7F0055">private static</font></b></font> <font face= "Courier New"><font color="#7F0055"><b>void</b></font>usage(Optionsoptions){<br> <font color="#FFFFFF">  </font>HelpFormatter formatter = <font color= "#7F0055"><b>new</b></font> HelpFormatter();<br> <br> <font color="#FFFFFF">  </font>formatter.printHelp(<font color= "#2A00FF">"CommandLineUI"</font>, options);<br> <br> <font color="#FFFFFF"> </font>}</font><br></td> </tr> </tbody> </table> <p>是不是相當的簡單呢?</p> <p> 接下來,我們要把在使用者所輸入的這三個值,一一的傳給之前所開發的程式,傳遞的方法,分別是:</p> <p>將code 傳給 網頁取得method</p> <p>將tp,lp傳給價格比較method</p> <p>程式碼如下所示:</p> <table border="1"> <tbody> <tr> <th>程式碼:</th> </tr> <tr> <td><font face="Courier New"><font color="#FFFFFF">  </font><b><font color= "#7F0055">if</font></b></font><font face= "Courier New">(cmd.hasOption(<font color="#2A00FF">"tp"</font>)){<br> <font color= "#FFFFFF">   </font>target_price=Float.parseFloat(cmd.getOptionValue(<font color="#2A00FF">"tp"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"lp"</font>)){<br> <font color= "#FFFFFF">   </font>low_price=Float.parseFloat(cmd.getOptionValue(<font color="#2A00FF">"lp"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"c"</font>)){<br> <font color= "#FFFFFF">   </font>code=Integer.parseInt(cmd.getOptionValue(<font color= "#2A00FF">"c"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//System.out.println("code = "+code);</font><br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">  </font><font color="#7F0055"><b>try</b></font>{<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>current= getCurrentValue(code);<br> <font color= "#FFFFFF">  </font>System.out.println(compareValues(code,current,target_price,low_price));<br> <font color="#FFFFFF">  </font>} <font color= "#7F0055"><b>catch</b></font>(Exception e) {<br> <font color="#FFFFFF">   </font>System.out.println(<font color= "#2A00FF">"Critical;"</font>+e.getMessage() );<br> <font color="#FFFFFF">  </font>}</font><br></td> </tr> </tbody> </table> <p> 在這個式裡我們將比較的結果利用system.out來作輸出,這結果會直接被傳送到stdout上,然後由nagios所接受。</p> <p> 到此,小明已經完成了核心程式的工作,在此我們先將完整的程式碼給列出來:</p> <table border="1"> <tbody> <tr> <td>股價監視程式完整程式列表:</td> </tr> <tr> <td>#</td> </tr> </tbody> </table> <p> 接下來我們要進行編譯的動作,由於這個程式我們用到了</p> <p>1 httpclient</p> <p>2 cli</p> <p> 這兩個程式庫,所以我們在編譯時,必須要將這兩個含式庫加到路徑裡面:</p> <table border="1"> <tbody> <tr> <td>javac -cp XXXX.jar:XXXXX.jar :./ App.java</td> </tr> </tbody> </table> <p> 完成之後,我們試著執行所產生的class檔,注意,因為我們程式碼裡有引用這兩個程式庫,所以執行之時,也一樣要在路徑裡作宣告。</p> <table border="1"> <tbody> <tr> <td>java -cp XXXX.jar:XXXXX.jar :./ App</td> </tr> </tbody> </table> <p> 此時,因為我們什麼都沒有輸入,所以依照所排演的,應該要吐出一些訊息:</p> <br> <p><br> <br></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">還有也作出了下列的元件部屬圖</span></font></p> <div class="java" align="left"> <table border="1"> <tbody> <tr> <th>#元件部屬圖</th> </tr> </tbody> </table> </div> <div class="java" align="left"> <table border="1"> <tbody> <tr> <th>#</th> <th>元件部屬圖</th> <th>#</th> </tr> <tr> <td>#</td> <td>#</td> <td>#</td> </tr> <tr> <td>#</td> <td> 由以上的圖可以看出,在黑盒子的部份是主要開發的原件,這個原件,而由於在server上要運行java的程式,需要設定一些路徑,所以為了簡單起見,小明寫了一個shell語言,來將執行時的複雜部份包裝起來。</td> <td>#</td> </tr> </tbody> </table> </div> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">我們將可以進行設定的部份以</span><span lang="EN-US"><font face="Century">java</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">語言來實作,將會是如以下的部份:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">因為需要接受語多的命令,所以採用了</span><span lang="EN-US"><font face="Century">common</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">之下的</span><span lang="EN-US"><font face= "Century">getopt</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這一個方便精巧的功具:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">程式碼如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這個工具可以幫助我們產生一些命令行,提示使用者該如何使用命令,以及讀取使用者的命令,非常的方便。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">還有,我們也知道股價的變動是一天不會超過或低於百分之七的,所以如果經裡的設定值,與現在的股價比起來,如果低於這個範圍,那我們就可以使得這一個插件休兵一天,不用一直去查詢網站。而相反的,如果說這一天的股價,很有可能到達這一個設定值,則我們就要希望能夠增加我們訪問這個股價的數量。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">將這一個邏輯以</span><span lang= "EN-US"><font face="Century">java</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">語言來作表示的話,將會是如下的範例:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">接下來是這個程式核心的邏輯部份,也就是我們要從網站上得到股價:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這個時候我們使用的是</span><span lang= "EN-US"><font face="Century">commons</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">程式庫的</span><span lang="EN-US"><font face= "Century">httpclient</font></span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">我們始我下面這一段程式碼來存取網站:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">程式碼將如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這個程式碼送出一個</span><span lang= "EN-US"><font face="Century">get</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">要求,從</span><span lang="EN-US"><font face= "Century">yahoo</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">網站上得到了台積電網頁。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">這一個網頁,裡的第一行是股價,所以我們試著取得網頁上的第一行。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">程式碼如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">然後這一個股價的位置位於這一行的第三個</span><span lang="EN-US"><font face="Century">TDTAG</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">之間,所以我們利用一個簡單的</span><span lang="EN-US"><font face="Century">regexp</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">,來取得這一個股價的位置。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">到目前為止,我們已經完成了這一個插件的大半部份,接下來就是將它們組合起來,成為一個完整的程式:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">將這個程式放到</span><span lang= "EN-US"><font face="Century">nagios</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">的</span><span lang="EN-US"><font face= "Century">server</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">上,接著,進行編譯及測式:</span></font></p> <p class="java" align="left"><span lang="EN-US"><font face= "Century"><font size="3">javacxxxx</font></font></span></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">執行這個程式:</span></font></p> <p class="java" align="left"><span lang="EN-US"><font face= "Century"><font size="3">java–cpxxxxxxxxx</font></font></span></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">結果我們發現這一個結果:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">依照這一個命令所是示的,我們假設我們的股價是</span><span lang="EN-US"><font face="Century">100</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">元,作出以下的設定:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">結果</span><span lang="EN-US"><font face= "Century">nagios</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">反回了這一個結果:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">因為現在台積電的股價還低於設定值,所以</span><span lang="EN-US"><font face="Century">ok</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">接著我們假設我們的目標股價是</span><span lang="EN-US"><font face="Century">50</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">元</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">出現了下列這一個訊息:</span></font></p> <p class="java" align="left"><span lang="EN-US"><font face= "Century"><font size="3">critical</font></font></span></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">果然台積電的股價以經有點危險了。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">看來沒什麼問題了。接下來我們將這個</span><span lang="EN-US"><font face="Century">plugin</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">安裝到</span><span lang="EN-US"><font face= "Century">nagios</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">上。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">然後,如果這個股價超過了這一個臨界值之後,通當會超過之後就一直超過,或是超過之後又低回來,當股價超過之後,如果一直不停的發送信息也不是辦法。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">所以我們要對這個細節,來對</span><span lang="EN-US"><font face="Century">nagios</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">作出設定:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">設定檔如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">一切就緒之後,接下來我們打開畫面,出現了以下的場景:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">接下來的問題,如果要將這個</span><span lang="EN-US"><font face="Century">plug</font></span><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">擴充成不只讓台責電能夠使用,該怎麼作好?</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">我想很多程式高手們早就發覺該怎麼做了,不過我還是雞婆一下把這個程式碼給出來,看了這個程式完成之後,我們就可以將我們所想要注意的股票一隻一隻的登入上去:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">設定檔如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">畫面如下所示:</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">不過,這一個程式還有一個問題,那就是程式股價如果到了設定值了,就會一直呈現緊急的狀態,當然,此時我們可以從新的設定我們的目標,或者是經由</span><span lang="EN-US"><font face="Century">cgi</font></span><span lang="ZH-TW" style="FONT-FAMILY: PMingLiU">來關閉股價的通知。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU">或者,你也可以提供一個到達目標之後,自動再設定目標的超強大機能,不過這一個內容,就交由讀者來自行發揮了。</span></font></p> <p class="java" align="left"><font size="3"><span lang="ZH-TW" style= "FONT-FAMILY: PMingLiU"><br></span></font></p> <div class="java" align="left"><br> <br></div> <div class="java" align="left"> <table cellspacing="0" cellpadding="3" bgcolor="#FFFFFF" border="0"> <tbody> <tr><!-- start source code --> <td valign="top" align="left"><code><font color= "#7F0055"><b>package</b></font>com.kbmj.someproject;<br> <br> <font color="#7F0055"><b>import</b></font> java.io.BufferedReader;<br> <font color="#7F0055"><b>import</b></font> java.io.IOException;<br> <font color="#7F0055"><b>import</b></font> java.io.InputStream;<br> <font color="#7F0055"><b>import</b></font> java.io.InputStreamReader;<br> <br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.BasicParser;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.CommandLine;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.CommandLineParser;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.HelpFormatter;<br> <font color="#7F0055"><b>import</b></font> org.apache.commons.cli.Option;<br> <font color="#7F0055"><b>import</b></font> org.apache.commons.cli.Options;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.cli.ParseException;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.httpclient.HttpClient;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.httpclient.HttpException;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.httpclient.HttpStatus;<br> <font color= "#7F0055"><b>import</b></font>org.apache.commons.httpclient.methods.GetMethod;<br> <br> <font color="#7F0055"><b>public class</b></font> App {<br> <font color="#FFFFFF"> </font><font color= "#7F0055"><b>publicstatic</b></font> <font color= "#7F0055"><b>void</b></font>main(String args[]){<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>target_price = <font color="#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>low_price = <font color="#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>code=<font color="#990000">2330</font>;<br> <br> <font color="#FFFFFF">  </font>Options options = <font color= "#7F0055"><b>new</b></font> Options();<br> <font color="#FFFFFF">  </font><font color="#3F7F5F">//option 1</font><br> <font color="#FFFFFF">  </font>Option target_price_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color="#2A00FF">"tp"</font>, true,<br> <font color="#FFFFFF">    </font><font color= "#2A00FF">"TargetPrice,forexample -tp=58.5 "</font>);<br> <font color="#FFFFFF">  </font>target_price_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//  option2</font><br> <font color="#FFFFFF">  </font>options.addOption(target_price_opt);<br> <font color="#FFFFFF">  </font>Option low_price_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color="#2A00FF">"lp"</font>, true,<br> <font color="#FFFFFF">    </font><font color= "#2A00FF">"LowPrice,forexample -lp=58.5 "</font>);<br> <font color="#FFFFFF">  </font>low_price_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//  option3</font><br> <font color="#FFFFFF">  </font>options.addOption(low_price_opt);<br> <font color="#FFFFFF">  </font>Option code_opt = <font color= "#7F0055"><b>new</b></font> Option(<font color= "#2A00FF">"c"</font>,true,<font color= "#2A00FF">"code,forexample-c=2330"</font>);<br> <font color="#FFFFFF">  </font>code_opt.setRequired(<font color= "#7F0055"><b>true</b></font> );<br> <font color="#FFFFFF">  </font>options.addOption(code_opt);<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//3.然後parseinput</font><br> <br> <font color="#FFFFFF">  </font>CommandLineParser parser = <font color= "#7F0055"><b>new</b></font> BasicParser();<br> <br> <font color="#FFFFFF">  </font>CommandLine cmd;<br> <br> <font color="#FFFFFF">  </font><font color="#7F0055"><b>try</b></font>{<br> <br> <font color="#FFFFFF">   </font>cmd = parser.parse(options, args);<br> <br> <font color="#FFFFFF">  </font>}<br> <br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>catch</b></font>(ParseException pe) {<br> <br> <font color="#FFFFFF">   </font><font color= "#3F7F5F">//4.發生錯誤就用usage() method給使用這提示</font><br> <br> <font color="#FFFFFF">   </font>usage(options);<br> <br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>return</b></font>;<br> <br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color="#3F7F5F">//</font><br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"tp"</font>)){<br> <font color= "#FFFFFF">   </font>target_price=Float.parseFloat(cmd.getOptionValue(<font color="#2A00FF">"tp"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"lp"</font>)){<br> <font color= "#FFFFFF">   </font>low_price=Float.parseFloat(cmd.getOptionValue(<font color="#2A00FF">"lp"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(cmd.hasOption(<font color= "#2A00FF">"c"</font>)){<br> <font color= "#FFFFFF">   </font>code=Integer.parseInt(cmd.getOptionValue(<font color= "#2A00FF">"c"</font>));<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//System.out.println("code = "+code);</font><br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">  </font><font color="#7F0055"><b>try</b></font>{<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>current= getCurrentValue(code);<br> <font color= "#FFFFFF">  </font>System.out.println(compareValues(code,current,target_price,low_price));<br> <font color="#FFFFFF">  </font>} <font color= "#7F0055"><b>catch</b></font>(Exception e) {<br> <font color="#FFFFFF">   </font>System.out.println(<font color= "#2A00FF">"Critical;"</font>+e.getMessage() );<br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF"> </font>}<br> <br> <font color="#FFFFFF"> </font><font color= "#7F0055"><b>privatestatic</b></font> String compareValues(<font color= "#7F0055"><b>int</b></font>code , <font color= "#7F0055"><b>float</b></font>current, <font color= "#7F0055"><b>float</b></font>target_price , <font color= "#7F0055"><b>float</b></font> low_price ) {<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>status =-<font color="#990000">1</font>;<br> <font color="#FFFFFF">  </font>String result=<font color= "#2A00FF">"UNKNOWN"</font>;<br> <font color="#FFFFFF">  </font>String message=<font color= "#2A00FF">"["</font>+code +<font color= "#2A00FF">"]current:"</font>+current+<font color= "#2A00FF">",targetis"</font>+target_price+<font color= "#2A00FF">",lowis"</font>+low_price;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(current &gt; target_price ) status =<font color= "#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>elseif</b></font>(current &gt; low_price ) status =<font color= "#990000">1</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>elseif</b></font>(current &lt; low_price ) status =<font color= "#990000">2</font>;<br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>switch</b></font>(status) {<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">0</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"WARNING;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">1</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"OK;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font><font color="#990000">2</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"CRITICAL;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>case</b></font>-<font color="#990000">1</font>:<br> <font color="#FFFFFF">   </font>result=<font color= "#2A00FF">"UNKNOWN;"</font>;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>break</b></font>;<br> <br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>return</b></font>result+message;<br> <font color="#FFFFFF"> </font>}<br> <br> <font color="#FFFFFF"> </font><font color= "#7F0055"><b>privatestatic</b></font> <font color= "#7F0055"><b>void</b></font>usage(Optionsoptions) {<br> <font color="#FFFFFF">  </font>HelpFormatter formatter = <font color= "#7F0055"><b>new</b></font> HelpFormatter();<br> <br> <font color="#FFFFFF">  </font>formatter.printHelp(<font color= "#2A00FF">"CommandLineUI"</font>, options);<br> <br> <font color="#FFFFFF"> </font>}<br> <font color="#FFFFFF"> </font><font color= "#7F0055"><b>privatestatic</b></font> <font color= "#7F0055"><b>float</b></font>getCurrentValue(<font color= "#7F0055"><b>int</b></font> code) <font color= "#7F0055"><b>throws</b></font>HttpException, IOException{<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>float</b></font>p=-<font color="#990000">1</font>;<br> <font color="#FFFFFF">  </font>String url=<font color= "#2A00FF">"http://tw.stock.yahoo.com/q/q?s="</font>+code;<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//HttpClientの生成</font><br> <font color="#FFFFFF">  </font>HttpClient client=<font color= "#7F0055"><b>new</b></font> HttpClient();<br> <br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//methodインスタンスの生成</font><br> <font color="#FFFFFF">  </font>GetMethod method = <font color= "#7F0055"><b>new</b></font> GetMethod(url);<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>statusCode = client.executeMethod(method);<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>if</b></font>(statusCode != HttpStatus.SC_OK) {<br> <font color="#FFFFFF">   </font><font color="#3F7F5F">//notok;</font><br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>return</b></font> p;<br> <font color="#FFFFFF">   </font><font color= "#3F7F5F">//System.out.println("失敗:"+method.getStatusLine());</font><br> <font color="#FFFFFF">  </font>}<br> <font color="#3F7F5F">//  HTMLソースを取得</font><br> <font color= "#FFFFFF">  </font>InputStream responseBody=method.getResponseBodyAsStream();<br> <font color="#FFFFFF">  </font><font color= "#3F7F5F">//getdatainnoXXX</font><br> <font color="#FFFFFF">  </font>BufferedReader br=<font color= "#7F0055"><b>new</b></font> BufferedReader(<font color= "#7F0055"><b>new</b></font> InputStreamReader(responseBody, <font color= "#2A00FF">"Big5"</font>) );<br> <font color="#FFFFFF">  </font>String line=<font color= "#7F0055"><b>null</b></font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>int</b></font>line_no=<font color="#990000">0</font>;<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>while</b></font>((line = br.readLine())!= <font color= "#7F0055"><b>null</b></font> ){<br> <font color="#FFFFFF">   </font>line_no++;<br> <font color="#FFFFFF">   </font><font color= "#7F0055"><b>if</b></font>(line_no ==<font color="#990000">164</font>){<br> <font color="#FFFFFF">  </font><br> <font color="#FFFFFF">   </font><br> <font color="#FFFFFF">  </font>}<br> <font color="#FFFFFF">  </font><font color= "#7F0055"><b>return</b></font>p;<br> <font color="#FFFFFF"> </font>}<br> }</code></td> <!-- end source code --></tr> </tbody> </table> </div> <!-- = END of automatically generated HTML code = --> <!-- ======================================================== -->

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。