Imagine we have a controller like this:
@RestController
@RequestMapping("/{parameter}")
public class MyController {
@ExceptionHandler(SomeException.class)
public Object handleSomeException() { /* handle */ }
@RequestMapping("/something")
public Object handleSomething(@PathVariable("parameter") String parameter) {
/* handle */
}
@RequestMapping("/somethingElse")
public Object handleSomethingElse(@PathVariable("parameter") String parameter) {
/* handle */
}
}
The question is, how to implement some common pre-\post-handling for this particular controller in similar way as @ExceptionHandler
is working? E.g. I want to have a method in controller which receives request prior to handler methods, but only requests for this particular controller.
I'm aware of RequestBodyAdvice
and ResponseBodyAdvice
interfaces, but want something local to controller.
As a usage example - I want to do some validation for common parameter
variable before each handler.
What is miss in all above answers it how to register interceptor for specific controller, which can be done as follows:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
}
}
In XML, the same:
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/admin/**"/>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/secure/*"/>
<bean class="org.example.SecurityInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
spring documentation
You will need to write you own HandlerInterceptor
. You can do it easily by extending HandlerInterceptorAdapter
. And then you can override preHandle()
and/or postHandle()
.
preHandle()
is called afterHandlerMapping
determined an appropriate handler object, but beforeHandlerAdapter
invokes the handler.
postHandle()
is called afterHandlerAdapter
actually invoked the handler, but before theDispatcherServlet
renders the view.
You can use the getRequestURI()
method of HttpServletRequest
to add logics for different handlers in preHandle()
.
Example:
public class ValidationInterceptor extends HandlerInterceptorAdapter {
public static final String FOO_URL = "foo";
public static final String BAR_URL = "bar";
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String uri = request.getRequestURI();
if (FOO_URL.equals(uri)) {
// for example - validation failed
response.sendRedirect("/to/some/url");
return false;
} else if (BAR_URL.equals(uri)) {
// for example - validation successful
}
return true;
}
}
Then register this HandlerInterceptor
in your dispatcher-servlet.xml
.
<mvc:interceptors>
<bean class="your.package.ValidationInterceptor"/>
</mvc:interceptors>
You can configure this to be more url-specific. See 22.16.5 Interceptors section of Spring Reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With