Skip to content

HandlerInterceptorAdapter: unexpected behaviour for different methods on the same endpoint [SPR-17375] #21908

@spring-projects-issues

Description

@spring-projects-issues

Enrico Graziani opened SPR-17375 and commented

Problem

While testing how HandlerInterceptorAdapter works, we found out that by:

  • registering the interceptor for /some/**
  • having a controller with a registered method GET /some/thing

will cause the interceptor to be executed for:

  •  GET /some/thing
  • all [VERB] /some/**
    APART [VERB] /some/thing

e.g. so POST /some/thing will not pass through the above interceptor

 

IMO
This sounds confusing.
The +expected behaviour+ would be to either execute the interceptor for:

  • all available methods/endpoint for the registered interceptor
    in this example, [VERB] /some/** requests
  • or, only the method/endpoint registered in the controllers
    in this example,  GET /some/thing

Background

We have a requirement to log every request and collect metrics in Splunk.
We were thinking on registering a HandlerInterceptorAdapter for holding these behaviours.

Code Snippets

Application is annotated with @SpringBootApplication 
Controller is annotated with @RestController

springBootVersion = "2.0.2.RELEASE"

Application

@SpringBootApplication
public class Application {

    private static final Logger logger = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        logger.info("Starting Application");
        SpringApplication.run(Application.class, args);
    }
}

WebConfig

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoggerRequestInterceptor loggerRequestInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loggerRequestInterceptor)
                .addPathPatterns("/some/**");
    }
}

LoggerRequestInterceptor

@Component
public class LoggerRequestInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = LoggerFactory.getLogger(LoggerRequestInterceptor.class);

    @Override
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) {
        logger.info(MessageFormat.format(
                "{0} {1}",
                request.getMethod(),
                request.getRequestURI()
        ));
        return true;
    }

}

Controller

@RestController
@RequestMapping("/some/")
public class HoldingController {

    @GetMapping(path = {"/thing"}, produces={"application/json"})
    public String getHoldingsMaterial() {
        return "hi";
    }
}

Behaviours

GET /some/thing

*.LoggerRequestInterceptor   : GET /some/thing

GET /some/notExisting

*.LoggerRequestInterceptor   : GET /some/notExisting

POST /some/thing

o.s.web.servlet.PageNotFound             : Request method 'POST' not supported

Affects: 5.0.6

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)status: declinedA suggestion or change that we don't feel we should currently apply

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions