Groovy调用示例

来源:互联网 发布:vc新建c语言项目 编辑:程序博客网 时间:2024/05/10 22:04

项目背景介绍:

由于某电商网站的数据量比较大,价格体系变更频繁,因此采用Groovy语言对价格统一展示,设计一个价格引擎具体如下:

一 、控制层中调用Groovy脚本

                ObjectMapper mapper = new ObjectMapper();  
Map<String,Object> params = JsonUtil.jsonToMap( getInParam().get("params").toString() );
TAceRule aceRule = new TAceRule();
aceRule.setName( getInParam().get("ace_rule_name").toString() );//获取groovy脚本名称
MyBatisDAO mybatisDao = (MyBatisDAO) this.getDaoFactory().get( "myBatisDAO" );
aceRule = mybatisDao.getAceRule(aceRule);
if(aceRule == null){
getOutParam().put("errorDetail", "没有配置通用规则");
return RETURN.REQ_PARAM_ERROR;
}
// 获取groovy脚本引擎
Calculate cal = CalculateManager.instant.calculate(StringUtils.hasText(aceRule.getEngine())?aceRule.getEngine():"groovy");//获取计算引擎,默认为groovy
CalculateContext context = CalculateManager.instant.context();//实例化CalculateContext  类
context.setContext("dao", getDaoFactory());  //设置Dao,Groovy引用的时候直接用dao来调用
context.setContext("session",getSession());//设置session,
context.setContext("cookie", getCookies());//设置cookie
context.setContext("inparams", params );//设置参数
cal.calculate(aceRule.getContext(), context);//参数 aceRule.getContext() 为数据库中的groovy脚本文件。
setOutParam(new HashMap<String, Object>(context.getContext()));
getOutParam().put("errorDetail", "计算完成");
return RETURN.SUCCESS;

二、CalculateManager 接口类

public enum CalculateManager {
instant;
public Calculate calculate(String script ){
//默认获取groovy
return new ScriptCalculate(script);
}

public CalculateContext context(){
return new CalculateContext();
}
}

三、获取Groovy驱动

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import org.leafframework.mvc.service.ace.Calculate;
import org.leafframework.mvc.service.ace.CalculateContext;
import org.leafframework.util.MapUtil;
import org.springframework.util.StringUtils;


public class ScriptCalculate implements Calculate{
private ScriptEngine engine ;
@Override
public BigDecimal calculate(String calculateScript,
CalculateContext context) {
//创建绑定
Bindings bindings= engine.createBindings();
for(Map.Entry<String, ?> entry:context.getContext().entrySet()){
bindings.put(entry.getKey(), entry.getValue());
}
Object result = null;
BigDecimal ret = null;
try {
result = engine.eval(calculateScript, bindings);
MapUtil<String, Object> retMap=MapUtil.of();
if(result != null){
if(result instanceof Number){
ret= new BigDecimal(((Number)result).doubleValue());
retMap.put(evalPrice, ret);
}else if(result instanceof String){
ret= new BigDecimal((String)result);
retMap.put(evalPrice, ret);
}else if(result instanceof Bindings){
retMap.put(evalResult, new HashMap<String,Object>((Bindings)result));
}else{
retMap.put(evalResult, result);
}
}
context.setContext(retMap.map());

} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
context.setContext(MapUtil.<String,Object>of().put("error", e.getMessage()).map());
}
return ret;
}
public ScriptCalculate(String scriptname){
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName(StringUtils.hasText(scriptname)?scriptname:"javascript");
if(engine == null){ //默认使用js引擎
engine = manager.getEngineByName("javascript");
}
}
}

三、CalculateContext  类,将待传递到Groovy中的参数封装到Map中

public class CalculateContext {
private Map<String, Object> map = new HashMap<String, Object>();
public void setContext(String k, Object v){
map.put(k, v);
}
public Object getContext(String k){
return map.get(k);
}
public void setContext(Map<String, Object> map){
this.map=map;
}
public Map<String, Object> getContext(){
return map;
}
}

四、数据中groovy脚本文件

import groovy.json.JsonSlurper;
import org.leafframework.data.dao.orm.TGGoodsPrice;
import org.springframework.util.StringUtils;
import java.text.DecimalFormat;
def params = new JsonSlurper().parseText(inparams.params) ;
//data 数据格式:商品ID,数量;
String pricecode=inparams.priceCode;
String custtype=inparams.custType;
String custlvl=inparams.custLvl;
String data = params.data;
def    mybatis=dao.myBatisDAO;
def result=[:];
double orderAmont=0.0;
double feecardAmont=0.0;
double numrateAmont=0.0;
double userDiscAmont=0.0;
double realOrderAmont=0.0;
if((!StringUtils.isEmpty(data)))
{
String[] goodslist = data.split(";");
double diectPrice = 0.0;
for(String str:goodslist)
{
String[] goods = str.split(",");
String goodsId=goods[0];
int count = Integer.valueOf(goods[1]);
def priceList = mybatis.getGoodsPrice(["pricecode":pricecode?.trim(),"goodsId":goodsId?.trim()]);
if(priceList.size()==0)
{
priceList = mybatis.getGoodsPrice(["pricecode":"0001","goodsId":goodsId?.trim()]);
}
double nrAmont=0.0;
double feAmont=0.0;
double orAmont=0.0;
for(def goodprice:priceList)
{
double price   = goodprice.getValue();
int    code    = goodprice.getCode();
int    min     = 0;
int    max     = 0;
double disc    = 0.0; 
double feecard = 0.0; 
println count+" : "+price;
if( goodprice.getNumMin()!=null)
{
min = goodprice.getNumMin();
}
if( goodprice.getNumMax()!=null)
{
max = goodprice.getNumMax();
}
if( goodprice.getDiscount()!=null)
{
disc = goodprice.getDiscount();
}
if( goodprice.getFeecard()!=null)
{
feecard = goodprice.getFeecard();
}
//println price +":"+code +":  "+min+":"+max+"  :"+ disc+":"+feecard;
if( count >=min && count<=max )
{
println "1sssssss:"+disc; 
if( disc!=null &&( disc >0 && disc<1) )
{
nrAmont=(count*(price-feecard))*(1-disc);
}
feAmont = count*feecard;
orAmont = price*count;
println nrAmont+" : "+ feAmont+":"+orAmont; 
break;
}
if( code == 1)
{
println "2sssssss:"+disc; 
if( disc!=null && (disc >0 && disc<1 ))
{
nrAmont=(count*(price-feecard))*(1-disc);
}
feAmont =count*feecard;
orAmont =price*count;
}
}
orderAmont   =orderAmont+orAmont;
feecardAmont =feecardAmont+feAmont;
numrateAmont =numrateAmont+nrAmont;
}
def custdisc = mybatis.getCustDisc( custlvl );
double userrate=custdisc.get(0).getDiscount();
if( userrate >0 && userrate<1 )
{
userrate=custdisc.get(0).getDiscount();
userDiscAmont= (1-userrate)*(orderAmont-feecardAmont-numrateAmont);
println "user: "+userrate+" : "+ (orderAmont-feecardAmont-numrateAmont);
}
realOrderAmont=orderAmont-feecardAmont-numrateAmont-userDiscAmont;
}
DecimalFormat df = new DecimalFormat(".00");
result.feecardAmont    =Double.parseDouble(df.format( feecardAmont) );
result.numrateAmont    =Double.parseDouble(df.format( numrateAmont) );
result.userDiscAmont   =Double.parseDouble(df.format( userDiscAmont) );
result.orderAmont      =Double.parseDouble(df.format( orderAmont) );
result.realOrderAmont  =Double.parseDouble(df.format( realOrderAmont) );
result;

0 0
原创粉丝点击