Both HandlerInterceptor
and HandlerInterceptorAdaptor
has preHandle
and postHandle
methods. But I am not able to understand what is the difference between them with respect to implementation.
postHandle() : After a request is handled by a request handler. It gives access to the returned ModelAndView object, so you can manipulate the model attributes in it. afterCompletion() : After the completion of all request processing i.e. after the view has been rendered.
Simply put, a Spring interceptor is a class that either extends the HandlerInterceptorAdapter class or implements the HandlerInterceptor interface. The HandlerInterceptor contains three main methods: prehandle() – called before the execution of the actual handler. postHandle() – called after the handler is executed.
Filters can modify inbound and outbound requests and responses including modification of headers, entity and other request/response parameters. Interceptors are used primarily for modification of entity input and output streams. You can use interceptors for example to zip and unzip output and input entity streams.
Interceptors will only execute after Filters. Fine-grained pre-processing tasks are suitable for HandlerInterceptors (authorization checks, etc.)
It's always a good practice to Program to an interface, not an implementation and Spring Framework uses this practice by providing quite a lot of these interfaces, HandlerInterceptor
is one of them. Some of these interfaces are richer than others. So if you as a client want to provide a custom implementation for them and only care for a few of their methods, you would end up with a few actual implementations and a lot of empty implementations.
For example, suppose you want to provide an implementation for preHandle
method and don't care about the other two. Unfortunately you should provide some empty implementations for the other two:
public class CustomHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
// Some complex logic
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
}
}
Those empty implementations would cause greater boilerplate codes when you're implementing even more richer interfaces, like WebMvcConfigurer
with 10+
abstract methods, imagine the loads of empty methods.
In order to solve this problem, Spring Framework usually provides a corresponding abstract Adapter for those interfaces, like HandlerInterceptorAdaptor
for HandlerInterceptor
interface or WebMvcConfigurerAdapter
for WebMvcConfigurer
. Those adapters are just a bunch of default and simplified implementations for all methods of those interfaces. You can refactor the preceding code using the provided adapter:
public class CustomHandlerInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
// Some complex logic
}
}
Since those empty implementations are provided by the HandlerInterceptorAdapter
class, you just need to provide your implementation for preHandle
method.
As I said, this is a recurring theme in the Spring Framework, some of the common examples are:
WebMvcConfigurer
and WebMvcConfigurerAdapter
CachingConfigurer
and CachingConfigurerSupport
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