Mapped interceptors

Interceptors are a great way to add logic that needs to be executed during every request to our web application. The cool thing about interceptors is that, not only can we have a logic that executes before and/or after the request, we can even bypass or redirect the original web request itself. So far, we have seen a couple of examples of interceptors, such as performance logging and internationalization, but one problem with those examples is that there is no proper way to stop them from being run for specific requests.

For example, we might have a specific web request that does not need to run that additional logic in our interceptor. How can we tell Spring MVC to selectively include or exclude interceptors? Mapped interceptors to the rescue; using mapped interceptors we can selectively include or exclude interceptors, based on a mapped URL. Mapped interceptors use Ant-based path pattern matching to determine whether a web request path matches the given URL path pattern.

Consider a situation where you want to show the special-offer products page only to those users who have a valid promo code, but others who are trying to access the special-offer products page with an invalid promo code should be redirected to an error page.

Time for action - mapped intercepting offer page requests

Let's see how we can achieve this piece of functionality with the help of a mapped interceptor:

  1. Create a class named PromoCodeInterceptor under the 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 java.io.IOException; 
     
          import javax.servlet.http.HttpServletRequest; 
          import javax.servlet.http.HttpServletResponse; 
          import org.springframework.web.servlet.handler
          .HandlerInterceptorAdapter; 
     
          public class PromoCodeInterceptor extends 
          HandlerInterceptorAdapter { 
     
             private String promoCode; 
             private String errorRedirect; 
             private String offerRedirect; 
     
             public boolean preHandle(HttpServletRequest request, 
             HttpServletResponse response, Object handler) throws 
             IOException{ 
                String givenPromoCode = request.getParameter("promo"); 
     
                if (promoCode.equals(givenPromoCode)) { 
                   response.sendRedirect(request.getContextPath() + "/" 
                   + offerRedirect); 
                } else { 
                   response.sendRedirect(errorRedirect); 
                } 
     
                return false; 
             } 
     
             public void setPromoCode(String promoCode) { 
                this.promoCode = promoCode; 
             } 
     
             public void setErrorRedirect(String errorRedirect) { 
                this.errorRedirect = errorRedirect; 
             } 
     
             public void setOfferRedirect(String offerRedirect) { 
                this.offerRedirect = offerRedirect; 
             } 
          } 
    
  2. Create a bean definition for PromoCodeInterceptor in our web application context (WebApplicationContextConfig.java) as follows:
          @Bean 
          public HandlerInterceptor promoCodeInterceptor() { 
             PromoCodeInterceptor promoCodeInterceptor = new 
          PromoCodeInterceptor(); 
             promoCodeInterceptor.setPromoCode("OFF3R"); 
             promoCodeInterceptor.setOfferRedirect("market/products"); 
             promoCodeInterceptor.setErrorRedirect("invalidPromoCode"); 
        
             return promoCodeInterceptor; 
          } 
    
  3. Now configure the PromoCodeInterceptor interceptor bean in our InterceptorRegistry as follows:
          @Override 
          public void addInterceptors(InterceptorRegistry registry) { 
             registry.addInterceptor(new       
             ProcessingTimeLogInterceptor()); 
        
             LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); 
             localeChangeInterceptor.setParamName("language"); 
             registry.addInterceptor(localeChangeInterceptor); 
        
             registry.addInterceptor(promoCodeInterceptor())
    
            .addPathPatterns("/**/market/products/specialOffer"); 
          } 
    
  4. Open our ProductController class and add one more request mapping method as follows:
          @RequestMapping("/products/invalidPromoCode") 
          public String invalidPromoCode() { 
                return "invalidPromoCode"; 
          } 
    
  5. Finally add one more JSP View file called invalidPromoCode.jsp under the directory src/main/webapp/WEB-INF/views/, add the following code snippets to it, and save it:
          <%@ taglib prefix="c" 
          uri="http://java.sun.com/jsp/jstl/core"%> 
          <%@ taglib prefix="spring" 
          uri="http://www.springframework.org/tags" %>  
          <!DOCTYPE html> 
          <html> 
          <head> 
          <meta http-equiv="Content-Type" content="text/html; 
          charset=ISO-8859-1"> 
          <link rel="stylesheet" href="//netdna.bootstrapcdn.com/
          bootstrap/3.0.0/css/bootstrap.min.css"> 
          <title>Invalid promo code</title> 
          </head> 
          <body> 
             <section> 
                <div class="jumbotron"> 
                   <div class="container"> 
                      <h1 class="alert alert-danger"> Invalid promo 
                      code</h1> 
                   </div> 
                </div> 
             </section> 
     
             <section> 
                <div class="container"> 
                   <p> 
                      <a href="<spring:url value="/market/products" />"
            class="btn btn-primary"> 
                         <span class="glyphicon-hand-left glyphicon">  
              </span> products 
                      </a> 
                   </p> 
                </div> 
           
             </section> 
          </body> 
          </html> 
    
  6. Now run our application and enter the http://localhost:8080/webstore/market/products/specialOffer?promo=offer URL; you should be able to see an error message page as follows:
    Time for action - mapped intercepting offer page requests

    Showing invalid promo code exception

  7. Now enter the http://localhost:8080/webstore/market/products/specialOffer?promo=OFF3R URL; you will land on a special-offer products page.
    Time for action - mapped intercepting offer page requests

    Showing special-offer page

What just happened?

The PromoCodeInterceptor class that we created in step 1 is very similar to ProcessingTimeLogInterceptor; the only difference is that we have extended HandlerInterceptorAdapter and only overridden the preHandle method:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException{ 
   String givenPromoCode = request.getParameter("promo"); 
 
   if (promoCode.equals(givenPromoCode)) { 
      response.sendRedirect(request.getContextPath() + "/" + offerRedirect); 
   } else { 
      response.sendRedirect(errorRedirect); 
   } 
 
   return false; 
} 

In the preHandle method, we are simply checking whether the request contains the correct promo code as the HTTP parameter. If so, we redirect the request to the configured special-offer page; otherwise, we redirect it to the configured error page.

The PromoCodeInterceptor class has three properties, promoCode, errorRedirect, and offerRedirect. The promoCode property is used to configure the valid promo code; in our case, we have assigned OFF3R as the valid promo code in step 2, so whoever is accessing the special-offer page should provide OFF3R as the promo code in their HTTP parameter in order to access the special-offer page.

The next two attributes, errorRedirect and offerRedirect, are used for redirection. errorRedirect indicates the redirect URL mapping in the case of an invalid promo code and offerRedirect indicates the redirect URL mapping for a successful promo code redirection.

Tip

I have not created a special-offer products page; for demonstration purposes I have reused the same regular products page as a special-offer products page, which is why we have assigned market/products as the value for offerRedirect; thus, in the case of a valid promo code we are simply redirecting to the regular products page. But if we create a special-offer products page, we can assign that page URL as the value for offerRedirect.

Okay, we have created the PromoCodeInterceptor bean, but we have to configure this interceptor with our Spring MVC runtime, which is what we have done in step 3 by adding the PromoCodeInterceptor bean to our InterceptorRegistry within the addInterceptors method:

@Override 
public void addInterceptors(InterceptorRegistry registry) { 
   registry.addInterceptor(new ProcessingTimeLogInterceptor()); 
    
   LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); 
   localeChangeInterceptor.setParamName("language"); 
   registry.addInterceptor(localeChangeInterceptor); 
    
   registry.addInterceptor(promoCodeInterceptor())
         .addPathPatterns("/**/market/products/specialOffer"); 
} 

If you notice, while adding promoCodeInterceptor to our InterceptorRegistry, we can specify URL patterns using the addPathPatterns method. This way we can specify the URL patterns to which the registered interceptor should apply. So our promoCodeInterceptor will get executed only for a request that ends with market/specialOffer.

Tip

While adding an interceptor, we can also specify the URL patterns that the registered interceptor should not apply to via the excludePathPatterns method.

In step 4, we have added one more request mapping method called invalidPromoCode to show an error page in the case of an invalid promo code. In step 5, we have added the corresponding error View file, called invalidPromoCode.jsp.

So in step 6, we purposely entered the http://localhost:8080/webstore/market/products/specialOffer?promo=offer URL into our running application to demonstrate PromoCodeInterceptor in action; we saw the error page because the promo code we gave in the URL is offer (?promo=offer), which is wrong. In step 7, we gave the correct promo code in the http://localhost:8080/webstore/market/products/specialOffer?promo=OFF3R URL, so we should be able to see the configured special-offer products page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.100.212