Intercepting filter pattern
- 6 min read
- 3 chapters
Explore on Lably
ToursExplore Lably’s 3D toursStructure
Filter manager, filter chain, filters and target are components of the pattern.
Filter manager
This manages filter processing and creates the filter chain with the appropriate filters, in the correct order, and initiates processing.
Filter chain
A Filter Chain is a specific series of filters, composed so as to form a logical chain.
Filters
These are the individual filters that are mapped to a target and their processing is coordinated by filter chain.
Target
This is the resource requested by the client.
Sign in to keep reading
2 more chapters are free with a Lably account.
Consequences
Following benefits can be considered:
- Improved reusability: Common code is centralized in pluggable components enhancing reuse.
- Increased flexibility: Generic common components can be applied and removed declaratively, improving flexibility.
Reduced performance can be a concern, as unnecessarily long chains of interceptors and filters may hurt performance.
Sample code
Sample code implementation for filters with custom filter strategy is given below.
Code for implementing a filter - debugging filter:
<span id="mwQA"></span><span class="kn" id="mwQQ">import</span><span class="w" id="mwQg"> </span><span class="nn" id="mwQw">java.io.IOException</span><span class="p" id="mwRA">;</span> <span class="kn" id="mwRQ">import</span><span class="w" id="mwRg"> </span><span class="nn" id="mwRw">javax.annotation.processing.Processor</span><span class="p" id="mwSA">;</span> <span class="kn" id="mwSQ">import</span><span class="w" id="mwSg"> </span><span class="nn" id="mwSw">jakarta.servlet.ServletException</span><span class="p" id="mwTA">;</span> <span class="kn" id="mwTQ">import</span><span class="w" id="mwTg"> </span><span class="nn" id="mwTw">jakarta.servlet.ServletRequest</span><span class="p" id="mwUA">;</span> <span class="kn" id="mwUQ">import</span><span class="w" id="mwUg"> </span><span class="nn" id="mwUw">jakarta.servlet.ServletResponse</span><span class="p" id="mwVA">;</span> <span class="kd" id="mwVQ">public</span><span class="w" id="mwVg"> </span><span class="kd" id="mwVw">class</span> <span class="nc" id="mwWA">DebuggingFilter</span><span class="w" id="mwWQ"> </span><span class="kd" id="mwWg">implements</span><span class="w" id="mwWw"> </span><span class="n" id="mwXA">Processor</span><span class="w" id="mwXQ"> </span><span class="p" id="mwXg">{</span> <span class="w" id="mwXw"> </span><span class="kd" id="mwYA">private</span><span class="w" id="mwYQ"> </span><span class="n" id="mwYg">Processor</span><span class="w" id="mwYw"> </span><span class="n" id="mwZA">target</span><span class="p" id="mwZQ">;</span> <span class="w" id="mwZg"> </span><span class="kd" id="mwZw">public</span><span class="w" id="mwaA"> </span><span class="nf" id="mwaQ">DebuggingFilter</span><span class="p" id="mwag">(</span><span class="n" id="mwaw">Processor</span><span class="w" id="mwbA"> </span><span class="n" id="mwbQ">myTarget</span><span class="p" id="mwbg">)</span><span class="w" id="mwbw"> </span><span class="p" id="mwcA">{</span> <span class="w" id="mwcQ"> </span><span class="n" id="mwcg">target</span><span class="w" id="mwcw"> </span><span class="o" id="mwdA">=</span><span class="w" id="mwdQ"> </span><span class="n" id="mwdg">myTarget</span><span class="p" id="mwdw">;</span> <span class="w" id="mweA"> </span><span class="p" id="mweQ">}</span> <span class="w" id="mweg"> </span><span class="kd" id="mwew">public</span><span class="w" id="mwfA"> </span><span class="kt" id="mwfQ">void</span><span class="w" id="mwfg"> </span><span class="nf" id="mwfw">execute</span><span class="p" id="mwgA">(</span><span class="n" id="mwgQ">ServletRequest</span><span class="w" id="mwgg"> </span><span class="n" id="mwgw">req</span><span class="p" id="mwhA">,</span><span class="w" id="mwhQ"> </span><span class="n" id="mwhg">ServletResponse</span><span class="w" id="mwhw"> </span><span class="n" id="mwiA">res</span><span class="p" id="mwiQ">)</span><span class="w" id="mwig"> </span><span class="kd" id="mwiw">throws</span><span class="w" id="mwjA"> </span><span class="n" id="mwjQ">IOException</span><span class="p" id="mwjg">,</span><span class="w" id="mwjw"> </span><span class="n" id="mwkA">ServletException</span><span class="w" id="mwkQ"> </span><span class="p" id="mwkg">{</span> <span class="w" id="mwkw"> </span><span class="c1" id="mwlA">// Do some filter processing here, such as </span> <span class="w" id="mwlQ"> </span><span class="c1" id="mwlg">// displaying request parameters</span> <span class="w" id="mwlw"> </span><span class="n" id="mwmA">target</span><span class="p" id="mwmQ">.</span><span class="na" id="mwmg">execute</span><span class="p" id="mwmw">(</span><span class="n" id="mwnA">req</span><span class="p" id="mwnQ">,</span><span class="w" id="mwng"> </span><span class="n" id="mwnw">res</span><span class="p" id="mwoA">);</span> <span class="w" id="mwoQ"> </span><span class="p" id="mwog">}</span> <span class="p" id="mwow">}</span>Code for implementing a filter - core processor:
<span id="mwrA"></span><span class="kn" id="mwrQ">import</span><span class="w" id="mwrg"> </span><span class="nn" id="mwrw">java.io.IOException</span><span class="p" id="mwsA">;</span> <span class="kn" id="mwsQ">import</span><span class="w" id="mwsg"> </span><span class="nn" id="mwsw">javax.annotation.processing.Processor</span><span class="p" id="mwtA">;</span> <span class="kn" id="mwtQ">import</span><span class="w" id="mwtg"> </span><span class="nn" id="mwtw">jakarta.servlet.ServletException</span><span class="p" id="mwuA">;</span> <span class="kn" id="mwuQ">import</span><span class="w" id="mwug"> </span><span class="nn" id="mwuw">jakarta.servlet.ServletRequest</span><span class="p" id="mwvA">;</span> <span class="kn" id="mwvQ">import</span><span class="w" id="mwvg"> </span><span class="nn" id="mwvw">jakarta.servlet.ServletResponse</span><span class="p" id="mwwA">;</span> <span class="kd" id="mwwQ">public</span><span class="w" id="mwwg"> </span><span class="kd" id="mwww">class</span> <span class="nc" id="mwxA">CoreProcessor</span><span class="w" id="mwxQ"> </span><span class="kd" id="mwxg">implements</span><span class="w" id="mwxw"> </span><span class="n" id="mwyA">Processor</span><span class="w" id="mwyQ"> </span><span class="p" id="mwyg">{</span> <span class="w" id="mwyw"> </span><span class="kd" id="mwzA">private</span><span class="w" id="mwzQ"> </span><span class="n" id="mwzg">Processor</span><span class="w" id="mwzw"> </span><span class="n" id="mw0A">target</span><span class="p" id="mw0Q">;</span> <span class="w" id="mw0g"> </span><span class="kd" id="mw0w">public</span><span class="w" id="mw1A"> </span><span class="nf" id="mw1Q">CoreProcessor</span><span class="p" id="mw1g">()</span><span class="w" id="mw1w"> </span><span class="p" id="mw2A">{</span> <span class="w" id="mw2Q"> </span><span class="k" id="mw2g">this</span><span class="p" id="mw2w">(</span><span class="kc" id="mw3A">null</span><span class="p" id="mw3Q">);</span> <span class="w" id="mw3g"> </span><span class="p" id="mw3w">}</span> <span class="w" id="mw4A"> </span><span class="kd" id="mw4Q">public</span><span class="w" id="mw4g"> </span><span class="nf" id="mw4w">CoreProcessor</span><span class="p" id="mw5A">(</span><span class="n" id="mw5Q">Processor</span><span class="w" id="mw5g"> </span><span class="n" id="mw5w">myTarget</span><span class="p" id="mw6A">)</span><span class="w" id="mw6Q"> </span><span class="p" id="mw6g">{</span> <span class="w" id="mw6w"> </span><span class="n" id="mw7A">target</span><span class="w" id="mw7Q"> </span><span class="o" id="mw7g">=</span><span class="w" id="mw7w"> </span><span class="n" id="mw8A">myTarget</span><span class="p" id="mw8Q">;</span> <span class="w" id="mw8g"> </span><span class="p" id="mw8w">}</span> <span class="w" id="mw9A"> </span><span class="kd" id="mw9Q">public</span><span class="w" id="mw9g"> </span><span class="kt" id="mw9w">void</span><span class="w" id="mw-A"> </span><span class="nf" id="mw-Q">execute</span><span class="p" id="mw-g">(</span><span class="n" id="mw-w">ServletRequest</span><span class="w" id="mw_A"> </span><span class="n" id="mw_Q">req</span><span class="p" id="mw_g">,</span><span class="w" id="mw_w"> </span><span class="n" id="mwAQA">ServletResponse</span><span class="w" id="mwAQE"> </span><span class="n" id="mwAQI">res</span><span class="p" id="mwAQM">)</span><span class="w" id="mwAQQ"> </span><span class="kd" id="mwAQU">throws</span><span class="w" id="mwAQY"> </span><span class="n" id="mwAQc">IOException</span><span class="p" id="mwAQg">,</span><span class="w" id="mwAQk"> </span><span class="n" id="mwAQo">ServletException</span><span class="w" id="mwAQs"> </span><span class="p" id="mwAQw">{</span> <span class="w" id="mwAQ0"> </span><span class="c1" id="mwAQ4">// Do core processing here</span> <span class="w" id="mwAQ8"> </span><span class="p" id="mwARA">}</span> <span class="p" id="mwARE">}</span>Code for handling requests:
<span id="mwARo"></span><span class="kn" id="mwARs">import</span><span class="w" id="mwARw"> </span><span class="nn" id="mwAR0">java.io.IOException</span><span class="p" id="mwAR4">;</span> <span class="kn" id="mwAR8">import</span><span class="w" id="mwASA"> </span><span class="nn" id="mwASE">javax.annotation.processing.Processor</span><span class="p" id="mwASI">;</span> <span class="kn" id="mwASM">import</span><span class="w" id="mwASQ"> </span><span class="nn" id="mwASU">jakarta.servlet.ServletException</span><span class="p" id="mwASY">;</span> <span class="kn" id="mwASc">import</span><span class="w" id="mwASg"> </span><span class="nn" id="mwASk">jakarta.servlet.ServletRequest</span><span class="p" id="mwASo">;</span> <span class="kn" id="mwASs">import</span><span class="w" id="mwASw"> </span><span class="nn" id="mwAS0">jakarta.servlet.ServletResponse</span><span class="p" id="mwAS4">;</span> <span class="kd" id="mwAS8">public</span><span class="w" id="mwATA"> </span><span class="kt" id="mwATE">void</span><span class="w" id="mwATI"> </span><span class="nf" id="mwATM">processRequest</span><span class="p" id="mwATQ">(</span><span class="n" id="mwATU">ServletRequest</span><span class="w" id="mwATY"> </span><span class="n" id="mwATc">req</span><span class="p" id="mwATg">,</span><span class="w" id="mwATk"> </span><span class="n" id="mwATo">ServletResponse</span><span class="w" id="mwATs"> </span><span class="n" id="mwATw">res</span><span class="p" id="mwAT0">)</span><span class="w" id="mwAT4"> </span><span class="kd" id="mwAT8">throws</span><span class="w" id="mwAUA"> </span><span class="n" id="mwAUE">IOException</span><span class="p" id="mwAUI">,</span><span class="w" id="mwAUM"> </span><span class="n" id="mwAUQ">ServletException</span><span class="w" id="mwAUU"> </span><span class="p" id="mwAUY">{</span> <span class="w" id="mwAUc"> </span><span class="n" id="mwAUg">Processor</span><span class="w" id="mwAUk"> </span><span class="n" id="mwAUo">processors</span><span class="w" id="mwAUs"> </span><span class="o" id="mwAUw">=</span><span class="w" id="mwAU0"> </span><span class="k" id="mwAU4">new</span><span class="w" id="mwAU8"> </span><span class="n" id="mwAVA">DebuggingFilter</span><span class="p" id="mwAVE">(</span><span class="k" id="mwAVI">new</span><span class="w" id="mwAVM"> </span><span class="n" id="mwAVQ">AuthenticationFilter</span><span class="p" id="mwAVU">(</span><span class="k" id="mwAVY">new</span><span class="w" id="mwAVc"> </span><span class="n" id="mwAVg">CoreProcessor</span><span class="p" id="mwAVk">()));</span> <span class="w" id="mwAVo"> </span><span class="n" id="mwAVs">processors</span><span class="p" id="mwAVw">.</span><span class="na" id="mwAV0">execute</span><span class="p" id="mwAV4">(</span><span class="n" id="mwAV8">req</span><span class="p" id="mwAWA">,</span><span class="w" id="mwAWE"> </span><span class="n" id="mwAWI">res</span><span class="p" id="mwAWM">);</span> <span class="w" id="mwAWQ"> </span><span class="c1" id="mwAWU">//Then dispatch to next resource, which is probably </span> <span class="w" id="mwAWY"> </span><span class="c1" id="mwAWc">// the View to display</span> <span class="w" id="mwAWg"> </span><span class="n" id="mwAWk">dispatcher</span><span class="p" id="mwAWo">.</span><span class="na" id="mwAWs">dispatch</span><span class="p" id="mwAWw">(</span><span class="n" id="mwAW0">req</span><span class="p" id="mwAW4">,</span><span class="w" id="mwAW8"> </span><span class="n" id="mwAXA">res</span><span class="p" id="mwAXE">);</span> <span class="p" id="mwAXI">}</span>Code for filter manager:
<span id="mwAXs"></span><span class="kn" id="mwAXw">import</span><span class="w" id="mwAX0"> </span><span class="nn" id="mwAX4">java.io.IOException</span><span class="p" id="mwAX8">;</span> <span class="kn" id="mwAYA">import</span><span class="w" id="mwAYE"> </span><span class="nn" id="mwAYI">javax.annotation.processing.Processor</span><span class="p" id="mwAYM">;</span> <span class="kn" id="mwAYQ">import</span><span class="w" id="mwAYU"> </span><span class="nn" id="mwAYY">jakarta.servlet.ServletException</span><span class="p" id="mwAYc">;</span> <span class="kn" id="mwAYg">import</span><span class="w" id="mwAYk"> </span><span class="nn" id="mwAYo">jakarta.servlet.ServletRequest</span><span class="p" id="mwAYs">;</span> <span class="kn" id="mwAYw">import</span><span class="w" id="mwAY0"> </span><span class="nn" id="mwAY4">jakarta.servlet.ServletResponse</span><span class="p" id="mwAY8">;</span> <span class="kd" id="mwAZA">public</span><span class="w" id="mwAZE"> </span><span class="kt" id="mwAZI">void</span><span class="w" id="mwAZM"> </span><span class="nf" id="mwAZQ">processRequest</span><span class="p" id="mwAZU">(</span><span class="n" id="mwAZY">ServletRequest</span><span class="w" id="mwAZc"> </span><span class="n" id="mwAZg">req</span><span class="p" id="mwAZk">,</span><span class="w" id="mwAZo"> </span><span class="n" id="mwAZs">ServletResponse</span><span class="w" id="mwAZw"> </span><span class="n" id="mwAZ0">res</span><span class="p" id="mwAZ4">)</span><span class="w" id="mwAZ8"> </span><span class="kd" id="mwAaA">throws</span><span class="w" id="mwAaE"> </span><span class="n" id="mwAaI">IOException</span><span class="p" id="mwAaM">,</span><span class="w" id="mwAaQ"> </span><span class="n" id="mwAaU">ServletException</span><span class="w" id="mwAaY"> </span><span class="p" id="mwAac">{</span> <span class="w" id="mwAag"> </span><span class="n" id="mwAak">Processor</span><span class="w" id="mwAao"> </span><span class="n" id="mwAas">processors</span><span class="w" id="mwAaw"> </span><span class="o" id="mwAa0">=</span><span class="w" id="mwAa4"> </span><span class="k" id="mwAa8">new</span><span class="w" id="mwAbA"> </span><span class="n" id="mwAbE">DebuggingFilter</span><span class="p" id="mwAbI">(</span><span class="k" id="mwAbM">new</span><span class="w" id="mwAbQ"> </span><span class="n" id="mwAbU">AuthenticationFilter</span><span class="p" id="mwAbY">(</span><span class="k" id="mwAbc">new</span><span class="w" id="mwAbg"> </span><span class="n" id="mwAbk">CoreProcessor</span><span class="p" id="mwAbo">()));</span> <span class="w" id="mwAbs"> </span><span class="n" id="mwAbw">processors</span><span class="p" id="mwAb0">.</span><span class="na" id="mwAb4">execute</span><span class="p" id="mwAb8">(</span><span class="n" id="mwAcA">req</span><span class="p" id="mwAcE">,</span><span class="w" id="mwAcI"> </span><span class="n" id="mwAcM">res</span><span class="p" id="mwAcQ">);</span> <span class="w" id="mwAcU"> </span><span class="c1" id="mwAcY">// Then dispatch to next resource, which is probably </span> <span class="w" id="mwAcc"> </span><span class="c1" id="mwAcg">// the View to display</span> <span class="w" id="mwAck"> </span><span class="n" id="mwAco">dispatcher</span><span class="p" id="mwAcs">.</span><span class="na" id="mwAcw">dispatch</span><span class="p" id="mwAc0">(</span><span class="n" id="mwAc4">req</span><span class="p" id="mwAc8">,</span><span class="w" id="mwAdA"> </span><span class="n" id="mwAdE">res</span><span class="p" id="mwAdI">);</span> <span class="p" id="mwAdM">}</span>Code for filter chain:
<span id="mwAdw"></span><span class="kn" id="mwAd0">import</span><span class="w" id="mwAd4"> </span><span class="nn" id="mwAd8">jakarta.servlet.Filter</span><span class="p" id="mwAeA">;</span> <span class="kd" id="mwAeE">public</span><span class="w" id="mwAeI"> </span><span class="kd" id="mwAeM">class</span> <span class="nc" id="mwAeQ">FilterChain</span><span class="w" id="mwAeU"> </span><span class="p" id="mwAeY">{</span> <span class="w" id="mwAec"> </span><span class="c1" id="mwAeg">// filter chain </span> <span class="w" id="mwAek"> </span><span class="c1" id="mwAeo">// apply filters</span> <span class="w" id="mwAes"> </span><span class="k" id="mwAew">for</span><span class="w" id="mwAe0"> </span><span class="p" id="mwAe4">(</span><span class="kd" id="mwAe8">final</span><span class="w" id="mwAfA"> </span><span class="n" id="mwAfE">Filter</span><span class="w" id="mwAfI"> </span><span class="n" id="mwAfM">filter</span><span class="w" id="mwAfQ"> </span><span class="p" id="mwAfU">:</span><span class="w" id="mwAfY"> </span><span class="n" id="mwAfc">filters</span><span class="p" id="mwAfg">)</span><span class="w" id="mwAfk"> </span><span class="p" id="mwAfo">{</span> <span class="w" id="mwAfs"> </span><span class="c1" id="mwAfw">// pass request & response through various </span> <span class="w" id="mwAf0"> </span><span class="c1" id="mwAf4">// filters</span> <span class="w" id="mwAf8"> </span><span class="n" id="mwAgA">filter</span><span class="p" id="mwAgE">.</span><span class="na" id="mwAgI">execute</span><span class="p" id="mwAgM">(</span><span class="n" id="mwAgQ">request</span><span class="p" id="mwAgU">,</span><span class="w" id="mwAgY"> </span><span class="n" id="mwAgc">response</span><span class="p" id="mwAgg">);</span> <span class="w" id="mwAgk"> </span><span class="p" id="mwAgo">}</span> <span class="w" id="mwAgs"> </span><span class="p" id="mwAgw">}</span> <span class="p" id="mwAg0">}</span>
