弹簧表达式(SpEL)支持投影集合对象的设置值吗?
尝试运行示例代码时出现以下错误。
Exception in thread "main" org.springframework.expression.spel.SpelEvaluationException: EL1068E:(pos 1310742): the expression component '![comment]' is not assignable
我要做的是 - 在符合特定条件的所有对象上设置一个值。 (下面的示例可能不符合最佳实践,因为我试图保持简单快速)
package com.test;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.util.ArrayList;
import java.util.List;
public class SpELTest {
public static class Person {
public String name;
public int age;
public String comment;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", comment='" + comment + '\'' +
'}';
}
}
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Person 1", 10));
people.add(new Person("Person 2", 20));
people.add(new Person("Person 3", 30));
people.add(new Person("Person 4", 40));
people.add(new Person("Person 5", 50));
people.add(new Person("Person 6", 60));
people.add(new Person("Person 7", 70));
people.add(new Person("Person 8", 80));
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("people", people);
// check the projected
List<String> projected = (List<String>) parser.parseExpression("#people.?[age > 50].![name]").getValue(context);
for (String p : projected) {
System.out.println(p);
}
// use expression to set values
parser.parseExpression("#people.?[age > 50].![comment]").setValue(context, "older than 50");
for (Person p : people) {
System.out.println(p);
}
}
}
输出:
Person 6
Person 7
Person 8
Exception in thread "main" org.springframework.expression.spel.SpelEvaluationException: EL1068E:(pos 1310742): the expression component '![comment]' is not assignable
at org.springframework.expression.spel.ast.ValueRef$TypedValueHolderValueRef.setValue(ValueRef.java:78)
at org.springframework.expression.spel.ast.CompoundExpression.setValue(CompoundExpression.java:87)
at org.springframework.expression.spel.standard.SpelExpression.setValue(SpelExpression.java:169)
at com.test.SpELTest.main(SpELTest.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:88)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:613)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
答案 0 :(得分:0)
您的代码中存在两个问题。
首先 - 你无法对一些简单属性的投射进行分配。
让我们考虑以下课程:
class Person {
String name
}
可以通过
更改Person
的名称
person.name = "newValue"
但你要做的是:
String projection = person.name
projection = "newValue"
这不会奏效。
第二件事是您无法将值older than 50
分配给集合(List
)。
你可以做这样的事情:
parser.parseExpression("(#people.?[age > 50 and comment == null])[0].comment")
.setValue(context, "older than 50");
但这只会改变结果投影中的第一项。
SpEL
没有简单的方法可以执行此操作,但您可以通过context.registerFunction
注册一些外部函数。这样的函数可以接受Person
对象的收集并对它们执行变异。