Convert String to Double in Spring Expression Language

2.4k views Asked by At

I'm quite new to spring expression language. I have a map which contains values as string.

{
 "id": "1",
 "object": {
  "object1": {
    "fields": {
      "value1": {
         "value":"3"
      },
      "value2": {
         "value":"2"
      }
    }
  }
 }
}

The spring expression that i have looks something like this,

((object['object1'].fields['value1'].value * object['object1'].fields['value2'].value) * 0.5)

My calculation method looks like this where SampleObject class has the map object

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

Since the value is string, I get an error saying cannot convert String to Double. This can be eliminated if i change the expression like this

((new Double(object['object1'].fields['value1'].value) * new Double(object['object1'].fields['value2'].value)) * 0.5)

But I'm looking for a solution where I don't have to change the expression or the object. Is there a solution.

Thanks in advance

2

There are 2 answers

2
Andy Clement On

You can plugin a class that supports operations on those operand types:

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;
    }

}

Then pass a customized StandardEvaluationContext to getValue():

    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());
1
shazin On

Since your JSON has value1.value and value2.value as String the Expression throws the Exception.

Either change your JSON to have Decimal values

{
 "id": "1",
 "object": {
  "object1": {
    "fields": {
      "value1": {
         "value":3.0
      },
      "value2": {
         "value":2.0
      }
    }
  }
 }
}

Or in the Expression method instead of casting do parsing.

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;
}