title: How do servlet filters work in Spring?
body: <p>I'm trying to add a CORS filter to my Spring web application but the filter is not being executed. I've followed the relevant steps here: <a href="https://spring.io/guides/gs/rest-service-cors/" rel="nofollow">https://spring.io/guides/gs/rest-service-cors/</a> to no avail. I'm not using Spring Boot. I'm bootstrapping my application using Spring's WebApplicationInitializer in a 3.0+ servlet spec container.</p>
  
  <p>Everything else in my application is working: configuration classes, controllers, hibernate entities, etc.</p>
  
  <p><strong>Update 1:</strong></p>
  
  <p>The below answers worked for me by adding the filter to the servlet container:</p>
  
  <pre><code>container.addFilter("CorsFilter", CorsFilter.class)
            .addMappingForUrlPatterns(null, false, "/*");
  </code></pre>
  
  <p>However, I'm curious why Spring Boot does not require this? They must automatically search for Filters and add them to the context. Is there a straightforward way to do this? It seems unfortunate that I have to create a filter and then add it to some list in another class. It'd be nice if they were automatically registered like in Spring Boot.</p>
  
  <p><strong>Relevant code snippets:</strong></p>
  
  <p>WebApplicationInitializer:</p>
  
  <pre><code>public class AppInitializer implements WebApplicationInitializer {
  
      @Override
      public void onStartup(ServletContext container) throws ServletException {
          // Create the 'root' Spring application context
          AnnotationConfigWebApplicationContext rootContext =
                  new AnnotationConfigWebApplicationContext();
          rootContext.register(AppConfig.class);
  
          // Manage the lifecycle of the root application context
          container.addListener(new ContextLoaderListener(rootContext));
  
          // Create the dispatcher servlet's Spring application context
          AnnotationConfigWebApplicationContext dispatcherContext =
                  new AnnotationConfigWebApplicationContext();
          dispatcherContext.register(WebAppConfig.class);
  
          // Register and map the dispatcher servlet
          ServletRegistration.Dynamic dispatcher =
                  container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
          dispatcher.setLoadOnStartup(1);
          dispatcher.addMapping("/");
      }
  
  }
  </code></pre>
  
  <p>AppConfig:</p>
  
  <pre><code>@Configuration
  @ComponentScan
  public class AppConfig {
  }
  </code></pre>
  
  <p>WebAppConfig:</p>
  
  <pre><code>@Configuration
  @EnableWebMvc
  @EnableSpringDataWebSupport
  @ComponentScan(basePackageClasses = AppConfig.class)
  public class WebAppConfig extends WebMvcConfigurerAdapter {
  }
  </code></pre>
  
  <p>CorsFilter:</p>
  
  <pre><code>@Component
  public class CorsFilter implements Filter {
  
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
              throws IOException, ServletException {
  
          HttpServletResponse httpResponse = (HttpServletResponse) response;
          httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
          httpResponse.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
          httpResponse.setHeader("Access-Control-Max-Age", "3600");
          httpResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
  
          HttpServletRequest httpRequest = (HttpServletRequest) request;
          String origin = httpRequest.getHeader("Origin");
          if (StringUtils.hasText(origin)) {
  
              boolean isMyDomain =
                  Pattern.compile("^https://(.*?\\.)?mydomain.com(:\\d+)?$")
                          .matcher(origin)
                          .find();
              if (isMyDomain) {
                  httpResponse.setHeader("Access-Control-Allow-Origin", origin);
              } else {
                  httpResponse.setHeader("Access-Control-Allow-Origin", "mydomain");
              }
  
          }
          chain.doFilter(request, response);
      }
  
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
          LoggerFactory.getLogger(getClass()).info("CorsFilter initiated");
      }
  
      @Override
      public void destroy() {
          LoggerFactory.getLogger(getClass()).info("CorsFilter destroyed");
      }
  }
  </code></pre>