Why Your @ControllerAdvice May Not Be Firing

The Spring @ControllerAdvice model can save a lot of coding in making objects and logic available to clients. It is extremely easy to implement and “just works.” But when it doesn’t “just work” for you, this post may provide you with a cause as I discovered for myself.

I blogged about using an External Properties file in my NixMash Spring app and how I’m passing the ApplicationSettings properties class as a Model Attribute to web pages.

@ModelAttribute("appSettings")
public ApplicationSettings getApplicationSettings() {
return applicationSettings;
}

Like I said, nothing to it, and with Thymeleaf’s tight Spring integration we can easily check any settings.

<div th:if="${appSettings.getIsDemoSite()}" class="demo-login-note">
Login with username "user", password "password"
</div>

This worked flawlessly except when I hit the /login page and the @ControllerAdvice didn’t fire. What was different about the /login page? Permissions? Context? Is he a good Greek Boy? I don’t know!!

Then I found this bit of code in my WebConfiguration @Configuration class.

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}

I did some reading from the Spring Reference Guide on addViewControllers().

21.16.7 View Controllers

[AddViewControllers] is a shortcut for defining a ParameterizableViewController that immediately forwards to a view when invoked. Use it in static cases when there is no Java controller logic to execute before the view generates the response.

(Emphasis mine, as they say.)

So by registering /login I was bypassing the @ControllerAdvice and ended up with a null “appSettings” on the client and a big fat error. Another case when the best code is no code at all. addViewControllers(/login) deleted!