一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java用 Rhino/Nashorn 代替第三方 JSON 轉換庫

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

2020-09-25 15:16sp42a Java教程

本篇文章主要介紹了Java用 Rhino/Nashorn 代替第三方 JSON 轉換庫,非常具有實用價值,需要的朋友可以參考下

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

背景知識:Java 6 提供對執行腳本語言的支持,這個支持來自于 JSR223 規范,對應的包是 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。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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 {
  /**
   * 創建 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,必須加變量,例如 執行 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()運算發生異常!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 的也是同理。

下面是單測的代碼。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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 接口,但通常只能讀的操作,如果對其執行 map.put(key, value) 的操作,是會引發 UnsupportOperation 的異常的。

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

原文鏈接:http://blog.csdn.net/zhangxin09/article/details/51810804

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 青视频在线| 欧美人在线一区二区三区 | 国产成人精品免费视频大全五级 | 天天天综合网 | 日韩理论在线观看 | 97国产自拍| 熟睡中的麻麻大白屁股小说 | 国产在线欧美日韩精品一区二区 | 青草碰人人澡人人澡 | 国产男女爱视频在线观看 | 国产精品嫩草影院一二三区入口 | 亚洲国产香蕉视频欧美 | a网在线 | 亚洲日本va中文字幕 | 青柠在线完整高清观看免费 | 五月激情丁香婷婷综合第九 | 免费精品在线视频 | 亚洲成人mv| 国产在线精品香蕉综合网一区 | 精品久久久久久午夜 | 国产综合欧美日韩视频一区 | 扒开放荡老师裙子猛烈的进入 | 日本不卡高清免费v日本 | 亚洲码和乱人伦中文一区 | 亚洲精品AV无码永久无码 | 草莓香蕉绿巨人丝瓜榴莲18 | 精选国产AV精选一区二区三区 | 亚洲狠狠综合久久 | 91大神在线精品播放 | 日本一区免费观看 | 精品高潮呻吟99AV无码 | 免费观看日本 | 国产91精品在线播放 | 欧美特欧美特级一片 | 久草青青在线 | 男人影院天堂网址 | 冰山美人调教耻辱h | 脱女学小内内摸出水网站免费 | 91进入蜜桃臀在线播放 | 久久成人伊人欧洲精品AV | 国产免费久久精品44 |