中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java如何利用JEXL實現動態表達式編譯

發布時間:2021-04-16 09:29:48 來源:億速云 閱讀:364 作者:小新 欄目:開發技術

小編給大家分享一下java如何利用JEXL實現動態表達式編譯,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

背景

做項目突然遇到這樣的需求:
系統要獲取多個數據源的數據,并進行處理,最后輸出多個字段。字段的計算規則一般是簡單的取值最多加一點條件判斷。
而且需要動態變動!!例如一個字段a的取值,如果a > 10的時候輸出10,a <= 10則輸出a。這里的10可能在一天后改成8,也可能在后天就改成了12。當然,如果只是一個數字的變動還好說,我們可以使用數據庫進行存儲。但是,萬一哪天需求突然變成了a < 10的時候輸出10,a >=10 則輸出a,就需要對代碼改動,再測試再發布才能到生產環境使用。
一兩個這樣的字段還沒什么,如果整個系統所依賴的字段都有這樣的屬性,那么我們就需要找一種方法來實現動態的加載邏輯。
下面介紹的JEXL就可以解決這種問題

JEXL(Java Expression Language)介紹

JEXL – Apache Commons JEXL Overview

下面用一些實例來介紹JEXL的使用方法

實例

maven依賴:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-jexl</artifactId>
    <version>2.0</version>
</dependency>

正則表達式匹配

首先寫一個公共方法:

public class Util {
    public static boolean regMatch(String regEx, String str) {
        Pattern pattern = Pattern.compile(regEx);
        return pattern.matcher(str).matches();
    }
}

下面是使用JEXL調用的方法

public void RL() {
    JexlContext jc = new MapContext();
    String str = "一二三四五六七八九十";
    jc.set("Util", new Util());
    jc.set("str", str);
    jc.set("ans", "");
    String expression = "ans = Util.regMatch(\"[\u4e00-\u9fa5]{10,}\",str)";
    Expression e = new JexlEngine().createExpression(expression);
    e.evaluate(jc);
    System.out.println(jc.get("ans"));
}

代碼中的expression變量就是可以動態編譯的表達式,這里要注意表達式中出現的所有變量,都需要事先set進JexlContext中,否則會報錯。這里有多種形式的錯誤:

①如果沒有set”Util”,程序運行中會拋出異常。

org.apache.commons.jexl2.JexlException: TmpTest.RL@40![13,40]: 'ans = QeUtil.regMatch('[一-龥]{10,}', str);' attempting to call method on null

②如果沒有set”str”,程序不會拋出異常,并輸出null。如果你的regMatch方法中有判空處理,就會輸出判空的結果。如果沒有判空處理,在控制臺的輸出如下:

警告: TmpTest.RL@39![36,39]: 'ans = QeUtil.regMatch('[一-龥]{10,}', str);' undefined variable str
二月 21, 2017 4:00:41 下午 org.apache.commons.jexl2.JexlEngine invocationFailed
警告: TmpTest.RL@39![13,40]: 'ans = QeUtil.regMatch('[一-龥]{10,}', str);' method invocation error
java.lang.NullPointerException

③如果沒有set”ans”,程序會正常運行,并輸出正確值
為了保險起見,建議表達式中出現的所有變量,都需要事先set進JexlContext中

循環

JEXL支持兩種循環方式:

for(item : list) {
    x = x + item;
}

while (x lt 10) {
    x = x + 2;
}

下面是使用while的實例:

public void loop() {
    JexlContext jc = new MapContext();
    jc.set("a", 1);
    jc.set("b", "0");
    jc.set("ans", new StringBuffer());
    Expression e = new JexlEngine().createExpression("while (a < 10) {a = a + 1;ans.append(b);}");
    e.evaluate(jc);
    System.out.println(jc.get("ans"));
}

get\set方法調用

JEXL支持傳入對象,并調用對象的方法
下面的簡單的get\set方法的實例:

public void getSet() {
    TmpTest tmpTest = new TmpTest();
    tmpTest.setA(1);
    JexlContext jc = new MapContext();
    jc.set("tmpTest", tmpTest);
    jc.set("ans", "");
    Expression e = new JexlEngine().createExpression("ans = tmpTest.getA()");
    e.evaluate(jc);
    System.out.println(jc.get("ans"));
    e = new JexlEngine().createExpression("ans = tmpTest.setA(2)");
    e.evaluate(jc);
    TmpTest tmpTest1 = (TmpTest) jc.get("tmpTest");
    System.out.println(tmpTest1.getA());
}

上面的用例會在控制臺先輸出1,再輸出2

以上是“java如何利用JEXL實現動態表達式編譯”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

海晏县| 瑞丽市| 和林格尔县| 乐平市| 通州市| 肇庆市| 怀远县| 锡林浩特市| 方山县| 宾川县| 遂昌县| 林周县| 高邑县| 茂名市| 定边县| 丹东市| 梧州市| 临漳县| 武邑县| 黄梅县| 潼南县| 阿合奇县| 枞阳县| 海林市| 东方市| 阿坝县| 南岸区| 乐陵市| 赣榆县| 噶尔县| 平潭县| 顺义区| 临夏县| 沈丘县| 晋城| 新龙县| 怀化市| 伊宁市| 叙永县| 房山区| 上犹县|