Time for action – configuring an interceptor

Một phần của tài liệu Spring MVC beginners guide (Trang 169 - 173)

Every web request takes a certain amount of time to get processed by the server. In order to find out how much time it takes to process a web request, we need to calculate the time difference between the starting time and ending time of a web request process. We can achieve that by using the interceptor concept. Let's see how to configure our own

interceptor in our project to log the execution time of every web request:

Open pom.xml; you can find pom.xml under the root directory of the project

1. itself.

You will see some tabs at the bottom of the pom.xml file; select the Dependencies

2. tab and click on the Add button in the Dependencies section.

A Select Dependency window will appear; enter Group Id as log4j, Artifact Id

3. as log4j, and Version as 1.2.17, select Scope as compile, click the OK button, and save pom.xml.

Create a class named ProcessingTimeLogInterceptor under the

4.

com.packt.webstore.interceptor package in the src/main/java source folder, and add the following code to it:

package com.packt.webstore.interceptor;

import javax.servlet.http.HttpServletRequest;

Internalize Your Store with Interceptor

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

public class ProcessingTimeLogInterceptor implements

HandlerInterceptor {

private static final Logger LOGGER =

Logger.getLogger(ProcessingTimeLogInterceptor.class);

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

long startTime = System.currentTimeMillis();

request.setAttribute("startTime", startTime);

return true;

}

public void postHandle(HttpServletRequest request,

HttpServletResponse response, Object handler, ModelAndView

modelAndView) {

String queryString = request.getQueryString() == null ? "" : "?" + request.getQueryString();

String path = request.getRequestURL() + queryString;

long startTime = (Long)

request.getAttribute("startTime");

long endTime = System.currentTimeMillis();

LOGGER.info(String.format("%s millisecond taken to

process the request %s.",(endTime - startTime), path));

}

public void afterCompletion(HttpServletRequest request,

HttpServletResponse response, Object handler, Exception exceptionIfAny){

// NO operation.

}

}

Now open your web application context configuration file

5. WebApplicationContextConfig.java, add the following method to it, and save the file:

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new

ProcessingTimeLogInterceptor());

}

Internalize Your Store with Interceptor

[ 158 ]

Create a property file named log4j.properties under the

6. src/main/resources directory, and add the following content. Then, save the file:

# Root logger option

log4j.rootLogger=INFO, file, stdout

# Direct log messages to a log file

log4j.appender.file=org.apache.log4j.RollingFileAppender

log4j.appender.file.File= C:\\webstore\\webstore-

performance.log

log4j.appender.file.MaxFileSize=1MB

log4j.appender.file.MaxBackupIndex=1

log4j.appender.file.layout=org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd

HH:mm:ss} %-5p %c{1}:%L - %m%n

# Direct log messages to stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target=System.out

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd

HH:mm:ss} %-5p %c{1}:%L - %m%n

Now run our application, enter the

7.

http://localhost:8080/webstore/market/products URL, and navigate to some pages; you should able to see the logging in the console as follows:

Showing ProcessingTimeLogInterceptor logging messages in the console

Open the file C:\webstore\webstore-performance.log; you can see the

8. same log message in the logging file as well.

What just happened?

Our intention was to record the execution time of every request coming to our web

application, so we decided to record the execution times in a log file. In order to use a logger, we needed the log4j library, so we added the log4j library as a Maven

dependency in step 3.

Internalize Your Store with Interceptor

In step 4, we defined an interceptor class named ProcessingTimeLogInterceptor by implementing the HandlerInterceptor interface. As we already saw, there are three methods that need to be implemented. We will see each method one by one. The first method is preHandle(), which is called before the execution of the Controller method:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

long startTime = System.currentTimeMillis();

request.setAttribute("startTime", startTime);

return true;

}

In the previously shown preHandle method, we just set the current time value in the request object for later retrieval. Whenever a request comes to our web application, it first comes through this preHandle method and sets the current time in the request object before reaching the Controller. We are returning true from this method because we want the execution chain to proceed with the next interceptor or the Controller itself. Otherwise, DispatcherServlet assumes that this interceptor has already dealt with the response itself. So if we return false from the preHandle method, the request won't proceed to the Controller or the next interceptor.

The second method is postHandle, which will be called after the Controller method's execution:

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {

String queryString = request.getQueryString() == null ? "" : "?" + request.getQueryString();

String path = request.getRequestURL() + queryString;

long startTime = (Long) request.getAttribute("startTime");

long endTime = System.currentTimeMillis();

LOGGER.info(String.format("%s millisecond taken to process the request

%s.",(endTime - startTime), path));

}

In the preceding method, we are simply logging the difference between the current time, which is considered to be the request processing finish time, and the start time, which we got from the request object. Our final method is afterCompletion, which is called after the View is rendered. We don't want to put any logic in this method, that's why I left the method empty.

Internalize Your Store with Interceptor

[ 160 ]

If you don't want to implement all the methods from the

HandlerInterceptor interface in your interceptor class, you could

consider extending your interceptor from

org.springframework.web.servlet.handler.HandlerIntercepto rAdapter, which is a convenient class provided by Spring MVC as a

default implementation of all the methods from the

HandlerInterceptor interface.

After creating our ProcessingTimeLogInterceptor, we need to register our interceptor with Spring MVC, which is what we have done in step 5 through the addInterceptors overridden method of WebMvcConfigurerAdapter:

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new ProcessingTimeLogInterceptor());

}

In step 6, we have added a log4j.properties file in order to specify some logger-related configurations. You can see we have configured the log file location in log4j.properties

as follows:

log4j.appender.file.File= C:\\webstore\\webstore-performance.log

Finally, in step 7 we ran our application in order to record some performance logging, and

we were able to see that the logger is just working fine via the console. You can open the log file to view the performance logs.

So we understood how to configure an interceptor and saw

ProcessingTimeLogInterceptor in action. In the next exercise, we will see how to use some Spring-provided interceptors.

Một phần của tài liệu Spring MVC beginners guide (Trang 169 - 173)

Tải bản đầy đủ (PDF)

(342 trang)