blob: 051383777973efb0a40d189a40188558f7d53f6e [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Source code</title>
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
</head>
<body>
<main role="main">
<div class="sourceContainer">
<pre><span class="sourceLineNo">001</span><a id="line.1">/*</a>
<span class="sourceLineNo">002</span><a id="line.2"> * Licensed to the Apache Software Foundation (ASF) under one</a>
<span class="sourceLineNo">003</span><a id="line.3"> * or more contributor license agreements. See the NOTICE file</a>
<span class="sourceLineNo">004</span><a id="line.4"> * distributed with this work for additional information</a>
<span class="sourceLineNo">005</span><a id="line.5"> * regarding copyright ownership. The ASF licenses this file</a>
<span class="sourceLineNo">006</span><a id="line.6"> * to you under the Apache License, Version 2.0 (the</a>
<span class="sourceLineNo">007</span><a id="line.7"> * "License"); you may not use this file except in compliance</a>
<span class="sourceLineNo">008</span><a id="line.8"> * with the License. You may obtain a copy of the License at</a>
<span class="sourceLineNo">009</span><a id="line.9"> *</a>
<span class="sourceLineNo">010</span><a id="line.10"> * http://www.apache.org/licenses/LICENSE-2.0</a>
<span class="sourceLineNo">011</span><a id="line.11"> *</a>
<span class="sourceLineNo">012</span><a id="line.12"> * Unless required by applicable law or agreed to in writing,</a>
<span class="sourceLineNo">013</span><a id="line.13"> * software distributed under the License is distributed on an</a>
<span class="sourceLineNo">014</span><a id="line.14"> * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</a>
<span class="sourceLineNo">015</span><a id="line.15"> * KIND, either express or implied. See the License for the</a>
<span class="sourceLineNo">016</span><a id="line.16"> * specific language governing permissions and limitations</a>
<span class="sourceLineNo">017</span><a id="line.17"> * under the License.</a>
<span class="sourceLineNo">018</span><a id="line.18"> */</a>
<span class="sourceLineNo">019</span><a id="line.19">package org.apache.shiro.web.servlet;</a>
<span class="sourceLineNo">020</span><a id="line.20"></a>
<span class="sourceLineNo">021</span><a id="line.21">import org.slf4j.Logger;</a>
<span class="sourceLineNo">022</span><a id="line.22">import org.slf4j.LoggerFactory;</a>
<span class="sourceLineNo">023</span><a id="line.23"></a>
<span class="sourceLineNo">024</span><a id="line.24">import javax.servlet.FilterChain;</a>
<span class="sourceLineNo">025</span><a id="line.25">import javax.servlet.ServletException;</a>
<span class="sourceLineNo">026</span><a id="line.26">import javax.servlet.ServletRequest;</a>
<span class="sourceLineNo">027</span><a id="line.27">import javax.servlet.ServletResponse;</a>
<span class="sourceLineNo">028</span><a id="line.28">import java.io.IOException;</a>
<span class="sourceLineNo">029</span><a id="line.29"></a>
<span class="sourceLineNo">030</span><a id="line.30">/**</a>
<span class="sourceLineNo">031</span><a id="line.31"> * Filter base class that guarantees to be just executed once per request,</a>
<span class="sourceLineNo">032</span><a id="line.32"> * on any servlet container. It provides a {@link #doFilterInternal}</a>
<span class="sourceLineNo">033</span><a id="line.33"> * method with HttpServletRequest and HttpServletResponse arguments.</a>
<span class="sourceLineNo">034</span><a id="line.34"> * &lt;p/&gt;</a>
<span class="sourceLineNo">035</span><a id="line.35"> * The {@link #getAlreadyFilteredAttributeName} method determines how</a>
<span class="sourceLineNo">036</span><a id="line.36"> * to identify that a request is already filtered. The default implementation</a>
<span class="sourceLineNo">037</span><a id="line.37"> * is based on the configured name of the concrete filter instance.</a>
<span class="sourceLineNo">038</span><a id="line.38"> * &lt;h3&gt;Controlling filter execution&lt;/h3&gt;</a>
<span class="sourceLineNo">039</span><a id="line.39"> * 1.2 introduced the {@link #isEnabled(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} method and</a>
<span class="sourceLineNo">040</span><a id="line.40"> * {@link #isEnabled()} property to allow explicit control over whether the filter executes (or allows passthrough)</a>
<span class="sourceLineNo">041</span><a id="line.41"> * for any given request.</a>
<span class="sourceLineNo">042</span><a id="line.42"> * &lt;p/&gt;</a>
<span class="sourceLineNo">043</span><a id="line.43"> * &lt;b&gt;NOTE&lt;/b&gt; This class was initially borrowed from the Spring framework but has continued modifications.</a>
<span class="sourceLineNo">044</span><a id="line.44"> *</a>
<span class="sourceLineNo">045</span><a id="line.45"> * @since 0.1</a>
<span class="sourceLineNo">046</span><a id="line.46"> */</a>
<span class="sourceLineNo">047</span><a id="line.47">public abstract class OncePerRequestFilter extends NameableFilter {</a>
<span class="sourceLineNo">048</span><a id="line.48"></a>
<span class="sourceLineNo">049</span><a id="line.49"> /**</a>
<span class="sourceLineNo">050</span><a id="line.50"> * Private internal log instance.</a>
<span class="sourceLineNo">051</span><a id="line.51"> */</a>
<span class="sourceLineNo">052</span><a id="line.52"> private static final Logger log = LoggerFactory.getLogger(OncePerRequestFilter.class);</a>
<span class="sourceLineNo">053</span><a id="line.53"></a>
<span class="sourceLineNo">054</span><a id="line.54"> /**</a>
<span class="sourceLineNo">055</span><a id="line.55"> * Suffix that gets appended to the filter name for the "already filtered" request attribute.</a>
<span class="sourceLineNo">056</span><a id="line.56"> *</a>
<span class="sourceLineNo">057</span><a id="line.57"> * @see #getAlreadyFilteredAttributeName</a>
<span class="sourceLineNo">058</span><a id="line.58"> */</a>
<span class="sourceLineNo">059</span><a id="line.59"> public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED";</a>
<span class="sourceLineNo">060</span><a id="line.60"></a>
<span class="sourceLineNo">061</span><a id="line.61"> /**</a>
<span class="sourceLineNo">062</span><a id="line.62"> * Determines generally if this filter should execute or let requests fall through to the next chain element.</a>
<span class="sourceLineNo">063</span><a id="line.63"> *</a>
<span class="sourceLineNo">064</span><a id="line.64"> * @see #isEnabled()</a>
<span class="sourceLineNo">065</span><a id="line.65"> */</a>
<span class="sourceLineNo">066</span><a id="line.66"> private boolean enabled = true; //most filters wish to execute when configured, so default to true</a>
<span class="sourceLineNo">067</span><a id="line.67"></a>
<span class="sourceLineNo">068</span><a id="line.68"> /**</a>
<span class="sourceLineNo">069</span><a id="line.69"> * Determines if the filter's once per request functionality is enabled, defaults to false. It is recommended</a>
<span class="sourceLineNo">070</span><a id="line.70"> * to leave this disabled if you are using a {@link javax.servlet.RequestDispatcher RequestDispatcher} to forward</a>
<span class="sourceLineNo">071</span><a id="line.71"> * or include request (JSP tags, programmatically, or via a framework).</a>
<span class="sourceLineNo">072</span><a id="line.72"> */</a>
<span class="sourceLineNo">073</span><a id="line.73"> private boolean filterOncePerRequest = false;</a>
<span class="sourceLineNo">074</span><a id="line.74"></a>
<span class="sourceLineNo">075</span><a id="line.75"> /**</a>
<span class="sourceLineNo">076</span><a id="line.76"> * Returns {@code true} if this filter should &lt;em&gt;generally&lt;/em&gt;&lt;b&gt;*&lt;/b&gt; execute for any request,</a>
<span class="sourceLineNo">077</span><a id="line.77"> * {@code false} if it should let the request/response pass through immediately to the next</a>
<span class="sourceLineNo">078</span><a id="line.78"> * element in the {@link FilterChain}. The default value is {@code true}, as most filters would inherently need</a>
<span class="sourceLineNo">079</span><a id="line.79"> * to execute when configured.</a>
<span class="sourceLineNo">080</span><a id="line.80"> * &lt;p/&gt;</a>
<span class="sourceLineNo">081</span><a id="line.81"> * &lt;b&gt;*&lt;/b&gt; This configuration property is for general configuration for any request that comes through</a>
<span class="sourceLineNo">082</span><a id="line.82"> * the filter. The</a>
<span class="sourceLineNo">083</span><a id="line.83"> * {@link #isEnabled(javax.servlet.ServletRequest, javax.servlet.ServletResponse) isEnabled(request,response)}</a>
<span class="sourceLineNo">084</span><a id="line.84"> * method actually determines whether or not if the filter is enabled based on the current request.</a>
<span class="sourceLineNo">085</span><a id="line.85"> *</a>
<span class="sourceLineNo">086</span><a id="line.86"> * @return {@code true} if this filter should &lt;em&gt;generally&lt;/em&gt; execute, {@code false} if it should let the</a>
<span class="sourceLineNo">087</span><a id="line.87"> * request/response pass through immediately to the next element in the {@link FilterChain}.</a>
<span class="sourceLineNo">088</span><a id="line.88"> * @since 1.2</a>
<span class="sourceLineNo">089</span><a id="line.89"> */</a>
<span class="sourceLineNo">090</span><a id="line.90"> public boolean isEnabled() {</a>
<span class="sourceLineNo">091</span><a id="line.91"> return enabled;</a>
<span class="sourceLineNo">092</span><a id="line.92"> }</a>
<span class="sourceLineNo">093</span><a id="line.93"></a>
<span class="sourceLineNo">094</span><a id="line.94"> /**</a>
<span class="sourceLineNo">095</span><a id="line.95"> * Sets whether or not this filter &lt;em&gt;generally&lt;/em&gt; executes for any request. See the</a>
<span class="sourceLineNo">096</span><a id="line.96"> * {@link #isEnabled() isEnabled()} JavaDoc as to what &lt;em&gt;general&lt;/em&gt; execution means.</a>
<span class="sourceLineNo">097</span><a id="line.97"> *</a>
<span class="sourceLineNo">098</span><a id="line.98"> * @param enabled whether or not this filter &lt;em&gt;generally&lt;/em&gt; executes.</a>
<span class="sourceLineNo">099</span><a id="line.99"> * @since 1.2</a>
<span class="sourceLineNo">100</span><a id="line.100"> */</a>
<span class="sourceLineNo">101</span><a id="line.101"> public void setEnabled(boolean enabled) {</a>
<span class="sourceLineNo">102</span><a id="line.102"> this.enabled = enabled;</a>
<span class="sourceLineNo">103</span><a id="line.103"> }</a>
<span class="sourceLineNo">104</span><a id="line.104"></a>
<span class="sourceLineNo">105</span><a id="line.105"> /**</a>
<span class="sourceLineNo">106</span><a id="line.106"> * Returns {@code true} if this filter should only execute once per request. If set to {@code false} this filter</a>
<span class="sourceLineNo">107</span><a id="line.107"> * will execute each time it is invoked.</a>
<span class="sourceLineNo">108</span><a id="line.108"> * @return {@code true} if this filter should only execute once per request.</a>
<span class="sourceLineNo">109</span><a id="line.109"> * @since 1.10</a>
<span class="sourceLineNo">110</span><a id="line.110"> */</a>
<span class="sourceLineNo">111</span><a id="line.111"> public boolean isFilterOncePerRequest() {</a>
<span class="sourceLineNo">112</span><a id="line.112"> return filterOncePerRequest;</a>
<span class="sourceLineNo">113</span><a id="line.113"> }</a>
<span class="sourceLineNo">114</span><a id="line.114"></a>
<span class="sourceLineNo">115</span><a id="line.115"> /**</a>
<span class="sourceLineNo">116</span><a id="line.116"> * Sets whether this filter executes once per request or for every invocation of the filter. It is recommended</a>
<span class="sourceLineNo">117</span><a id="line.117"> * to leave this disabled if you are using a {@link javax.servlet.RequestDispatcher RequestDispatcher} to forward</a>
<span class="sourceLineNo">118</span><a id="line.118"> * or include request (JSP tags, programmatically, or via a framework). </a>
<span class="sourceLineNo">119</span><a id="line.119"> *</a>
<span class="sourceLineNo">120</span><a id="line.120"> * @param filterOncePerRequest Whether this filter executes once per request.</a>
<span class="sourceLineNo">121</span><a id="line.121"> * @since 1.10</a>
<span class="sourceLineNo">122</span><a id="line.122"> */</a>
<span class="sourceLineNo">123</span><a id="line.123"> public void setFilterOncePerRequest(boolean filterOncePerRequest) {</a>
<span class="sourceLineNo">124</span><a id="line.124"> this.filterOncePerRequest = filterOncePerRequest;</a>
<span class="sourceLineNo">125</span><a id="line.125"> }</a>
<span class="sourceLineNo">126</span><a id="line.126"></a>
<span class="sourceLineNo">127</span><a id="line.127"> /**</a>
<span class="sourceLineNo">128</span><a id="line.128"> * This {@code doFilter} implementation stores a request attribute for</a>
<span class="sourceLineNo">129</span><a id="line.129"> * "already filtered", proceeding without filtering again if the</a>
<span class="sourceLineNo">130</span><a id="line.130"> * attribute is already there.</a>
<span class="sourceLineNo">131</span><a id="line.131"> *</a>
<span class="sourceLineNo">132</span><a id="line.132"> * @see #getAlreadyFilteredAttributeName</a>
<span class="sourceLineNo">133</span><a id="line.133"> * @see #shouldNotFilter</a>
<span class="sourceLineNo">134</span><a id="line.134"> * @see #doFilterInternal</a>
<span class="sourceLineNo">135</span><a id="line.135"> */</a>
<span class="sourceLineNo">136</span><a id="line.136"> public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)</a>
<span class="sourceLineNo">137</span><a id="line.137"> throws ServletException, IOException {</a>
<span class="sourceLineNo">138</span><a id="line.138"> String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();</a>
<span class="sourceLineNo">139</span><a id="line.139"> if ( request.getAttribute(alreadyFilteredAttributeName) != null &amp;&amp; filterOncePerRequest) {</a>
<span class="sourceLineNo">140</span><a id="line.140"> log.trace("Filter '{}' already executed. Proceeding without invoking this filter.", getName());</a>
<span class="sourceLineNo">141</span><a id="line.141"> filterChain.doFilter(request, response);</a>
<span class="sourceLineNo">142</span><a id="line.142"> } else //noinspection deprecation</a>
<span class="sourceLineNo">143</span><a id="line.143"> if (/* added in 1.2: */ !isEnabled(request, response) ||</a>
<span class="sourceLineNo">144</span><a id="line.144"> /* retain backwards compatibility: */ shouldNotFilter(request) ) {</a>
<span class="sourceLineNo">145</span><a id="line.145"> log.debug("Filter '{}' is not enabled for the current request. Proceeding without invoking this filter.",</a>
<span class="sourceLineNo">146</span><a id="line.146"> getName());</a>
<span class="sourceLineNo">147</span><a id="line.147"> filterChain.doFilter(request, response);</a>
<span class="sourceLineNo">148</span><a id="line.148"> } else {</a>
<span class="sourceLineNo">149</span><a id="line.149"> // Do invoke this filter...</a>
<span class="sourceLineNo">150</span><a id="line.150"> log.trace("Filter '{}' not yet executed. Executing now.", getName());</a>
<span class="sourceLineNo">151</span><a id="line.151"> request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);</a>
<span class="sourceLineNo">152</span><a id="line.152"></a>
<span class="sourceLineNo">153</span><a id="line.153"> try {</a>
<span class="sourceLineNo">154</span><a id="line.154"> doFilterInternal(request, response, filterChain);</a>
<span class="sourceLineNo">155</span><a id="line.155"> } finally {</a>
<span class="sourceLineNo">156</span><a id="line.156"> // Once the request has finished, we're done and we don't</a>
<span class="sourceLineNo">157</span><a id="line.157"> // need to mark as 'already filtered' any more.</a>
<span class="sourceLineNo">158</span><a id="line.158"> request.removeAttribute(alreadyFilteredAttributeName);</a>
<span class="sourceLineNo">159</span><a id="line.159"> }</a>
<span class="sourceLineNo">160</span><a id="line.160"> }</a>
<span class="sourceLineNo">161</span><a id="line.161"> }</a>
<span class="sourceLineNo">162</span><a id="line.162"></a>
<span class="sourceLineNo">163</span><a id="line.163"> /**</a>
<span class="sourceLineNo">164</span><a id="line.164"> * Returns {@code true} if this filter should filter the specified request, {@code false} if it should let the</a>
<span class="sourceLineNo">165</span><a id="line.165"> * request/response pass through immediately to the next element in the {@code FilterChain}.</a>
<span class="sourceLineNo">166</span><a id="line.166"> * &lt;p/&gt;</a>
<span class="sourceLineNo">167</span><a id="line.167"> * This default implementation merely returns the value of {@link #isEnabled() isEnabled()}, which is</a>
<span class="sourceLineNo">168</span><a id="line.168"> * {@code true} by default (to ensure the filter always executes by default), but it can be overridden by</a>
<span class="sourceLineNo">169</span><a id="line.169"> * subclasses for request-specific behavior if necessary. For example, a filter could be enabled or disabled</a>
<span class="sourceLineNo">170</span><a id="line.170"> * based on the request path being accessed.</a>
<span class="sourceLineNo">171</span><a id="line.171"> * &lt;p/&gt;</a>
<span class="sourceLineNo">172</span><a id="line.172"> * &lt;b&gt;Helpful Hint:&lt;/b&gt; if your subclass extends {@link org.apache.shiro.web.filter.PathMatchingFilter PathMatchingFilter},</a>
<span class="sourceLineNo">173</span><a id="line.173"> * you may wish to instead override the</a>
<span class="sourceLineNo">174</span><a id="line.174"> * {@link org.apache.shiro.web.filter.PathMatchingFilter#isEnabled(javax.servlet.ServletRequest, javax.servlet.ServletResponse, String, Object)</a>
<span class="sourceLineNo">175</span><a id="line.175"> * PathMatchingFilter.isEnabled(request,response,path,pathSpecificConfig)}</a>
<span class="sourceLineNo">176</span><a id="line.176"> * method if you want to make your enable/disable decision based on any path-specific configuration.</a>
<span class="sourceLineNo">177</span><a id="line.177"> *</a>
<span class="sourceLineNo">178</span><a id="line.178"> * @param request the incoming servlet request</a>
<span class="sourceLineNo">179</span><a id="line.179"> * @param response the outbound servlet response</a>
<span class="sourceLineNo">180</span><a id="line.180"> * @return {@code true} if this filter should filter the specified request, {@code false} if it should let the</a>
<span class="sourceLineNo">181</span><a id="line.181"> * request/response pass through immediately to the next element in the {@code FilterChain}.</a>
<span class="sourceLineNo">182</span><a id="line.182"> * @throws IOException in the case of any IO error</a>
<span class="sourceLineNo">183</span><a id="line.183"> * @throws ServletException in the case of any error</a>
<span class="sourceLineNo">184</span><a id="line.184"> * @see org.apache.shiro.web.filter.PathMatchingFilter#isEnabled(javax.servlet.ServletRequest, javax.servlet.ServletResponse, String, Object)</a>
<span class="sourceLineNo">185</span><a id="line.185"> * @since 1.2</a>
<span class="sourceLineNo">186</span><a id="line.186"> */</a>
<span class="sourceLineNo">187</span><a id="line.187"> @SuppressWarnings({"UnusedParameters"})</a>
<span class="sourceLineNo">188</span><a id="line.188"> protected boolean isEnabled(ServletRequest request, ServletResponse response) throws ServletException, IOException {</a>
<span class="sourceLineNo">189</span><a id="line.189"> return isEnabled();</a>
<span class="sourceLineNo">190</span><a id="line.190"> }</a>
<span class="sourceLineNo">191</span><a id="line.191"></a>
<span class="sourceLineNo">192</span><a id="line.192"> /**</a>
<span class="sourceLineNo">193</span><a id="line.193"> * Return name of the request attribute that identifies that a request has already been filtered.</a>
<span class="sourceLineNo">194</span><a id="line.194"> * &lt;p/&gt;</a>
<span class="sourceLineNo">195</span><a id="line.195"> * The default implementation takes the configured {@link #getName() name} and appends &amp;quot;{@code .FILTERED}&amp;quot;.</a>
<span class="sourceLineNo">196</span><a id="line.196"> * If the filter is not fully initialized, it falls back to the implementation's class name.</a>
<span class="sourceLineNo">197</span><a id="line.197"> *</a>
<span class="sourceLineNo">198</span><a id="line.198"> * @return the name of the request attribute that identifies that a request has already been filtered.</a>
<span class="sourceLineNo">199</span><a id="line.199"> * @see #getName</a>
<span class="sourceLineNo">200</span><a id="line.200"> * @see #ALREADY_FILTERED_SUFFIX</a>
<span class="sourceLineNo">201</span><a id="line.201"> */</a>
<span class="sourceLineNo">202</span><a id="line.202"> protected String getAlreadyFilteredAttributeName() {</a>
<span class="sourceLineNo">203</span><a id="line.203"> String name = getName();</a>
<span class="sourceLineNo">204</span><a id="line.204"> if (name == null) {</a>
<span class="sourceLineNo">205</span><a id="line.205"> name = getClass().getName();</a>
<span class="sourceLineNo">206</span><a id="line.206"> }</a>
<span class="sourceLineNo">207</span><a id="line.207"> return name + ALREADY_FILTERED_SUFFIX;</a>
<span class="sourceLineNo">208</span><a id="line.208"> }</a>
<span class="sourceLineNo">209</span><a id="line.209"></a>
<span class="sourceLineNo">210</span><a id="line.210"> /**</a>
<span class="sourceLineNo">211</span><a id="line.211"> * Can be overridden in subclasses for custom filtering control,</a>
<span class="sourceLineNo">212</span><a id="line.212"> * returning &lt;code&gt;true&lt;/code&gt; to avoid filtering of the given request.</a>
<span class="sourceLineNo">213</span><a id="line.213"> * &lt;p&gt;The default implementation always returns &lt;code&gt;false&lt;/code&gt;.</a>
<span class="sourceLineNo">214</span><a id="line.214"> *</a>
<span class="sourceLineNo">215</span><a id="line.215"> * @param request current HTTP request</a>
<span class="sourceLineNo">216</span><a id="line.216"> * @return whether the given request should &lt;i&gt;not&lt;/i&gt; be filtered</a>
<span class="sourceLineNo">217</span><a id="line.217"> * @throws ServletException in case of errors</a>
<span class="sourceLineNo">218</span><a id="line.218"> * @deprecated in favor of overriding {@link #isEnabled(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}</a>
<span class="sourceLineNo">219</span><a id="line.219"> * for custom behavior. This method will be removed in Shiro 2.0.</a>
<span class="sourceLineNo">220</span><a id="line.220"> */</a>
<span class="sourceLineNo">221</span><a id="line.221"> @Deprecated</a>
<span class="sourceLineNo">222</span><a id="line.222"> @SuppressWarnings({"UnusedDeclaration"})</a>
<span class="sourceLineNo">223</span><a id="line.223"> protected boolean shouldNotFilter(ServletRequest request) throws ServletException {</a>
<span class="sourceLineNo">224</span><a id="line.224"> return false;</a>
<span class="sourceLineNo">225</span><a id="line.225"> }</a>
<span class="sourceLineNo">226</span><a id="line.226"></a>
<span class="sourceLineNo">227</span><a id="line.227"></a>
<span class="sourceLineNo">228</span><a id="line.228"> /**</a>
<span class="sourceLineNo">229</span><a id="line.229"> * Same contract as for</a>
<span class="sourceLineNo">230</span><a id="line.230"> * {@link #doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)},</a>
<span class="sourceLineNo">231</span><a id="line.231"> * but guaranteed to be invoked only once per request.</a>
<span class="sourceLineNo">232</span><a id="line.232"> *</a>
<span class="sourceLineNo">233</span><a id="line.233"> * @param request incoming {@code ServletRequest}</a>
<span class="sourceLineNo">234</span><a id="line.234"> * @param response outgoing {@code ServletResponse}</a>
<span class="sourceLineNo">235</span><a id="line.235"> * @param chain the {@code FilterChain} to execute</a>
<span class="sourceLineNo">236</span><a id="line.236"> * @throws ServletException if there is a problem processing the request</a>
<span class="sourceLineNo">237</span><a id="line.237"> * @throws IOException if there is an I/O problem processing the request</a>
<span class="sourceLineNo">238</span><a id="line.238"> */</a>
<span class="sourceLineNo">239</span><a id="line.239"> protected abstract void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)</a>
<span class="sourceLineNo">240</span><a id="line.240"> throws ServletException, IOException;</a>
<span class="sourceLineNo">241</span><a id="line.241">}</a>
</pre>
</div>
</main>
</body>
</html>