parent
e97fc7be38
commit
84cce6018c
|
@ -66,50 +66,6 @@ If you prefer numeric comparisons instead, avoid number-based `null` comparisons
|
||||||
in favor of comparisons against zero (for example, `X > 0` or `X < 0`).
|
in favor of comparisons against zero (for example, `X > 0` or `X < 0`).
|
||||||
====
|
====
|
||||||
|
|
||||||
In addition to the standard relational operators, SpEL supports the `instanceof` and regular
|
|
||||||
expression-based `matches` operators. The following listing shows examples of both:
|
|
||||||
|
|
||||||
[tabs]
|
|
||||||
======
|
|
||||||
Java::
|
|
||||||
+
|
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
|
||||||
----
|
|
||||||
// evaluates to false
|
|
||||||
boolean falseValue = parser.parseExpression(
|
|
||||||
"'xyz' instanceof T(Integer)").getValue(Boolean.class);
|
|
||||||
|
|
||||||
// evaluates to true
|
|
||||||
boolean trueValue = parser.parseExpression(
|
|
||||||
"'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
|
|
||||||
|
|
||||||
// evaluates to false
|
|
||||||
boolean falseValue = parser.parseExpression(
|
|
||||||
"'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
|
|
||||||
----
|
|
||||||
|
|
||||||
Kotlin::
|
|
||||||
+
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
|
||||||
----
|
|
||||||
// evaluates to false
|
|
||||||
val falseValue = parser.parseExpression(
|
|
||||||
"'xyz' instanceof T(Integer)").getValue(Boolean::class.java)
|
|
||||||
|
|
||||||
// evaluates to true
|
|
||||||
val trueValue = parser.parseExpression(
|
|
||||||
"'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
|
|
||||||
|
|
||||||
// evaluates to false
|
|
||||||
val falseValue = parser.parseExpression(
|
|
||||||
"'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
|
|
||||||
----
|
|
||||||
======
|
|
||||||
|
|
||||||
CAUTION: Be careful with primitive types, as they are immediately boxed up to their
|
|
||||||
wrapper types. For example, `1 instanceof T(int)` evaluates to `false`, while
|
|
||||||
`1 instanceof T(Integer)` evaluates to `true`.
|
|
||||||
|
|
||||||
Each symbolic operator can also be specified as a purely textual equivalent. This avoids
|
Each symbolic operator can also be specified as a purely textual equivalent. This avoids
|
||||||
problems where the symbols used have special meaning for the document type in which the
|
problems where the symbols used have special meaning for the document type in which the
|
||||||
expression is embedded (such as in an XML document). The textual equivalents are:
|
expression is embedded (such as in an XML document). The textual equivalents are:
|
||||||
|
@ -124,6 +80,104 @@ expression is embedded (such as in an XML document). The textual equivalents are
|
||||||
|
|
||||||
All of the textual operators are case-insensitive.
|
All of the textual operators are case-insensitive.
|
||||||
|
|
||||||
|
In addition to the standard relational operators, SpEL supports the `between`,
|
||||||
|
`instanceof`, and regular expression-based `matches` operators. The following listing
|
||||||
|
shows examples of all three:
|
||||||
|
|
||||||
|
[tabs]
|
||||||
|
======
|
||||||
|
Java::
|
||||||
|
+
|
||||||
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
|
----
|
||||||
|
boolean result;
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"1 between {1, 5}").getValue(Boolean.class);
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"1 between {10, 15}").getValue(Boolean.class);
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'elephant' between {'aardvark', 'zebra'}").getValue(Boolean.class);
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'elephant' between {'aardvark', 'cobra'}").getValue(Boolean.class);
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"123 instanceof T(Integer)").getValue(Boolean.class);
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'xyz' instanceof T(Integer)").getValue(Boolean.class);
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
|
||||||
|
----
|
||||||
|
|
||||||
|
Kotlin::
|
||||||
|
+
|
||||||
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
|
----
|
||||||
|
// evaluates to true
|
||||||
|
var result = parser.parseExpression(
|
||||||
|
"1 between {1, 5}").getValue(Boolean::class.java)
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"1 between {10, 15}").getValue(Boolean::class.java)
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'elephant' between {'aardvark', 'zebra'}").getValue(Boolean::class.java)
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'elephant' between {'aardvark', 'cobra'}").getValue(Boolean::class.java)
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"123 instanceof T(Integer)").getValue(Boolean::class.java)
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'xyz' instanceof T(Integer)").getValue(Boolean::class.java)
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean::class.java)
|
||||||
|
----
|
||||||
|
======
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
The left operand to the `between` operator must be a single value, and the right operand
|
||||||
|
must be a 2-element list which defines the range.
|
||||||
|
|
||||||
|
The `between` operator returns `true` if the left operand is _between_ the two elements
|
||||||
|
in the range, inclusive (using a comparison algorithm based on `java.lang.Comparable`).
|
||||||
|
In addition, the first element in the range must be less than or equal to the second
|
||||||
|
element in the range.
|
||||||
|
====
|
||||||
|
|
||||||
|
CAUTION: Be careful with primitive types, as they are immediately boxed up to their
|
||||||
|
wrapper types. For example, `1 instanceof T(int)` evaluates to `false`, while
|
||||||
|
`1 instanceof T(Integer)` evaluates to `true`.
|
||||||
|
|
||||||
|
|
||||||
[[expressions-operators-logical]]
|
[[expressions-operators-logical]]
|
||||||
== Logical Operators
|
== Logical Operators
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -26,12 +26,18 @@ import org.springframework.expression.spel.SpelMessage;
|
||||||
import org.springframework.expression.spel.support.BooleanTypedValue;
|
import org.springframework.expression.spel.support.BooleanTypedValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the between operator. The left operand to between must be a single value and
|
* Represents the {@code between} operator.
|
||||||
* the right operand must be a list - this operator returns true if the left operand is
|
*
|
||||||
* between (using the registered comparator) the two elements in the list. The definition
|
* <p>The left operand must be a single value, and the right operand must be a
|
||||||
* of between being inclusive follows the SQL BETWEEN definition.
|
* 2-element list which defines the range.
|
||||||
|
*
|
||||||
|
* <p>This operator returns {@code true} if the left operand is between the two
|
||||||
|
* elements in the range, inclusive (using the registered {@link TypeComparator}
|
||||||
|
* for comparison). In addition, the first element in the range must be less than
|
||||||
|
* or equal to the second element in the range.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
|
* @author Sam Brannen
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class OperatorBetween extends Operator {
|
public class OperatorBetween extends Operator {
|
||||||
|
|
|
@ -221,6 +221,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||||
void relationalOperators() {
|
void relationalOperators() {
|
||||||
boolean result = parser.parseExpression("2 == 2").getValue(Boolean.class);
|
boolean result = parser.parseExpression("2 == 2").getValue(Boolean.class);
|
||||||
assertThat(result).isTrue();
|
assertThat(result).isTrue();
|
||||||
|
|
||||||
// evaluates to false
|
// evaluates to false
|
||||||
result = parser.parseExpression("2 < -5.0").getValue(Boolean.class);
|
result = parser.parseExpression("2 < -5.0").getValue(Boolean.class);
|
||||||
assertThat(result).isFalse();
|
assertThat(result).isFalse();
|
||||||
|
@ -232,17 +233,47 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void otherOperators() {
|
void otherOperators() {
|
||||||
// evaluates to false
|
boolean result;
|
||||||
boolean falseValue = parser.parseExpression("'xyz' instanceof T(int)").getValue(Boolean.class);
|
|
||||||
assertThat(falseValue).isFalse();
|
|
||||||
|
|
||||||
// evaluates to true
|
// evaluates to true
|
||||||
boolean trueValue = parser.parseExpression("'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
|
result = parser.parseExpression(
|
||||||
assertThat(trueValue).isTrue();
|
"1 between {1, 5}").getValue(Boolean.class);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
|
||||||
// evaluates to false
|
// evaluates to false
|
||||||
falseValue = parser.parseExpression("'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
|
result = parser.parseExpression(
|
||||||
assertThat(falseValue).isFalse();
|
"1 between {10, 15}").getValue(Boolean.class);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'elephant' between {'aardvark', 'zebra'}").getValue(Boolean.class);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'elephant' between {'aardvark', 'cobra'}").getValue(Boolean.class);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"123 instanceof T(Integer)").getValue(Boolean.class);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'xyz' instanceof T(Integer)").getValue(Boolean.class);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
|
||||||
|
// evaluates to true
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
|
||||||
|
// evaluates to false
|
||||||
|
result = parser.parseExpression(
|
||||||
|
"'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);
|
||||||
|
assertThat(result).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue