在Spring表达式语言中将字符串转换为双精度

在Spring表达式语言中将字符串转换为双精度,spring,hashmap,type-conversion,spring-el,Spring,Hashmap,Type Conversion,Spring El,我对spring表达式语言还很陌生。我有一个包含字符串值的映射 { "id": "1", "object": { "object1": { "fields": { "value1": { "value":"3" }, "value2": { "value":"2" } } } } } 我的春季表情是这样的 ((object['object1'].fields['value1'].v

我对spring表达式语言还很陌生。我有一个包含字符串值的映射

{
 "id": "1",
 "object": {
  "object1": {
    "fields": {
      "value1": {
         "value":"3"
      },
      "value2": {
         "value":"2"
      }
    }
  }
 }
}
我的春季表情是这样的

((object['object1'].fields['value1'].value * object['object1'].fields['value2'].value) * 0.5)
我的计算方法如下所示,其中SampleObject类具有map对象

public Double calculation(String expression, SampleObject sampleObject){
    ExpressionParser parser = new SpelExpressionParser();
    Expression exp = parser.parseExpression(expression);
    Double evaluatedValue = (Double)exp.getValue(sampleObject);
    return evaluatedValue;
}
由于该值是string,因此我得到一个错误,即无法将string转换为Double。如果我像这样更改表达式,这可以消除

((new Double(object['object1'].fields['value1'].value) * new Double(object['object1'].fields['value2'].value)) * 0.5)
但我正在寻找一种解决方案,在这种解决方案中,我不必更改表达式或对象。有解决办法吗


请提前感谢,因为您的JSON具有
value1.value
value2.value
作为字符串,表达式会引发异常

或者将JSON更改为具有十进制值

{
 "id": "1",
 "object": {
  "object1": {
    "fields": {
      "value1": {
         "value":3.0
      },
      "value2": {
         "value":2.0
      }
    }
  }
 }
}
或者在表达式方法中,而不是强制转换进行解析

public Double calculation(String expression, SampleObject sampleObject){
    ExpressionParser parser = new SpelExpressionParser();
    Expression exp = parser.parseExpression(expression);
    Double evaluatedValue = Double.parseDouble(exp.getValue(sampleObject).toString()); // This line
    return evaluatedValue;
}

您可以插入支持对这些操作数类型执行操作的类:

class StringDoubleOperatorOverloader implements OperatorOverloader {

    @Override
    public boolean overridesOperation(Operation operation, Object leftOperand,
            Object rightOperand) throws EvaluationException {
        return operation==Operation.MULTIPLY && 
               leftOperand instanceof String && 
               rightOperand instanceof String;
    }

    @Override
    public Object operate(Operation operation, Object leftOperand, Object rightOperand)
            throws EvaluationException {
        Double l = Double.valueOf((String)leftOperand);
        Double r = Double.valueOf((String)rightOperand);
        return l*r;
    }

}
然后将自定义的
StandardEvaluationContext
传递给
getValue()


正如我在问题中提到的,我不想改变地图。另外,您的第二个建议不起作用,因为问题在表达式中,而不是在评估值中。因此,我仍然收到这样的错误消息“类型为'java.lang.String'和'java.lang.String'的对象之间不支持运算符'MULTIPLY'”。仅供参考,第二个解决方案也可以这样实现,Double evaluatedValue=exp.getValue(sampleObject,Double.class);当表达式包含更多值和更多算术运算时,此操作将不起作用。表达式将更改,但格式无法更改。这就是我面临的问题。另外,我正在传递类似exp.getValue(sampleObject)的sampleObject,因为该对象就是包含这些值的对象。如果扩展插件操作符重载中支持的类型和操作,它肯定会工作吗?您可以让overridesOperation和operate方法执行您喜欢的任何操作。我的目标是找到一个不必更改表达式或包含数据的对象的解决方案。与您所做的主要不同之处在于,我使用了两个参数版本的getValue(),除了包含数据的对象之外,还可以在不同的计算上下文中传递。我的“new SampleObject()”正是我构建一个测试用例的方式,它代表了您正在做的事情,您可以传入SampleObject。
    ExpressionParser parser = new SpelExpressionParser();
    Expression exp = parser.parseExpression(expression);

    StandardEvaluationContext sec = new StandardEvaluationContext();
    sec.setOperatorOverloader(new StringDoubleOperatorOverloader());

    Double evaluatedValue = (Double)exp.getValue(sec,new SampleObject());