Intercepting incoming requests using Spring’s Interceptor

Interceptor, as the name suggests, is broker your request might have to meet before it reaches the requested path controller.
Interceptor in J2EE is analogous to a receptionist in an office whom you have to talk with before meeting a person of interest.
Requests can be intercepted for several reasons for Logging, filtering requests as per country or optimizing image files before they are permanently saved. Or We can say, Before any request is served, To log the
origin of the request, modify the header file and append it into it the desired things, interceptors are needed. Interceptor is not specific to Spring rather standard of J2EE.
Writing loggers or optimizer in each and every controller can inject anomalies in your application and increase code overhead as well. Introducing J2EE interceptor in the application makes things lots easier by putting all those codes in a place by associating them with as many access point as needed
ultimately deciphering each request before it reaches the requested, path controller.
There are two ways interceptor can be implemented in spring
  1. Directly implementing an interface called HandleInterceptor
    2. or Extending HandleInterceptorAdapter.
Following functions need to be overridden when extending HandleInterceptorAdapter class :
1.preHandle
If returned true, the control would be passed to the next handler or next designated interceptor (i.e. postHandle)
If returned false, then it is assumed that no further handling is needed and written object
is responded to the client (postHandle and afterCompletion are not invoked).
2.postHandle
This function is invoked just before data is rendered to the client. Here you can add headers to the response object.
3.afterCompletion
it’s a callback method which is called back after data is rendered to the client.

Let’s have a code objective and its process plan.

Objective:
1. Log the IP address accessing resource URL “/data/secure-code”.
2. Block all IP address starting with “192” and redirect them to “/auth-failed”.
3. Log the total time to process request.
4. Interceptor chaining.
Process.
1. Create a class called LogInterceptor and extends it with HandlerInterceptorAdapter and annotated it with @Component.
2. Create another called AuthInterceptor and do same as specified for LogInterceptor.
3. Create Controller with path “/data/secure-code” and “/auth-failed”.
4. Register the above interceptor and path controller in new class WebMVCConfigure extending WebMVCConfigurerAdapter and annotated it with @Configuration
5. Make sure you make use of addPathPattern and excludePattern ( the path written inside excludePattern is not intercepted)
6. Not writing addPathPattern impliest that interceptor will be applied to all requested URL patterns.
Let's get into the code now.
Open IntelliJ and follow the process as shown in the snippet

Select Spring Initializer
Check Web For InBuild Tomcat.

Create three packages controller, config and interceptor as shown below in an image.


Right Click on the controller and write the code as shown below


Create a class. Let’s say LogInterceptor extending HandleInterceptor Adapter in interceptor package. Press Ctrl+O(specific to intellij) and override highlighted methods.

Override prehandle, postHandle and afterCompletion

PreHandle is the first point of interception and can be implemented like this.

Follow comments for clarity: refer git URL for more

PostHandle and afterCompletion should be like

postHandle is invoked just before date is rendered to the client whereas aftercompletion is callback once page render is completed

Register LogInterceptor in WebMvcConfigurerAdapter
We have interceptor in a place, now its time to register the interceptor in WebMVCConfig. For that create a class called WebMVCConfig, extend WebMvcConfigurerAdapter and override addInterceptor function as shown below

Override addInterceptor function

Add this code inside addInterceptor function :
registry.addInterceptor(new LogInterceptor());
// it is assume that LogInterceptor is going to intercept every incoming requests. Lets see on next step, how Interceptor can be associated with specific request or url pattern.
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/secure-code"); 
//addPathPattern ensure that interceptor is levied to specified pattern. In our case it is applicable to path with this pattern "/admin/login"
Similiary path can be exculded from intercepting using code given below.
"  registry.addInterceptor(new LogInterceptor()).addPathPatterns("/secure-code/*").excludePathPatterns("/secure-code/public");    "
Now the whole code inside WebMVCConfig should look like this

Don’t forget to annotate class with @Configuration

Now go to LogInterceptor and ensure if you have everything like shown below

and Lastly, the order of execution of interceptor: You just need to make sure the Interceptor are added in your desired orders like shown below

1. LogInterceptor is First Interceptor to intervene in the incoming request. Once it's through control would be passed to AuthInterceptor.

Note the application.properties file should have the following things specified.
logging.level.org.springframework=DEBUG
logging.level.com.howtodoinjava=DEBUG# Logging pattern for the consolelogging.pattern.console= %d{yyyy-MM-dd HH:mm:ss} - %msg%n#output to a temp_folder/filelogging.file=${java.io.tmpdir}/application.log#logging.file=c://application-debug.log
# Logging pattern for filelogging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg

Comments

Popular posts from this blog

Hibernate (Java) -- by jps sasadara

Observer Design Pattern & RxJava & @Async

JAVA uml Based cording <<< by jps sasadara >>>