java調用jruby擷取網頁內容(JDK1.5)

來源:互聯網
上載者:User

   有4台測試機器通過是通過路由器上網的,路由器通過撥號方式上網。每隔一段時間,就會重新撥號,在其自動撥號後,IP即發生變化,必須跑到機房查看路由器的公網ip後才能進行遠端連線。

   最初打算在路由器後面的機器上執行tracert www.sina.com.cn 命令來找到路由器的ip,然後自動發送郵件給相關人員。 然而在測試機上執行tracert命令不能跟蹤到路由ip,時間緊迫,於是想到一個比較笨的辦法,去訪問一些可以顯示請求機器公網ip的頁面,然後把頁面的內容抓取下來發郵件給大家。 該程式已用java實現,但是略感複雜。周末無事,想想能否通過ruby來訪問網頁擷取ip地址,然後java來發送郵件。下面是實踐過程:

   我裝的JDK是1.5,因此需要首先下載以下的包:

   1)下載JRUBY包,是:http://dist.codehaus.org/jruby/1.1.6/,我下載的是最新的1.1.6版本,要注意的是一定要下載jruby-complete-1.1.6.jar包,這個完整的包裡才有依賴的一些.rb檔案

    2) 下載JSR 223相關包,是:http://www.jcp.org/en/jsr/detail?id=223,

下載最新的發布版本,在這個包裡有script-api.jar(JSR 223的實現包)、script-js.jar(Rhino的engine實現)和js.jar(Rhino)三個jar檔案,都需要加入classhpath。注意:如果你使用的是JDK 1.6,那麼1.6已經整合了JSR 223,所以不需要額外引入script-api.jar和script-js.jar,js.jar還是需要引入的。三個包之間的關係是:script-api.jar是面向最終的開發人員的,script-js.jar是一個代理,把最終的指令碼解析轉寄給js.jar,包括其它指令碼的支援也是這種模式,比如要對JRuby支援,也肯定有一個按規範實現的代理。

    3)下載JRuby的代理,https://scripting.dev.java.net/servlets/ProjectDocumentList,檔案jsr223-engines.zip裡包含了各種代理,在jruby/build目錄下存在jruby-engine.jar檔案,加入到classpath。

    4)下載一個可選的輔助jar包,因為代碼中用到了StringUtils類,從apache網站下載commons-lang-2.4.jar包,也加入到classpath

 

編寫JAVA代碼:

 

import java.util.*;
import java.io.*;
import javax.script.*;
import com.sun.script.jruby.JRubyScriptEngineManager;
import org.apache.commons.lang.StringUtils;
import java.nio.charset.*;

public class Main
{
 public static void main(String args[])
 { 
    System.out.println("----------"+System.getProperty("file.encoding"));
    long start = System.currentTimeMillis();
    
    // 取得指令碼引擎的管理器,用來擷取對應的引擎,如下面的jruby

    //因為安裝的是JDK1.5,所以要用JRubyScriptEngineManager 代替ScriptEngine ,否者編譯不通過
    JRubyScriptEngineManager manager = new JRubyScriptEngineManager();
    
    // 設定上下文參數
    Hashtable<String, String> params = new Hashtable<String, String>();
    params.put("id", "testID"); // JRuby會把請求響應結果放在指定的ID中,Java代碼從中擷取
    params.put("url", "http://www.google.cn"); // HTTP請求地址
    try {
    
        // 根據指定的名字"jruby"擷取指令碼引擎
       
        ScriptEngine jrubyEngine = manager.getEngineByName("jruby");
        jrubyEngine.put("params", params); // 把參數放置在上下文中
    
        // 執行HTTPService.rb中的指令碼
        Object value = jrubyEngine.eval(new InputStreamReader(
            Main.class.getResourceAsStream("getIP.rb"))
        );
    
        // 根據指定的ID,從引擎中提取響應結果
        Object response = jrubyEngine.get(params.get("id"));
    
        // 如果ID中沒有結果,則從執行eval時的返回結果中擷取
        if(response == null || StringUtils.isEmpty(response.toString())) {
            response = (value == null ? value : value.toString());
        }
    
        // 輸出請求響應結果到控制台
        //System.out.println(new String(response.toString().getBytes("utf-8"),"gbk"));
        System.out.println(response);
       
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println((System.currentTimeMillis() - start) + "ms");
  }
}

 

注意:對以JDK1.5,要用JRubyScriptEngineManager 代替ScriptEngine ,否者編譯不通過。

 

Ruby代碼(getIP.rb):

 

require 'net/http'
require 'uri'
eval(
"$#{$params.get('id')}=Net::HTTP.get(URI.parse('#{$params.get('url')}'))"                     
);

 

編譯java後,運行Main.java 時報錯:

D:/script/javaexec/juby>java Main
----------GB18030
java.lang.IllegalArgumentException: no engine registered for: jruby

 

 

需要這樣才能運行:

java -cp .;D:/open/jruby/sjp-1_0-fr-ri/script-api.jar;D:/open/jruby-1.1.6/lib/bsf.jar;D:/open/jruby/jruby-complete-1.1.6.jar;D:/open/jruby/jruby-engine.jar;D:/open/commons-lang-2.4/commons-lang-2.4.jar  Main

 

 

可見使用ruby去擷取頁面內容僅僅三行代碼即完成,比起之前寫的java類要簡單不少。

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.