自定义表达式解析器

解析器:

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.tf.arithmetic.bean.Exterior;

/**
 * 自定义计算表达式解析器和计算器
 * 表达式的写法:@{占位变量}
 * @author yzl
 *
 */
public class ExpressionResolver {
    private ExpressionResolver(){}
    private static ExpressionResolver resolver = null;
    public static ExpressionResolver getInstance(){
        if(null==resolver){
            resolver = new ExpressionResolver();
        }
        return resolver;
    }

    /**
     * 计算表达式的结果
     * @param expression  解析包含@{}的表达式
     * @param bean
     * @param precision
     * @return
     * @throws ScriptException
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     */
    public double getExecuteResult(String expression, Object bean, int precision) throws ScriptException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        expression = this.parse(expression, bean);
        ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
        double result = (Double) se.eval(expression);
        return MathUtils.multiply(result, 1d, precision);
    }

    /**
     * 解析自定义的@{}表达式
     * (@{ys}*[email protected]{csd}*[email protected]{jg}*[email protected]{sf}*[email protected]{yf}*[email protected]{sd}*0.08)*10
     * @param expression
     * @param bean
     * @return
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    private String parse(String expression, Object bean) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        //保存表达式中的所有变量
        List<String> variableList = new ArrayList<String>();

        String reg = "@\\{";
        String reg2 = "\\}";
        Pattern pattern = Pattern.compile(reg);
        Pattern pattern2 = Pattern.compile(reg2);
        String[] arr = pattern.split(expression);
        for(int i=0; i<arr.length; i++){
            if(!"(".equals(arr[i]) && !")".equals(arr[i])){
                variableList.add(pattern2.split(arr[i])[0]);
            }
        }

        String fieldName = null;
        String methodName = null;
        Object result = null;

        //用值替换表达式中的变量
        if(variableList.size()>0){
            Field[] field = bean.getClass().getDeclaredFields();
            for(int i=0; i<field.length; i++){
                fieldName = field[i].getName();
                methodName = "get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                result = bean.getClass().getMethod(methodName, null).invoke(bean);
                expression = expression.replace("@{"+fieldName+"}", result.toString());
            }
        }

        return expression;
    }

    public static void main(String[] args) throws Exception {
        String input = "(@{ys}*[email protected]{csd}*[email protected]{jg}*[email protected]{sf}*[email protected]{yf}*[email protected]{sd}*0.08)*10";
        String reg = "@\\{";
        String reg2 = "\\}";
        Pattern pattern = Pattern.compile(reg);
        Pattern pattern2 = Pattern.compile(reg2);
        String[] arr = pattern.split(input);
        for(int i=0; i<arr.length; i++){
            if(!"(".equals(arr[i]) && !")".equals(arr[i])){
                System.out.println("得到变量:"+pattern2.split(arr[i])[0]);
            }
        }

        Exterior bean = new Exterior(8,8,8,8,8,8);
        double val = ExpressionResolver.getInstance().getExecuteResult(input, bean, 2);
        System.out.println(val);
    }
}

需要的实体bean(例子):

/**
 * 某模型的pojo对象
 * @author yzl
 *
 */
public class Exterior {
    private int ys;
    private int csd;
    private int jg;
    private int sf;
    private int yf;
    private int sd;

    public int getYs() {
        return ys;
    }
    public void setYs(int ys) {
        this.ys = ys;
    }
    public int getCsd() {
        return csd;
    }
    public void setCsd(int csd) {
        this.csd = csd;
    }
    public int getJg() {
        return jg;
    }
    public void setJg(int jg) {
        this.jg = jg;
    }
    public int getSf() {
        return sf;
    }
    public void setSf(int sf) {
        this.sf = sf;
    }
    public int getYf() {
        return yf;
    }
    public void setYf(int yf) {
        this.yf = yf;
    }
    public int getSd() {
        return sd;
    }
    public void setSd(int sd) {
        this.sd = sd;
    }

    public Exterior(int ys, int csd, int jg, int sf, int yf, int sd) {
        super();
        this.ys = ys;
        this.csd = csd;
        this.jg = jg;
        this.sf = sf;
        this.yf = yf;
        this.sd = sd;
    }

    public Exterior() {
        super();
    }
}
时间: 2024-08-27 12:28:14

自定义表达式解析器的相关文章

Java中使用Groovy实现自定义表达式解析

Groovy作为一种JVM-Based语言,目前普及程度正在提高.本文演示一下在Java类中,通过继承GDK的groovy.lang.Script类如何支持自定义表达式解析功能. 输入: 表示一行数据的某个map结构.在实际应用中,产生这种结构的最常见场景可能是通过JDBC访问数据库.通过调用WebService服务得到的某行结果集等. 目标设定: 假设我们希望对输入数据进行某个运算.此处示例中,我们模拟oracle中最常用的nvl函数. 处理过程:  首先,通过继承groovy.lang.Sc

BeanNameViewResolver自定义视图解析器

RedirectView:定义外部资源视图对象 JstlView:定义内部资源视图对象 使用自定义视图解析器 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

SpringMVC自动封装List对象——自定义参数解析器

前台传递的参数为集合对象时,后台Controller希望用一个List集合接收数据. 原生SpringMVC是不支持,Controller参数定义为List类型时,接收参数会报如下错误: org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.util.List]: Specified class is an interface at org.springframework.beans.B

[LeetCode] Ternary Expression Parser 三元表达式解析器

Given a string representing arbitrarily nested ternary expressions, calculate the result of the expression. You can always assume that the given expression is valid and only consists of digits 0-9, ?, :, T and F (T and Frepresent True and False respe

[转载]开发 Spring 自定义视图和视图解析器

原文出处 http://www.ibm.com/developerworks/cn/java/j-lo-springview/ 概述 Spring 3.0 默认包含了多种视图和视图解析器,比如 JSP.Velocity 视图等,但在某些情况下,我们需要开发自定义的视图及其解析器,以便显示特殊文件格式的视图,我们也可以使用自定义视图及解析器,针对特定的视图做相应的处理.本文将通过一个示例来介绍如何开发 Spring 自定义视图和视图解析器,来显示后缀名为 SWF 的视图,并提供一个简单的注册机制,

Spring自定义argumentResolver参数解析器

在一个web程序中,当一个HTTP请求进来时,会被容器处理进而转换成一个servlet请求.http请求所携带的数据,虽然是格式化的但是无类型:而java作为强类型语言,同时为了健壮性考虑,必然要有完善的类型约束.当然,那么,将数据从servlet请求中转换到java中,一个很原始的方式是手动处理.幸好,Spring MVC通过以注解往函数添加额外信息的方式,使得上述的数据转换过程能够交由框架自动处理.从一个角度去看,Controller中的函数声明及注解定义了此HTTP请求的数据格式和类型,也

SPEL 表达式解析

Spring Expression Language 解析器 SPEL解析过程 使用 ExpressionParser 基于 ParserContext 将字符串解析为 Expression, Expression 再根据 EvaluationContext 计算表达式的值. 将字符串解析为 Expression StandardBeanExpressionResolver# /** 默认表达式前缀 */ public static final String DEFAULT_EXPRESSION

SpringMVC 配置多视图解析器(velocity,jsp)

1.自定义视图解析器 package com.zhaochao.controller; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework

SpringMVC源码阅读:视图解析器

1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring4.3.7)分析,弄清楚SpringMVC如何完成视图解析的 2.源码分析 在SpringMVC源码阅读:拦截器分析过doDispatch的运行过程,这里再分析一遍 回到DispatcherServlet类的doDispatch方法,看看doDispatch如何获取ModelAndView Hand