| <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>AbstractShiroFilter.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Shiro :: Web</a> > <a href="index.source.html" class="el_package">org.apache.shiro.web.servlet</a> > <span class="el_source">AbstractShiroFilter.java</span></div><h1>AbstractShiroFilter.java</h1><pre class="source lang-java linenums">/* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.shiro.web.servlet; |
| |
| import org.apache.shiro.SecurityUtils; |
| import org.apache.shiro.session.Session; |
| import org.apache.shiro.subject.ExecutionException; |
| import org.apache.shiro.subject.Subject; |
| import org.apache.shiro.web.filter.mgt.FilterChainResolver; |
| import org.apache.shiro.web.mgt.DefaultWebSecurityManager; |
| import org.apache.shiro.web.mgt.WebSecurityManager; |
| import org.apache.shiro.web.subject.WebSubject; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import javax.servlet.FilterChain; |
| import javax.servlet.ServletException; |
| import javax.servlet.ServletRequest; |
| import javax.servlet.ServletResponse; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import java.io.IOException; |
| import java.util.concurrent.Callable; |
| |
| /** |
| * Abstract base class that provides all standard Shiro request filtering behavior and expects |
| * subclasses to implement configuration-specific logic (INI, XML, .properties, etc). |
| * <p/> |
| * Subclasses should perform configuration and construction logic in an overridden |
| * {@link #init()} method implementation. That implementation should make available any constructed |
| * {@code SecurityManager} and {@code FilterChainResolver} by calling |
| * {@link #setSecurityManager(org.apache.shiro.web.mgt.WebSecurityManager)} and |
| * {@link #setFilterChainResolver(org.apache.shiro.web.filter.mgt.FilterChainResolver)} methods respectively. |
| * <h3>Static SecurityManager</h3> |
| * By default the {@code SecurityManager} instance enabled by this filter <em>will not</em> be enabled in static |
| * memory via the {@code SecurityUtils.}{@link SecurityUtils#setSecurityManager(org.apache.shiro.mgt.SecurityManager) setSecurityManager} |
| * method. Instead, it is expected that Subject instances will always be constructed on a request-processing thread |
| * via instances of this Filter class. |
| * <p/> |
| * However, if you need to construct {@code Subject} instances on separate (non request-processing) threads, it might |
| * be easiest to enable the SecurityManager to be available in static memory via the |
| * {@link SecurityUtils#getSecurityManager()} method. You can do this by additionally specifying an {@code init-param}: |
| * <pre> |
| * &lt;filter&gt; |
| * ... other config here ... |
| * &lt;init-param&gt; |
| * &lt;param-name&gt;staticSecurityManagerEnabled&lt;/param-name&gt; |
| * &lt;param-value&gt;true&lt;/param-value&gt; |
| * &lt;/init-param&gt; |
| * &lt;/filter&gt; |
| * </pre> |
| * See the Shiro <a href="http://shiro.apache.org/subject.html">Subject documentation</a> for more information as to |
| * if you would do this, particularly the sections on the {@code Subject.Builder} and Thread Association. |
| * |
| * @since 1.0 |
| * @see <a href="http://shiro.apache.org/subject.html">Subject documentation</a> |
| */ |
| public abstract class AbstractShiroFilter extends OncePerRequestFilter { |
| |
| <span class="fc" id="L76"> private static final Logger log = LoggerFactory.getLogger(AbstractShiroFilter.class);</span> |
| |
| private static final String STATIC_INIT_PARAM_NAME = "staticSecurityManagerEnabled"; |
| |
| // Reference to the security manager used by this filter |
| private WebSecurityManager securityManager; |
| |
| // Used to determine which chain should handle an incoming request/response |
| private FilterChainResolver filterChainResolver; |
| |
| /** |
| * Whether or not to bind the constructed SecurityManager instance to static memory (via |
| * SecurityUtils.setSecurityManager). This was added to support https://issues.apache.org/jira/browse/SHIRO-287 |
| * @since 1.2 |
| */ |
| private boolean staticSecurityManagerEnabled; |
| |
| <span class="fc" id="L93"> protected AbstractShiroFilter() {</span> |
| <span class="fc" id="L94"> this.staticSecurityManagerEnabled = false;</span> |
| <span class="fc" id="L95"> }</span> |
| |
| public WebSecurityManager getSecurityManager() { |
| <span class="fc" id="L98"> return securityManager;</span> |
| } |
| |
| public void setSecurityManager(WebSecurityManager sm) { |
| <span class="fc" id="L102"> this.securityManager = sm;</span> |
| <span class="fc" id="L103"> }</span> |
| |
| public FilterChainResolver getFilterChainResolver() { |
| <span class="fc" id="L106"> return filterChainResolver;</span> |
| } |
| |
| public void setFilterChainResolver(FilterChainResolver filterChainResolver) { |
| <span class="fc" id="L110"> this.filterChainResolver = filterChainResolver;</span> |
| <span class="fc" id="L111"> }</span> |
| |
| /** |
| * Returns {@code true} if the constructed {@link #getSecurityManager() securityManager} reference should be bound |
| * to static memory (via |
| * {@code SecurityUtils.}{@link SecurityUtils#setSecurityManager(org.apache.shiro.mgt.SecurityManager) setSecurityManager}), |
| * {@code false} otherwise. |
| * <p/> |
| * The default value is {@code false}. |
| * <p/> |
| * |
| * |
| * @return {@code true} if the constructed {@link #getSecurityManager() securityManager} reference should be bound |
| * to static memory (via {@code SecurityUtils.}{@link SecurityUtils#setSecurityManager(org.apache.shiro.mgt.SecurityManager) setSecurityManager}), |
| * {@code false} otherwise. |
| * @since 1.2 |
| * @see <a href="https://issues.apache.org/jira/browse/SHIRO-287">SHIRO-287</a> |
| */ |
| public boolean isStaticSecurityManagerEnabled() { |
| <span class="fc" id="L130"> return staticSecurityManagerEnabled;</span> |
| } |
| |
| /** |
| * Sets if the constructed {@link #getSecurityManager() securityManager} reference should be bound |
| * to static memory (via {@code SecurityUtils.}{@link SecurityUtils#setSecurityManager(org.apache.shiro.mgt.SecurityManager) setSecurityManager}). |
| * <p/> |
| * The default value is {@code false}. |
| * |
| * @param staticSecurityManagerEnabled if the constructed {@link #getSecurityManager() securityManager} reference |
| * should be bound to static memory (via |
| * {@code SecurityUtils.}{@link SecurityUtils#setSecurityManager(org.apache.shiro.mgt.SecurityManager) setSecurityManager}). |
| * @since 1.2 |
| * @see <a href="https://issues.apache.org/jira/browse/SHIRO-287">SHIRO-287</a> |
| */ |
| public void setStaticSecurityManagerEnabled(boolean staticSecurityManagerEnabled) { |
| <span class="fc" id="L146"> this.staticSecurityManagerEnabled = staticSecurityManagerEnabled;</span> |
| <span class="fc" id="L147"> }</span> |
| |
| protected final void onFilterConfigSet() throws Exception { |
| //added in 1.2 for SHIRO-287: |
| <span class="fc" id="L151"> applyStaticSecurityManagerEnabledConfig();</span> |
| <span class="fc" id="L152"> init();</span> |
| <span class="fc" id="L153"> ensureSecurityManager();</span> |
| //added in 1.2 for SHIRO-287: |
| <span class="fc bfc" id="L155" title="All 2 branches covered."> if (isStaticSecurityManagerEnabled()) {</span> |
| <span class="fc" id="L156"> SecurityUtils.setSecurityManager(getSecurityManager());</span> |
| } |
| <span class="fc" id="L158"> }</span> |
| |
| /** |
| * Checks if the init-param that configures the filter to use static memory has been configured, and if so, |
| * sets the {@link #setStaticSecurityManagerEnabled(boolean)} attribute with the configured value. |
| * |
| * @since 1.2 |
| * @see <a href="https://issues.apache.org/jira/browse/SHIRO-287">SHIRO-287</a> |
| */ |
| private void applyStaticSecurityManagerEnabledConfig() { |
| <span class="fc" id="L168"> String value = getInitParam(STATIC_INIT_PARAM_NAME);</span> |
| <span class="fc bfc" id="L169" title="All 2 branches covered."> if (value != null) {</span> |
| <span class="fc" id="L170"> Boolean b = Boolean.valueOf(value);</span> |
| <span class="pc bpc" id="L171" title="1 of 2 branches missed."> if (b != null) {</span> |
| <span class="fc" id="L172"> setStaticSecurityManagerEnabled(b);</span> |
| } |
| } |
| <span class="fc" id="L175"> }</span> |
| |
| public void init() throws Exception { |
| <span class="fc" id="L178"> }</span> |
| |
| /** |
| * A fallback mechanism called in {@link #onFilterConfigSet()} to ensure that the |
| * {@link #getSecurityManager() securityManager} property has been set by configuration, and if not, |
| * creates one automatically. |
| */ |
| private void ensureSecurityManager() { |
| <span class="fc" id="L186"> WebSecurityManager securityManager = getSecurityManager();</span> |
| <span class="pc bpc" id="L187" title="1 of 2 branches missed."> if (securityManager == null) {</span> |
| <span class="nc" id="L188"> log.info("No SecurityManager configured. Creating default.");</span> |
| <span class="nc" id="L189"> securityManager = createDefaultSecurityManager();</span> |
| <span class="nc" id="L190"> setSecurityManager(securityManager);</span> |
| } |
| <span class="fc" id="L192"> }</span> |
| |
| protected WebSecurityManager createDefaultSecurityManager() { |
| <span class="nc" id="L195"> return new DefaultWebSecurityManager();</span> |
| } |
| |
| protected boolean isHttpSessions() { |
| <span class="nc" id="L199"> return getSecurityManager().isHttpSessionMode();</span> |
| } |
| |
| /** |
| * Wraps the original HttpServletRequest in a {@link ShiroHttpServletRequest}, which is required for supporting |
| * Servlet Specification behavior backed by a {@link org.apache.shiro.subject.Subject Subject} instance. |
| * |
| * @param orig the original Servlet Container-provided incoming {@code HttpServletRequest} instance. |
| * @return {@link ShiroHttpServletRequest ShiroHttpServletRequest} instance wrapping the original. |
| * @since 1.0 |
| */ |
| protected ServletRequest wrapServletRequest(HttpServletRequest orig) { |
| <span class="nc" id="L211"> return new ShiroHttpServletRequest(orig, getServletContext(), isHttpSessions());</span> |
| } |
| |
| /** |
| * Prepares the {@code ServletRequest} instance that will be passed to the {@code FilterChain} for request |
| * processing. |
| * <p/> |
| * If the {@code ServletRequest} is an instance of {@link HttpServletRequest}, the value returned from this method |
| * is obtained by calling {@link #wrapServletRequest(javax.servlet.http.HttpServletRequest)} to allow Shiro-specific |
| * HTTP behavior, otherwise the original {@code ServletRequest} argument is returned. |
| * |
| * @param request the incoming ServletRequest |
| * @param response the outgoing ServletResponse |
| * @param chain the Servlet Container provided {@code FilterChain} that will receive the returned request. |
| * @return the {@code ServletRequest} instance that will be passed to the {@code FilterChain} for request processing. |
| * @since 1.0 |
| */ |
| @SuppressWarnings({"UnusedDeclaration"}) |
| protected ServletRequest prepareServletRequest(ServletRequest request, ServletResponse response, FilterChain chain) { |
| <span class="nc" id="L230"> ServletRequest toUse = request;</span> |
| <span class="nc bnc" id="L231" title="All 2 branches missed."> if (request instanceof HttpServletRequest) {</span> |
| <span class="nc" id="L232"> HttpServletRequest http = (HttpServletRequest) request;</span> |
| <span class="nc" id="L233"> toUse = wrapServletRequest(http);</span> |
| } |
| <span class="nc" id="L235"> return toUse;</span> |
| } |
| |
| /** |
| * Returns a new {@link ShiroHttpServletResponse} instance, wrapping the {@code orig} argument, in order to provide |
| * correct URL rewriting behavior required by the Servlet Specification when using Shiro-based sessions (and not |
| * Servlet Container HTTP-based sessions). |
| * |
| * @param orig the original {@code HttpServletResponse} instance provided by the Servlet Container. |
| * @param request the {@code ShiroHttpServletRequest} instance wrapping the original request. |
| * @return the wrapped ServletResponse instance to use during {@link FilterChain} execution. |
| * @since 1.0 |
| */ |
| protected ServletResponse wrapServletResponse(HttpServletResponse orig, ShiroHttpServletRequest request) { |
| <span class="nc" id="L249"> return new ShiroHttpServletResponse(orig, getServletContext(), request);</span> |
| } |
| |
| /** |
| * Prepares the {@code ServletResponse} instance that will be passed to the {@code FilterChain} for request |
| * processing. |
| * <p/> |
| * This implementation delegates to {@link #wrapServletRequest(javax.servlet.http.HttpServletRequest)} |
| * only if Shiro-based sessions are enabled (that is, !{@link #isHttpSessions()}) and the request instance is a |
| * {@link ShiroHttpServletRequest}. This ensures that any URL rewriting that occurs is handled correctly using the |
| * Shiro-managed Session's sessionId and not a servlet container session ID. |
| * <p/> |
| * If HTTP-based sessions are enabled (the default), then this method does nothing and just returns the |
| * {@code ServletResponse} argument as-is, relying on the default Servlet Container URL rewriting logic. |
| * |
| * @param request the incoming ServletRequest |
| * @param response the outgoing ServletResponse |
| * @param chain the Servlet Container provided {@code FilterChain} that will receive the returned request. |
| * @return the {@code ServletResponse} instance that will be passed to the {@code FilterChain} during request processing. |
| * @since 1.0 |
| */ |
| @SuppressWarnings({"UnusedDeclaration"}) |
| protected ServletResponse prepareServletResponse(ServletRequest request, ServletResponse response, FilterChain chain) { |
| <span class="nc" id="L272"> ServletResponse toUse = response;</span> |
| <span class="nc bnc" id="L273" title="All 6 branches missed."> if (!isHttpSessions() && (request instanceof ShiroHttpServletRequest) &&</span> |
| (response instanceof HttpServletResponse)) { |
| //the ShiroHttpServletResponse exists to support URL rewriting for session ids. This is only needed if |
| //using Shiro sessions (i.e. not simple HttpSession based sessions): |
| <span class="nc" id="L277"> toUse = wrapServletResponse((HttpServletResponse) response, (ShiroHttpServletRequest) request);</span> |
| } |
| <span class="nc" id="L279"> return toUse;</span> |
| } |
| |
| /** |
| * Creates a {@link WebSubject} instance to associate with the incoming request/response pair which will be used |
| * throughout the request/response execution. |
| * |
| * @param request the incoming {@code ServletRequest} |
| * @param response the outgoing {@code ServletResponse} |
| * @return the {@code WebSubject} instance to associate with the request/response execution |
| * @since 1.0 |
| */ |
| protected WebSubject createSubject(ServletRequest request, ServletResponse response) { |
| <span class="nc" id="L292"> return new WebSubject.Builder(getSecurityManager(), request, response).buildWebSubject();</span> |
| } |
| |
| /** |
| * Updates any 'native' Session's last access time that might exist to the timestamp when this method is called. |
| * If native sessions are not enabled (that is, standard Servlet container sessions are being used) or there is no |
| * session ({@code subject.getSession(false) == null}), this method does nothing. |
| * <p/>This method implementation merely calls |
| * <code>Session.{@link org.apache.shiro.session.Session#touch() touch}()</code> on the session. |
| * |
| * @param request incoming request - ignored, but available to subclasses that might wish to override this method |
| * @param response outgoing response - ignored, but available to subclasses that might wish to override this method |
| * @since 1.0 |
| */ |
| @SuppressWarnings({"UnusedDeclaration"}) |
| protected void updateSessionLastAccessTime(ServletRequest request, ServletResponse response) { |
| <span class="nc bnc" id="L308" title="All 2 branches missed."> if (!isHttpSessions()) { //'native' sessions</span> |
| <span class="nc" id="L309"> Subject subject = SecurityUtils.getSubject();</span> |
| //Subject should never _ever_ be null, but just in case: |
| <span class="nc bnc" id="L311" title="All 2 branches missed."> if (subject != null) {</span> |
| <span class="nc" id="L312"> Session session = subject.getSession(false);</span> |
| <span class="nc bnc" id="L313" title="All 2 branches missed."> if (session != null) {</span> |
| try { |
| <span class="nc" id="L315"> session.touch();</span> |
| <span class="nc" id="L316"> } catch (Throwable t) {</span> |
| <span class="nc" id="L317"> log.error("session.touch() method invocation has failed. Unable to update" +</span> |
| "the corresponding session's last access time based on the incoming request.", t); |
| <span class="nc" id="L319"> }</span> |
| } |
| } |
| } |
| <span class="nc" id="L323"> }</span> |
| |
| /** |
| * {@code doFilterInternal} implementation that sets-up, executes, and cleans-up a Shiro-filtered request. It |
| * performs the following ordered operations: |
| * <ol> |
| * <li>{@link #prepareServletRequest(ServletRequest, ServletResponse, FilterChain) Prepares} |
| * the incoming {@code ServletRequest} for use during Shiro's processing</li> |
| * <li>{@link #prepareServletResponse(ServletRequest, ServletResponse, FilterChain) Prepares} |
| * the outgoing {@code ServletResponse} for use during Shiro's processing</li> |
| * <li> {@link #createSubject(javax.servlet.ServletRequest, javax.servlet.ServletResponse) Creates} a |
| * {@link Subject} instance based on the specified request/response pair.</li> |
| * <li>Finally {@link Subject#execute(Runnable) executes} the |
| * {@link #updateSessionLastAccessTime(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} and |
| * {@link #executeChain(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)} |
| * methods</li> |
| * </ol> |
| * <p/> |
| * The {@code Subject.}{@link Subject#execute(Runnable) execute(Runnable)} call in step #4 is used as an |
| * implementation technique to guarantee proper thread binding and restoration is completed successfully. |
| * |
| * @param servletRequest the incoming {@code ServletRequest} |
| * @param servletResponse the outgoing {@code ServletResponse} |
| * @param chain the container-provided {@code FilterChain} to execute |
| * @throws IOException if an IO error occurs |
| * @throws javax.servlet.ServletException if an Throwable other than an IOException |
| */ |
| protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, final FilterChain chain) |
| throws ServletException, IOException { |
| |
| <span class="nc" id="L353"> Throwable t = null;</span> |
| |
| try { |
| <span class="nc" id="L356"> final ServletRequest request = prepareServletRequest(servletRequest, servletResponse, chain);</span> |
| <span class="nc" id="L357"> final ServletResponse response = prepareServletResponse(request, servletResponse, chain);</span> |
| |
| <span class="nc" id="L359"> final Subject subject = createSubject(request, response);</span> |
| |
| //noinspection unchecked |
| <span class="nc" id="L362"> subject.execute(new Callable() {</span> |
| public Object call() throws Exception { |
| <span class="nc" id="L364"> updateSessionLastAccessTime(request, response);</span> |
| <span class="nc" id="L365"> executeChain(request, response, chain);</span> |
| <span class="nc" id="L366"> return null;</span> |
| } |
| }); |
| <span class="nc" id="L369"> } catch (ExecutionException ex) {</span> |
| <span class="nc" id="L370"> t = ex.getCause();</span> |
| <span class="nc" id="L371"> } catch (Throwable throwable) {</span> |
| <span class="nc" id="L372"> t = throwable;</span> |
| <span class="nc" id="L373"> }</span> |
| |
| <span class="nc bnc" id="L375" title="All 2 branches missed."> if (t != null) {</span> |
| <span class="nc bnc" id="L376" title="All 2 branches missed."> if (t instanceof ServletException) {</span> |
| <span class="nc" id="L377"> throw (ServletException) t;</span> |
| } |
| <span class="nc bnc" id="L379" title="All 2 branches missed."> if (t instanceof IOException) {</span> |
| <span class="nc" id="L380"> throw (IOException) t;</span> |
| } |
| //otherwise it's not one of the two exceptions expected by the filter method signature - wrap it in one: |
| <span class="nc" id="L383"> String msg = "Filtered request failed.";</span> |
| <span class="nc" id="L384"> throw new ServletException(msg, t);</span> |
| } |
| <span class="nc" id="L386"> }</span> |
| |
| /** |
| * Returns the {@code FilterChain} to execute for the given request. |
| * <p/> |
| * The {@code origChain} argument is the |
| * original {@code FilterChain} supplied by the Servlet Container, but it may be modified to provide |
| * more behavior by pre-pending further chains according to the Shiro configuration. |
| * <p/> |
| * This implementation returns the chain that will actually be executed by acquiring the chain from a |
| * {@link #getFilterChainResolver() filterChainResolver}. The resolver determines exactly which chain to |
| * execute, typically based on URL configuration. If no chain is returned from the resolver call |
| * (returns {@code null}), then the {@code origChain} will be returned by default. |
| * |
| * @param request the incoming ServletRequest |
| * @param response the outgoing ServletResponse |
| * @param origChain the original {@code FilterChain} provided by the Servlet Container |
| * @return the {@link FilterChain} to execute for the given request |
| * @since 1.0 |
| */ |
| protected FilterChain getExecutionChain(ServletRequest request, ServletResponse response, FilterChain origChain) { |
| <span class="nc" id="L407"> FilterChain chain = origChain;</span> |
| |
| <span class="nc" id="L409"> FilterChainResolver resolver = getFilterChainResolver();</span> |
| <span class="nc bnc" id="L410" title="All 2 branches missed."> if (resolver == null) {</span> |
| <span class="nc" id="L411"> log.debug("No FilterChainResolver configured. Returning original FilterChain.");</span> |
| <span class="nc" id="L412"> return origChain;</span> |
| } |
| |
| <span class="nc" id="L415"> FilterChain resolved = resolver.getChain(request, response, origChain);</span> |
| <span class="nc bnc" id="L416" title="All 2 branches missed."> if (resolved != null) {</span> |
| <span class="nc" id="L417"> log.trace("Resolved a configured FilterChain for the current request.");</span> |
| <span class="nc" id="L418"> chain = resolved;</span> |
| } else { |
| <span class="nc" id="L420"> log.trace("No FilterChain configured for the current request. Using the default.");</span> |
| } |
| |
| <span class="nc" id="L423"> return chain;</span> |
| } |
| |
| /** |
| * Executes a {@link FilterChain} for the given request. |
| * <p/> |
| * This implementation first delegates to |
| * <code>{@link #getExecutionChain(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) getExecutionChain}</code> |
| * to allow the application's Shiro configuration to determine exactly how the chain should execute. The resulting |
| * value from that call is then executed directly by calling the returned {@code FilterChain}'s |
| * {@link FilterChain#doFilter doFilter} method. That is: |
| * <pre> |
| * FilterChain chain = {@link #getExecutionChain}(request, response, origChain); |
| * chain.{@link FilterChain#doFilter doFilter}(request,response);</pre> |
| * |
| * @param request the incoming ServletRequest |
| * @param response the outgoing ServletResponse |
| * @param origChain the Servlet Container-provided chain that may be wrapped further by an application-configured |
| * chain of Filters. |
| * @throws IOException if the underlying {@code chain.doFilter} call results in an IOException |
| * @throws ServletException if the underlying {@code chain.doFilter} call results in a ServletException |
| * @since 1.0 |
| */ |
| protected void executeChain(ServletRequest request, ServletResponse response, FilterChain origChain) |
| throws IOException, ServletException { |
| <span class="nc" id="L448"> FilterChain chain = getExecutionChain(request, response, origChain);</span> |
| <span class="nc" id="L449"> chain.doFilter(request, response);</span> |
| <span class="nc" id="L450"> }</span> |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.7.201606060606</span></div></body></html> |