As discovered in spring-boot:3.2.0-RC1 (previous milestone unaffected) changes to populate init parameters and dispatch types in MockMvc auto-configuration have led to all filters (or those without explicit registration?) ending up with empty-string as their getFilterName. This ultimately breaks the OncePerRequestFilter behavior because all filters use .FILTERED as their request attribute so only the first one runs.

The stack here I believe is something like:

org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer#addFilter
org.springframework.test.web.servlet.setup.AbstractMockMvcBuilder#addFilter(jakarta.servlet.Filter, java.util.Map<java.lang.String,java.lang.String>, java.util.EnumSet<jakarta.servlet.DispatcherType>, java.lang.String...)

So we end up with MockMvcFilterDecorator even though we aren't doing any filtering/otherwise -- this is change from last milestone.

Then in MockMvcFilterDecorator#initIfRequired we create a MockFilterConfig which always has an empty-string filterName.

@wilkinsona had suggestions over here about different approaches to harmonizing this between framework and boot: https://github.com/spring-projects/spring-boot/issues/37835#issuecomment-1773729361

Comment From: edwardsre

We are experiencing this regression also. I have been able to work around it temporarily by overriding getFilterName() in our once per request filter InvocationContextFilter.

  @Override
  protected String getFilterName() {
    return Optional.ofNullable(super.getFilterName())
      .filter(StringUtils::hasText)
      .orElseGet(InvocationContextFilter.class::getSimpleName);
  }