Close

Spring MVC - @ControllerAdvice With @ModelAttribute Example

[Last Updated: Apr 30, 2018]

@ControllerAdvice is a specialization of @Component which can be used to define methods with @ExceptionHandler, @InitBinder, and @ModelAttribute annotations. Such methods are applied to all @RequestMapping methods across multiple @Controller classes instead of just local @Controller class.

Following example shows how to use @ModelAttribute in @ControllerAdvice class to globally apply module attributes.

Example

We are going to populate module attributes with the page counter and the request URI in the @ControllerAdvice class.

package com.logicbig.example;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;

@ControllerAdvice
public class PageCountersControllerAdvice {
  //uri to counter map
  private ConcurrentHashMap<String, LongAdder> counterMap = new ConcurrentHashMap<>();

  @ModelAttribute
  public void handleRequest(HttpServletRequest request, Model model) {
      String requestURI = request.getRequestURI();
      //counter increment for each access to a particular uri
      counterMap.computeIfAbsent(requestURI, key -> new LongAdder())
                .increment();
      //populating counter in the model
      model.addAttribute("counter", counterMap.get(requestURI).sum());
      //populating request URI in the model
      model.addAttribute("uri", requestURI);
  }
}

The Controllers

@Controller
public class ProductsController {

  @RequestMapping("/products/**")
  public String handleRequest(){
      //todo:prepare page content
      return "app-page";
  }
}
@Controller
public class ServicesController {

  @RequestMapping("/services/**")
  public String handleRequest() {
      //todo:prepare page content
      return "app-page";
  }
}

The view

src/main/webapp/WEB-INF/views/app-page.jsp

<html>
<body>

<p>Page counter: ${counter}</p>
<p>App content .... at ${uri}</p>

</body>
</html>

Output

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war

Accessing and refreshing pages multiple times:

As seen above, page counter is maintained and supplied as module attribute for both of our controllers.

Example Project

Dependencies and Technologies Used:

  • spring-webmvc 5.0.5.RELEASE: Spring Web MVC.
  • javax.servlet-api 3.0.1 Java Servlet API
  • JDK 1.8
  • Maven 3.3.9

@ControllerAdvice With @ModelAttribute Example Select All Download
  • controller-advice-model-attribute-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • PageCountersControllerAdvice.java
          • webapp
            • WEB-INF
              • views

    See Also