亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java用 Rhino/Nashorn 代替第三方 JSON 轉換庫

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

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

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

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

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

import java.util.List; 
import java.util.Map; 
 
import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 
import javax.script.ScriptException; 
 
/** 
 * json 轉為 java 對象的工具類 
 * 
 * @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 對象 
   */ 
  @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 對象 
   */ 
  public static Map<String, Object> getMap(String js) { 
    return getMap(js, null); 
  } 
 
  /** 
   * 轉換為 map 或 list 
   * 
   * @param js 
   *      JSON 字符串 
   * @param key 
   *      JSON Path,可以帶有 aa.bb.cc 
   * @param clazz 
   *      目標類型 
   * @return 目標對象 
   */ 
  @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()運算發(fā)生異常!eval 代碼:" + js); 
      e.printStackTrace(); 
    } 
 
    return result; 
  } 
 
  /** 
   * 讀取 json 里面的 list,list 里面每一個都是 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 里面每一個都是 map 
   * 
   * @param js 
   *      JSON 字符串 
   * @return 包含 Map 的列表 
   */ 
  public static List<Map<String, Object>> getList(String js) { 
    return getList(js, null); 
  } 
 
  /** 
   * 讀取 json 里面的 list,list 里面每一個都是 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 里面每一個都是 String 
   * 
   * @param js 
   *      JSON 字符串 
   * @return 包含 String 的列表 
   */ 
  public static List<String> getStringList(String js) { 
    return getStringList(js, null); 
  } 
 
  /** 
   * js number 為 double 類型,在 java 里面使用不方便,將其轉換為 int 
   * 
   * @param d 
   *      js number 
   * @return int 值 
   */ 
  public static int double2int(Double d) { 
    if (d > Integer.MAX_VALUE) { 
      System.out.println(d + "數值太大,不應用這個方法轉換到 int"); 
      return 0; 
    } else { 
      return d.intValue(); 
    } 
 
  } 
} 

其實使用起來非常地方便!js 的對象本身是 map 結構,而 Rhino 原生對象 NativeObject 是 js 對象在 Java 語言里面的對應物,它已經實現了 Map 接口,所以完全可以把 NativeObject 當作 map 來使用!類型轉換下即可!eval() 返回的是 object,如果可以判斷 object 類型為 NativeObject,直接轉化 (Map)object 就可以了——接著就是使用 get 等方法,甚至在 JSP 頁面中也可以使用。

List 的也是同理。

下面是單測的代碼。

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 接口,但通常只能讀的操作,如果對其執(zhí)行 map.put(key, value) 的操作,是會引發(fā) UnsupportOperation 的異常的。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • SpringBoot參數校驗之@Validated的使用詳解

    SpringBoot參數校驗之@Validated的使用詳解

    這篇文章主要通過示例為大家詳細介紹一下介紹了SpringBoot參數校驗中@Validated的使用方法,文中的示例代碼講解詳細,需要的可以參考一下
    2022-06-06
  • java反射原理制作對象打印工具

    java反射原理制作對象打印工具

    本文主要給大家介紹了java反射原理制作對象打印工具的方法和代碼,以及一個熱心網友給出的更加簡潔方便的代碼,小伙伴們需要的話可以參考下。
    2015-12-12
  • 前后端分離跨域springBoot跨域有效解決問題

    前后端分離跨域springBoot跨域有效解決問題

    這篇文章主要介紹了前后端分離跨域springBoot跨域有效解決問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • centos7安裝java的多種方式總結

    centos7安裝java的多種方式總結

    這篇文章主要給大家介紹了關于centos7安裝java的多種方式,文中通過實例代碼以及圖文介紹的非常詳細,對大家學習或者使用java具有一定的參考學習價值,需要的朋友可以參考下
    2023-01-01
  • MyBatis框架關聯映射實例詳解

    MyBatis框架關聯映射實例詳解

    這篇文章主要介紹了MyBatis框架關聯映射,關系映射主要處理復雜的SQl查詢,如子查詢,多表聯查等復雜查詢,應用此種需求時可以考慮使用,需要的朋友可以參考下
    2022-11-11
  • Java ArrayList.toArray(T[]) 方法的參數類型是 T 而不是 E的原因分析

    Java ArrayList.toArray(T[]) 方法的參數類型是 T 而不是 E的原因分析

    這篇文章主要介紹了Java ArrayList.toArray(T[]) 方法的參數類型是 T 而不是 E的原因分析的相關資料,需要的朋友可以參考下
    2016-04-04
  • Spring Boot如何防止重復提交

    Spring Boot如何防止重復提交

    這篇文章主要為大家詳細介紹了Spring Boot如何防止重復提交,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Mapper批量插入Oracle數據@InsertProvider注解

    Mapper批量插入Oracle數據@InsertProvider注解

    今天小編就為大家分享一篇關于Mapper批量插入Oracle數據@InsertProvider注解,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 在攔截器中讀取request參數,解決在controller中無法二次讀取的問題

    在攔截器中讀取request參數,解決在controller中無法二次讀取的問題

    這篇文章主要介紹了在攔截器中讀取request參數,解決在controller中無法二次讀取的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Lambda表達式和Java集合框架

    Lambda表達式和Java集合框架

    本文主要介紹了Lambda表達式和Java集合框架的相關知識,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03

最新評論