最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java用 Rhino/Nashorn 代替第三方 JSON 轉(zhuǎn)換庫(kù)

 更新時(shí)間:2017年05月08日 10:09:26   作者:sp42a  
本篇文章主要介紹了Java用 Rhino/Nashorn 代替第三方 JSON 轉(zhuǎn)換庫(kù),非常具有實(shí)用價(jià)值,需要的朋友可以參考下

Java 本身就自帶 JS 引擎,自從 Java 1.6 開始就支持了,愈來愈好。我對(duì) js 比較熟悉,因此有個(gè)大膽的想法,為什么不用自帶 js 引擎作 json 轉(zhuǎn)換呢?這樣我們可以不用引入其他第三方庫(kù)。

背景知識(shí):Java 6 提供對(duì)執(zhí)行腳本語(yǔ)言的支持,這個(gè)支持來自于 JSR223 規(guī)范,對(duì)應(yīng)的包是 javax.script。默認(rèn)情況下,Java 6 只支持 JavaScript 腳本,它底層的實(shí)現(xiàn)是 Mozilla Rhino,它是個(gè)純 Java 的 JavaScript 實(shí)現(xiàn)。

除了 OpenJDK 不自帶 js 引擎外,Sun/Oracle 的都支持。所以完全可以這么來做。

我本人很早就這么做了。只是早期 1.6/1.7 的 Rhino 性能低下,但到了 1.8 性能已經(jīng)不能同日而語(yǔ)了,——因?yàn)橐呀?jīng)升級(jí)到 Nashorn 引擎了,一個(gè)非??斓?js 引擎實(shí)現(xiàn)。另外一點(diǎn),之前寫的代碼十分累贅。盡管也重構(gòu)了幾次,但還是寫不好。于是現(xiàn)欲改之,改成為一個(gè)稍“明快”的版本。請(qǐng)各位看官見下面代碼,其作用就是將 JSON 字符串轉(zhuǎn)換為 Java 的 Map 或者 List。

import java.util.List; 
import java.util.Map; 
 
import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 
import javax.script.ScriptException; 
 
/** 
 * json 轉(zhuǎn)為 java 對(duì)象的工具類 
 * 
 * @author frank 
 * 
 */ 
public class JSON { 
  /** 
   * 創(chuàng)建 js 引擎工廠,支持 java 6/7 的 rhino 和 java 8 的 nashorn 
   * 
   * @return js 引擎 
   */ 
  public static ScriptEngine engineFatory() { 
    return new ScriptEngineManager() 
        .getEngineByName(System.getProperty("java.version").contains("1.8.") ? "nashorn" : "rhino"); 
  } 
 
  /** 
   * JVM 自帶的 JS 引擎 
   */ 
  private final static ScriptEngine engine = engineFatory(); 
 
  /** 
   * 讀取 json 里面的 map 
   * 
   * @param js 
   *      JSON 字符串 
   * @param key 
   *      JSON Path,可以帶有 aa.bb.cc 
   * @return Map 對(duì)象 
   */ 
  @SuppressWarnings("unchecked") 
  public static Map<String, Object> getMap(String js, String key) { 
    return (Map<String, Object>) accessMember(js, key, Map.class); 
  } 
 
  /** 
   * 讀取 json 里面的 map 
   * 
   * @param js 
   *      JSON 字符串 
   * @return Map 對(duì)象 
   */ 
  public static Map<String, Object> getMap(String js) { 
    return getMap(js, null); 
  } 
 
  /** 
   * 轉(zhuǎn)換為 map 或 list 
   * 
   * @param js 
   *      JSON 字符串 
   * @param key 
   *      JSON Path,可以帶有 aa.bb.cc 
   * @param clazz 
   *      目標(biāo)類型 
   * @return 目標(biāo)對(duì)象 
   */ 
  @SuppressWarnings("unchecked") 
  public static <T> T accessMember(String js, String key, Class<T> clazz) { 
    T result = null; 
 
    try { 
      engine.eval("var obj = " + js);// rhino 不能直接返回 map,如 eval("{a:1}") 
                      // -->null,必須加變量,例如 執(zhí)行 var xx = 
                      // {...}; 
      Object obj; 
      if (key == null) { 
        obj = engine.eval("obj;"); 
      } else { 
        if (key.contains(".")) { 
          obj = engine.eval("obj." + key + ";"); 
        } else { 
          obj = engine.eval("obj['" + key + "'];"); 
        } 
      } 
      result = (T) obj; 
    } catch (ScriptException e) { 
      System.err.println("腳本eval()運(yùn)算發(fā)生異常!eval 代碼:" + js); 
      e.printStackTrace(); 
    } 
 
    return result; 
  } 
 
  /** 
   * 讀取 json 里面的 list,list 里面每一個(gè)都是 map 
   * 
   * @param js 
   *      JSON 字符串 
   * @param key 
   *      JSON Path,可以帶有 aa.bb.cc 
   * @return 包含 Map 的列表 
   */ 
  @SuppressWarnings("unchecked") 
  public static List<Map<String, Object>> getList(String js, String key) { 
    return (List<Map<String, Object>>) accessMember(js, key, List.class); 
  } 
 
  /** 
   * 讀取 json 里面的 list,list 里面每一個(gè)都是 map 
   * 
   * @param js 
   *      JSON 字符串 
   * @return 包含 Map 的列表 
   */ 
  public static List<Map<String, Object>> getList(String js) { 
    return getList(js, null); 
  } 
 
  /** 
   * 讀取 json 里面的 list,list 里面每一個(gè)都是 String 
   * 
   * @param js 
   *      JSON 字符串 
   * @param key 
   *      JSON Path,可以帶有 aa.bb.cc 
   * @return 包含 String 的列表 
   */ 
  @SuppressWarnings("unchecked") 
  public static List<String> getStringList(String js, String key) { 
    return (List<String>) accessMember(js, key, List.class); 
  } 
 
  /** 
   * 讀取 json 里面的 list,list 里面每一個(gè)都是 String 
   * 
   * @param js 
   *      JSON 字符串 
   * @return 包含 String 的列表 
   */ 
  public static List<String> getStringList(String js) { 
    return getStringList(js, null); 
  } 
 
  /** 
   * js number 為 double 類型,在 java 里面使用不方便,將其轉(zhuǎn)換為 int 
   * 
   * @param d 
   *      js number 
   * @return int 值 
   */ 
  public static int double2int(Double d) { 
    if (d > Integer.MAX_VALUE) { 
      System.out.println(d + "數(shù)值太大,不應(yīng)用這個(gè)方法轉(zhuǎn)換到 int"); 
      return 0; 
    } else { 
      return d.intValue(); 
    } 
 
  } 
} 

其實(shí)使用起來非常地方便!js 的對(duì)象本身是 map 結(jié)構(gòu),而 Rhino 原生對(duì)象 NativeObject 是 js 對(duì)象在 Java 語(yǔ)言里面的對(duì)應(yīng)物,它已經(jīng)實(shí)現(xiàn)了 Map 接口,所以完全可以把 NativeObject 當(dāng)作 map 來使用!類型轉(zhuǎn)換下即可!eval() 返回的是 object,如果可以判斷 object 類型為 NativeObject,直接轉(zhuǎn)化 (Map)object 就可以了——接著就是使用 get 等方法,甚至在 JSP 頁(yè)面中也可以使用。

List 的也是同理。

下面是單測(cè)的代碼。

import java.util.List; 
import java.util.Map; 
 
import org.junit.Test; 
 
import com.ajaxjs.util.json.JSON; 
 
import static org.junit.Assert.*; 
 
public class TestJSON { 
 
  @Test 
  public void testGetMap() { 
    Map<String, Object> map; 
    map = JSON.getMap("{a:'hello', b: 'world!', c: { d: 'Nice!'}}"); 
    System.out.println(map.get("a")); 
    assertNotNull(map); 
    map = JSON.getMap("{a:'hello', b: 'world!', c: { d: 'Nice!'}}", "c"); 
    System.out.println(map.get("d")); 
    assertNotNull(map); 
    map = JSON.getMap("{a:'hello', b: 'world!', c: { d: 'Nice!', e: { f: 'fff'}}}", "c.e"); 
    System.out.println(map.get("f")); 
    assertNotNull(map); 
  } 
 
  @Test 
  public void testGetListMap() { 
    List<Map<String, Object>> list; 
    list = JSON.getList("[{a:'hello'}, 123, true]"); 
    System.out.println(list.get(0).get("a")); 
    assertTrue(list.size() > 0); 
 
    list = JSON.getList("[{a:'hello'}, {b: 'world!'}, {c: { d: 'Nice!'}}]"); 
    System.out.println(list.get(0).get("a")); 
    assertTrue(list.size() > 0); 
 
    list = JSON.getList("{a:'hello', b: 'world!', c: [{ d: 'Nice!!!'}]}", "c"); 
    System.out.println(list.get(0).get("d")); 
  } 
 
  @Test 
  public void testGetListString() { 
    List<String> list; 
    list = JSON.getStringList("['a', 'b', 'c']"); 
    System.out.println(list.get(0)); 
    assertTrue(list.size() > 0); 
 
    list = JSON.getStringList("[1, 'b', 'c']"); 
    System.out.println(list.get(1)); 
    assertTrue(list.size() > 0); 
 
  } 
} 

值得注意的是,雖然 JSEngine 提供了 Map 接口,但通常只能讀的操作,如果對(duì)其執(zhí)行 map.put(key, value) 的操作,是會(huì)引發(fā) UnsupportOperation 的異常的。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot定時(shí)任務(wù)參數(shù)運(yùn)行代碼實(shí)例解析

    SpringBoot定時(shí)任務(wù)參數(shù)運(yùn)行代碼實(shí)例解析

    這篇文章主要介紹了SpringBoot定時(shí)任務(wù)運(yùn)行代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • java 中 阻塞隊(duì)列BlockingQueue詳解及實(shí)例

    java 中 阻塞隊(duì)列BlockingQueue詳解及實(shí)例

    這篇文章主要介紹了java 中 阻塞隊(duì)列BlockingQueue詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • JAVA發(fā)送HTTP請(qǐng)求的多種方式詳細(xì)總結(jié)

    JAVA發(fā)送HTTP請(qǐng)求的多種方式詳細(xì)總結(jié)

    目前做項(xiàng)目中有一個(gè)需求是這樣的,需要通過Java發(fā)送url請(qǐng)求,查看該url是否有效,這時(shí)我們可以通過獲取狀態(tài)碼來判斷,下面這篇文章主要給大家介紹了關(guān)于JAVA發(fā)送HTTP請(qǐng)求的多種方式總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • Spring之IOC詳解

    Spring之IOC詳解

    本文主要介紹了Spring中的IOC的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-03-03
  • 從JVM分析Java的類的加載和卸載機(jī)制

    從JVM分析Java的類的加載和卸載機(jī)制

    這篇文章主要介紹了從JVM分析Java的類的加載和卸載機(jī)制,講解了Java類的聲明周期,需要的朋友可以參考下
    2015-11-11
  • C++ 程序流程結(jié)構(gòu)詳解

    C++ 程序流程結(jié)構(gòu)詳解

    這篇文章主要介紹了C++程序的程序流程結(jié)構(gòu)以及關(guān)系和邏輯運(yùn)算符講解,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2021-09-09
  • java使用poi生成excel的步驟

    java使用poi生成excel的步驟

    2010以上格式使用XSSFWorkBook對(duì)象, 2003格式使用HSSFWorkBook對(duì)象, 其他對(duì)象操作基本一樣,本文重點(diǎn)給大家介紹java使用poi生成excel的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2022-04-04
  • RocketMQ延遲消息簡(jiǎn)明介紹

    RocketMQ延遲消息簡(jiǎn)明介紹

    這篇文章主要介紹了RocketMQ延遲消息,延遲消息是個(gè)啥?顧名思義,就是等一段時(shí)間再消費(fèi)的消息。文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • java教學(xué)筆記之對(duì)象的創(chuàng)建與銷毀

    java教學(xué)筆記之對(duì)象的創(chuàng)建與銷毀

    面向?qū)ο蟮木幊陶Z(yǔ)言使程序能夠直觀的反應(yīng)客觀世界的本來面目,并且使軟件開發(fā)人員能夠運(yùn)用人類認(rèn)識(shí)事物所采用的一般思維方法進(jìn)行軟件開發(fā),是當(dāng)今計(jì)算機(jī)領(lǐng)域中軟件開發(fā)和應(yīng)用的主流技術(shù)。
    2016-01-01
  • java 分布式與集群的區(qū)別和聯(lián)系

    java 分布式與集群的區(qū)別和聯(lián)系

    本文主要介紹了java分布式與集群的區(qū)別和聯(lián)系,具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02

最新評(píng)論

汕头市| 沁阳市| 鸡西市| 宾阳县| 连州市| 海南省| 崇仁县| 偏关县| 武冈市| 仙游县| 申扎县| 德安县| 迁安市| 溧阳市| 紫阳县| 武威市| 武川县| 新郑市| 开远市| 周口市| 清涧县| 探索| 淮北市| 江安县| 左云县| 贺州市| 奇台县| 宝应县| 榆林市| 阳曲县| 泰兴市| 怀安县| 尤溪县| 武清区| 中超| 萨嘎县| 壶关县| 涪陵区| 龙海市| 象州县| 朝阳县|