在java代码中执行js脚本,实现计算出字符串“(1+2)*(1+3)”的结果

        今天在公司项目中,发现一个计算运费的妙招。由于运费规则各种各样,因此写一个公式存到数据库。下次需要计算运费时,直接取出这个公式,把公式的未知变量给替换掉,然后计算出结果就是ok了。

一、先看几张图

(1)数据库存的公式
        
(2)怎么在java代码中计算出结果,见下面2张图
        
        这图,是在map集合中存了 key为"\\$w"  value为重量的参数。关键是下面这图
        
        这图中方法接收参数为 (公式,公式中变量的真实内容的Map集合)
    比较巧妙的地方是,它把这个公式字符串变成js形式的变量运算字符串;然后执行js脚本,这样就把结果算出来了。
    就相当于在java中,把"1+2" 这个字符串给算出结果来了。而且它这里还巧妙的使用了js的Math的一些方法。

二、来写个demo

        写个方法,实现传入公式和参数,计算出结果。直接上代码吧
package com.zxy.test;
import java.util.HashMap;
import java.util.Map;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.junit.Test;

/**     
 * 如何将一个字符串公式,计算出结果
 * @author  ZENG.XIAO.YAN    
 * @date  	Oct 26, 2017 7:34:08 PM  
 * @version V1.0    
 */

public class RunJsOnJava {
	
	@Test
	public void test01() throws ScriptException {
		String formula = "(a+b)*(a-b)"; 
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("a", 20.1);
		map.put("b", 11.1);
		Double result =  (Double) this.calculateResultByFormula(formula, map);
		System.out.println(result);  //280.80000000000007
	}
	
	/**
	 * 通过字符串公式,和参数,计算出结果
	 * @param formula
	 * @param paramMap
	 * @return
	 * @throws ScriptException 
	 */
	public Object calculateResultByFormula (String formula,Map<String,Object> paramMap) throws ScriptException {
		ScriptEngineManager manager = new ScriptEngineManager();
		ScriptEngine scriptEngine = manager.getEngineByName("js");
		for (String key : paramMap.keySet()) {
			formula = formula.replaceAll(key, paramMap.get(key).toString());
		}
        //此时 formula="(20.1+11.1)*(20.1-11.1)"
		Object result = scriptEngine.eval(formula); // 运行js脚本
		return result;
	}
}

三、小结

        通过百度,发现通过ScriptEngineManager相关api可以在java运行各种脚本。这种运行js脚本的方式,我们可以用来处理一些计算规则灵活多变的业务。就比如本项目中计算运费的模块,由于运费计算规则比较多变,所以就采用这种方式实现。
 
 
 

 

posted @ 2017-10-26 20:53  zeng1994  阅读(4543)  评论(0编辑  收藏  举报