[[filter]]
= Filter

Message filters are used to decide whether a `Message` should be passed along or dropped based on some criteria, such as a message header value or message content itself.
Therefore, a message filter is similar to a router, except that, for each message received from the filter's input channel, that same message may or may not be sent to the filter's output channel.
Unlike the router, it makes no decision regarding which message channel to send the message to but decides only whether to send the message at all.

NOTE: As we describe later in this section, the filter also supports a discard channel.
In certain cases, it can play the role of a very simple router (or "`switch`"), based on a boolean condition.

In Spring Integration, you can configure a message filter as a message endpoint that delegates to an implementation of the `MessageSelector` interface.
That interface is itself quite simple, as the following listing shows:

[source,java]
----
public interface MessageSelector {

    boolean accept(Message<?> message);

}
----

The `MessageFilter` constructor accepts a selector instance, as the following example shows:

[source,java]
----
MessageFilter filter = new MessageFilter(someSelector);
----

[[filter-dsl]]
== Configuring a Filter with Java, Groovy and Kotlin DSLs

The `IntegrationFlowBuilder` provided by the Java DSL (which is also used as a base for the Groovy and Kotlin DSLs) provides a number of overloaded methods for the `filter()` operator.
The `MessageSelector` abstraction mentioned above can be used as a Lambda in a `filter()` definition:

[tabs]
======
Java DSL::
+
[source, java, role="primary"]
----
@Bean
public IntegrationFlow someFlow() {
    return f -> f
              .<String>filter((payload) -> !"junk".equals(payload));
}
----

Kotlin DSL::
+
[source, kotlin, role="secondary"]
----
@Bean
fun someFlow() =
    integrationFlow {
        filter<String> { it != "junk" }
    }
----

Groovy DSL::
+
[source, groovy, role="secondary"]
----
@Bean
someFlow() {
    integrationFlow {
        filter String, { it != 'junk' }
    }
}
----
======

See more information about DSLs in the respective chapters:

* xref:dsl.adoc#java-dsl[Java DSL]
* xref:kotlin-dsl.adoc[Kotlin DSL]
* xref:groovy-dsl.adoc[Groovy DSL]

[[filter-xml]]
== Configuring a Filter with XML

In combination with the namespace and SpEL, you can configure powerful filters with very little Java code.

You can use the `<filter>` element is used to create a message-selecting endpoint.
In addition to `input-channel` and `output-channel` attributes, it requires a `ref` attribute.
The `ref` can point to a `MessageSelector` implementation, as the following example shows:

[source,xml]
----
<int:filter input-channel="input" ref="selector" output-channel="output"/>

<bean id="selector" class="example.MessageSelectorImpl"/>
----

Alternatively, you can add the `method` attribute.
In that case, the `ref` attribute may refer to any object.
The referenced method may expect either the `Message` type or the payload type of inbound messages.
The method must return a boolean value.
If the method returns 'true', the message is sent to the output channel.
The following example shows how to configure a filter that uses the `method` attribute:

[source,xml]
----
<int:filter input-channel="input" output-channel="output"
    ref="exampleObject" method="someBooleanReturningMethod"/>

<bean id="exampleObject" class="example.SomeObject"/>
----

If the selector or adapted POJO method returns `false`, a few settings  control the handling of the rejected message.
By default, (if configured as in the preceding example) rejected messages are silently dropped.
If rejection should instead result in an error condition, set the `throw-exception-on-rejection` attribute to `true`, as the following example shows:

[source,xml]
----
<int:filter input-channel="input" ref="selector"
    output-channel="output" throw-exception-on-rejection="true"/>
----

If you want rejected messages to be routed to a specific channel, provide that reference as the `discard-channel`, as the following example shows:

[source,xml]
----
<int:filter input-channel="input" ref="selector"
    output-channel="output" discard-channel="rejectedMessages"/>
----

If the `throwExceptionOnRejection == false` and no `discardChannel` is provided, the message is silently dropped and an `o.s.i.filter.MessageFilter` instance just emits a warning log message (starting with version 6.1) about this discarded message.
To drop the message with no warning in the logs, a `NullChannel` can be configured as the `discardChannel` on the filter.
The goal of the framework is to not be completely silent, by default, requiring an explicit option to be set, if that is the desired behavior.

See also xref:handler-advice/advising-filters.adoc[Advising Filters].

NOTE: Message filters are commonly used in conjunction with a publish-subscribe channel.
Many filter endpoints may be subscribed to the same channel, and they decide whether to pass the message to the next endpoint, which could be any of the supported types (such as a service activator).
This provides a reactive alternative to the more proactive approach of using a message router with a single point-to-point input channel and multiple output channels.

We recommend using a `ref` attribute if the custom filter implementation is referenced in other `<filter>` definitions.
However, if the custom filter implementation is scoped to a single `<filter>` element, you should provide an inner bean definition, as the following example shows:

[source,xml]
----
<int:filter method="someMethod" input-channel="inChannel" output-channel="outChannel">
  <beans:bean class="org.foo.MyCustomFilter"/>
</filter>
----

NOTE: Using both the `ref` attribute and an inner handler definition in the same `<filter>` configuration is not allowed, as it creates an ambiguous condition and throws an exception.

IMPORTANT: If the `ref` attribute references a bean that extends `MessageFilter` (such as filters provided by the framework itself), the configuration is optimized by injecting the output channel into the filter bean directly.
In this case, each `ref` must be to a separate bean instance (or a `prototype`-scoped bean) or use the inner `<bean/>` configuration type.
However, this optimization applies only if you do not provide any filter-specific attributes in the filter XML definition.
If you inadvertently reference the same message handler from multiple beans, you get a configuration exception.

With the introduction of SpEL support, Spring Integration added the `expression` attribute to the filter element.
It can be used to avoid Java entirely for simple filters, as the following example shows:

[source,xml]
----
<int:filter input-channel="input" expression="payload.equals('nonsense')"/>
----

The string passed as the value of the expression attribute is evaluated as a SpEL expression with the message available in the evaluation context.
If you must include the result of an expression in the scope of the application context, you can use the `#{}` notation, as defined in the https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#expressions-beandef[SpEL reference documentation], as the following example shows:

[source,xml]
----
<int:filter input-channel="input"
            expression="payload.matches(#{filterPatterns.nonsensePattern})"/>
----

If the expression itself needs to be dynamic, you can use an 'expression' sub-element.
That provides a level of indirection for resolving the expression by its key from an `ExpressionSource`.
That is a strategy interface that you can implement directly, or you can rely upon a version available in Spring Integration that loads expressions from a "`resource bundle`" and can check for modifications after a given number of seconds.
All of this is demonstrated in the following configuration example, where the expression could be reloaded within one minute if the underlying file had been modified:

[source,xml]
----
<int:filter input-channel="input" output-channel="output">
    <int:expression key="filterPatterns.example" source="myExpressions"/>
</int:filter>

<beans:bean id="myExpressions"
    class="o.s.i.expression.ReloadableResourceBundleExpressionSource">
    <beans:property name="basename" value="config/integration/expressions"/>
    <beans:property name="cacheSeconds" value="60"/>
</beans:bean>
----

If the `ExpressionSource` bean is named `expressionSource`, you need not provide the` source` attribute on the `<expression>` element.
However, in the preceding example, we show it for completeness.

The 'config/integration/expressions.properties' file (or any more-specific version with a locale extension to be resolved in the typical way that resource-bundles are loaded) can contain a key/value pair, as the following example shows:

[source]
----
filterPatterns.example=payload > 100
----

NOTE: All of these examples that use `expression` as an attribute or sub-element can also be applied within transformer, router, splitter, service-activator, and header-enricher elements.
The semantics and role of the given component type would affect the interpretation of the evaluation result, in the same way that the return value of a method-invocation would be interpreted.
For example, an expression can return strings that are to be treated as message channel names by a router component.
However, the underlying functionality of evaluating the expression against the message as the root object and resolving bean names if prefixed with '@' is consistent across all of the core EIP components within Spring Integration.

[[filter-annotations]]
== Configuring a Filter with Annotations

The following example shows how to configure a filter by using annotations:

[source,java]
----
public class PetFilter {
    ...
    @Filter  <1>
    public boolean dogsOnly(String input) {
        ...
    }
}
----

<1> An annotation indicating that this method is to be used as a filter.
It must be specified if this class is to be used as a filter.


All the configuration options provided by the XML element are also available for the `@Filter` annotation.

The filter can be either referenced explicitly from XML or, if the `@MessageEndpoint` annotation is defined on the class, detected automatically through classpath scanning.

See also xref:handler-advice/advising-with-annotations.adoc[Advising Endpoints Using Annotations].
