Groovy作为一种JVM-Based语言,目前普及程度正在提高。本文演示一下在Java类中,通过继承GDK的groovy.lang.Script类如何支持自定义表达式解析功能。

输入:

表示一行数据的某个map结构。在实际应用中,产生这种结构的最常见场景可能是通过JDBC访问数据库、通过调用WebService服务得到的某行结果集等。

目标设定:

假设我们希望对输入数据进行某个运算。此处示例中,我们模拟oracle中最常用的nvl函数。

处理过程:

首先,通过继承groovy.lang.Script,定义自己的表达式解析类:

public class MyBasicScript extends Script

在该类中实现具体的解析方法:

public static Object nvl(Object str,Object val){

return str==null ||"".equals(str)?val:str;

}

其次,基于上述自定义类,实例化一个CompilerConfiguration对象。

CompilerConfiguration cfg = new CompilerConfiguration();

cfg.setScriptBaseClass(MyBasicScript.class.getName());

以此CompilerConfiguration实例为参数,实例化一个GroovyShell对象

shell = new GroovyShell(cfg);

通过shell对象,解析并运行表达式。在运行前,可以通过bingding对象绑定脚本运行时的上下文数据:

Binding binding = new Binding(map);

Script script = shell.parse(expr);

script.setBinding(binding);

script.run();

附完整的代码示例(共两个类,分别是自定义脚本实现类、调用及测试类)

package jg.groovy;

import groovy.lang.Script;

import java.lang.reflect.Method;

public class MyBasicScript extends Script {

@Override

public Object run() {

//show usage

Method[] methods = MyBasicScript.class.getDeclaredMethods();

StringBuilder sb=new StringBuilder();

for (Method method : methods) {

sb.append(method);

}

return sb.substring(0, sb.length()-1);

}

public static Object nvl(Object str, Object val) {

return str == null || "".equals(str) ? val : str;

}

}

package jg.groovy;

import groovy.lang.Binding;

import groovy.lang.GroovyShell;

import groovy.lang.Script;

import java.util.HashMap;

import java.util.Hashtable;

import java.util.Map;

import org.codehaus.groovy.control.CompilerConfiguration;

public class ExprSupport {

private static final Object lock = new Object();

private static final GroovyShell shell;

private static Hashtable cache = new Hashtable();

static {

CompilerConfiguration cfg = new CompilerConfiguration();

cfg.setScriptBaseClass(MyBasicScript.class.getName());

shell = new GroovyShell(cfg);

}

public static Object parseExpr(String expr) {

Script s = getScriptFromCache(expr);

return s.run();

}

public static Object parseExpr(String expr, Map, ?> map) {

Binding binding = new Binding(map);

Script script = getScriptFromCache(expr);

script.setBinding(binding);

return script.run();

}

private static Script getScriptFromCache(String expr) {

if (cache.contains(expr)) {

return cache.get(expr);

}

synchronized (lock) {

if (cache.contains(expr)) {

return cache.get(expr);

}

Script script = shell.parse(expr);

cache.put(expr, script);

return script;

}

}

/**

* @param args

*/

public static void main(String[] args) {

// eg. get one row from db

Map row = new HashMap();

row.put("id", 42);

row.put("name", "");

//带绑定数据参数的调用方式

System.out.println(ExprSupport.parseExpr("nvl(id,0)", row));

System.out.println(ExprSupport.parseExpr("nvl(name,‘anonymous‘)", row));

//不带绑定数据参数的调用方式,这个是groovy的内置能力

System.out.println(ExprSupport.parseExpr("1+2"));

}

}

输出:

42

anonymous

3

总结:结合groovy对表达式的内置支持能力与自定义脚本能力,可以实现功能强大的表达式解析能力。

原文:http://www.cnblogs.com/ora11g/p/4473544.html

java 自定义表达式_Java中使用Groovy实现自定义表达式解析相关推荐

  1. java中自定义比较器_Java中的比较器:自定义规则!!!

    比较器 Java语言中的比较器分为两种: Comparable比较器:Comparable是排序接口:若一个类实现了Comparable接口,就意味着"该类支持排序".(作用在实体 ...

  2. java 动态重载_Java中是否可以实现动态重载解析?

    所以我有一类这样的重载方法: class Foo { public void test(Object value) { ... } public void test(String value) { . ...

  3. java 文件路径表达式_Java基础(二十二) Lambda表达式和File类

    函数式编程思想 强调的是做什么,而不是以什么样的方式来做,它忽略了面向对象的复杂语法,只要能够获取到结果,谁去做的,怎么做的,都不重要,重要的是结果,不重视过程. 冗余的Runnable代码 传统的写 ...

  4. java for 嵌套_Java中的for循环嵌套

    Java嵌套循环是指在一个循环语句的循环体中再定义一个循环语句的语法结构.whiledo.while.for循环语句都可以进行嵌套,并且它们之间也可以互相嵌套,如最常见的在for循环中嵌套for循环, ...

  5. java判断类型_Java中类型判断的几种方式 - 码农小胖哥 - 博客园

    1. 前言 在Java这种强类型语言中类型转换.类型判断是经常遇到的.今天就细数一下Java中类型判断的方法方式. 2. instanceof instanceof是Java的一个运算符,用来判断一个 ...

  6. java 数据类型分为_JAVA中分为基本数据类型及引用数据类型

    byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围-32768~32717,默认值 ...

  7. 自定义关键字_Java中的自定义异常

    在测试脚本的编写中会需要使用自定义异常,通常可以很容易地用「Java」创建自定义异常类.它可以是已检查或未检查的异常.下面将演示一个简单的示例来检查Java中自定义异常的创建. 如何创建自定义异常类 ...

  8. java file 方法_JAVA中File的常用方法

    一.File类中包含了很多获得文件或文件夹属性的方法,使用起来比较方便,下面将常见的方法介绍如下: a.createNewFile方法 public boolean createNewFile() t ...

  9. java 判断类型_Java中类型判断的几种方式

    在Java这种强类型语言中类型转换.类型判断是经常遇到的.今天就细数一下Java中类型判断的方法方式.拉勾IT课小编为大家提供java种类型判断方式. instanceof instanceof是Ja ...

最新文章

  1. 各个大厂的机器学习平台概述
  2. x86汇编从实模式到保护模式-程序加载器
  3. 生态和能力是国内自研操作系统发展的关键
  4. 史上最全Java多线程面试60题,含答案大赠送!
  5. 云+X案例展 | 民生类:纷享销客助力沃得农机构筑智能化、信息化之路
  6. 实体类blob类型_Mysql的数据类型和JPA的实体类
  7. TCP和UDP,HTTP和HTTPS
  8. 初识 Node.js
  9. INT 21H 指令说明及使用方法
  10. 【python快速入门】—唐宇迪课程笔记
  11. 路由器(无线桥接)中继模式遇到无法上网的解决方案
  12. php微信定位功能,JavaScript微信定位功能实现方法
  13. html 输入字数限制,说一说限制字数的输入框踩的坑
  14. 帐套文件(*.mdf)无法复制,拷贝出现数据错误(循环冗余检查)帐套文件(*.mdf)无法复制,拷贝出现数据错误(循环冗余检查),sql附加823错误
  15. Python使用Win32和天行机器人API实现微信自动聊天机器人(自动敷衍机器人)
  16. 北京工业大学外网访问知网数据库方法
  17. 蚂蚁金服bPaaS究竟是什么?
  18. 零售商贩mysql表设计:banner+banner_item+image关联表(轮播图表)
  19. Android 基础知识+app测试权限问题
  20. Synopsys VCS工具介绍

热门文章

  1. 美版三星s7 g930 p版刷官方国际版安卓8以及手机卡信号和关闭DM服务相关问题
  2. 程序代码初学者_初学者极客:在Windows 7和Vista中设置默认程序
  3. 你不知道的Nmap之空闲扫描
  4. 如何在大学期间提高英语能力
  5. ie6,ie7,ie8,ie9 css bug兼容解决记录
  6. 什么模式下不可使用曝光补偿_摄影技巧丨手动模式与曝光补偿,到底哪个更好用?...
  7. 小程序 uni-app picker-view改变选中行上下边框样式
  8. windows7桌面没有IE图标-花年记事
  9. 傅里叶变换对称性质MATLAB,实数序列离散傅里叶变换(DFT)的共轭对称性质
  10. 【详解】KMP算法——多图,多例子(c语言)