2011-07-21 11 views
5

Czy operator języka Spring Expression obsługuje operator IN? Podobne do SQL IN.Czy operator języka Spring Expression obsługuje operator IN?

public class Security { 
private secTyp1; 
public Security (String aSecTyp1) { 
    secTyp1 = aSecTyp1; 
} 
} 

Security security = new Security("BOND"); 
StandardEvaluationContext context = new StandardEvaluationContext(security); 
ExpressionParser parser = new SpelExpressionParser(); 
// This should return true 
boolean result = parser.parseExpression("secTyp1 **IN** {'BOND','SWPI'}").getValue(context, Boolean.class); 
// This should return false 
result = parser.parseExpression("secTyp1 **IN** {'FUT','SWPI'}").getValue(context, Boolean.class); 

otrzymuję następujący wyjątek

org.springframework.expression.spel.SpelParseException: EL1041E:(pos 8): After parsing a valid expression, there is still more data in the expression: 'IN' 
    at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:118) 
    at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:56) 
    at org.springframework.expression.spel.standard.SpelExpressionParser.doParseExpression(SpelExpressionParser.java:1) 
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:66) 
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:56) 
    at com.rules.AssignableSecurityRule.evaluateInCondition(AssignableSecurityRule.java:48) 
    at com.rules.AssignableSecurityRuleTest.testINCondition(AssignableSecurityRuleTest.java:43) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

Odpowiedz

5

nie obsługuje Operatora, ponieważ nie jest to potrzebne. Zamiast tego możesz użyć funkcji wywołania Method.

Tak więc, wywołanie .contains (..) na liście zrobi to, co chcesz.

Można spróbować te dwa rozwiązania

@Test 
    public void solutionOneTest() { 
     final Security security = new Security("BOND"); 
     final EvaluationContext context = new StandardEvaluationContext(security); 

     Boolean contains = PARSER.parseExpression("{'BOND','SWPI'}.contains(#root.secTyp1)").getValue(context, Boolean.class); 
     Assert.assertTrue(contains); 

     contains = PARSER.parseExpression("{'FUT','SWPI'}.contains(#root.secTyp1)").getValue(context, Boolean.class); 
     Assert.assertFalse(contains); 
    } 

    @Test 
    public void solutionTwoTest() { 
     final Security security = new Security("BOND"); 
     final EvaluationContext context = new StandardEvaluationContext(); 
     context.setVariable("sec", security); 

     Boolean contains = PARSER.parseExpression("{'BOND','SWPI'}.contains(#sec.secTyp1)").getValue(context, Boolean.class); 
     Assert.assertTrue(contains); 

     contains = PARSER.parseExpression("{'FUT','SWPI'}.contains(#sec.secTyp1)").getValue(context, Boolean.class); 
     Assert.assertFalse(contains); 
    } 
+1

.contains() działa . Można również użyć dopasowań: secTyp1 odpowiada "BOND | SWPI ' – Heathen

+0

@Heathen ingenius –

0

Oprócz wywoływania metod bezpośrednio w odpowiedzi micfra, w Spel obsługuje również kilka bardzo silnych wyrażeń filtrowania kolekcji, jak również. Collection Selection pozwala odfiltrować podmenu dopasowanie wartości, kiedy można następnie przetestować rozmiarze:

!{'BOND','SWPI'}.?[#this == 'BOND'].empty 

Gdzie to jest naprawdę przydatny filtruje wymienia złożonych obiektów:

!securities.?[secTyp1 == 'BOND'].empty