@ControllerAdvice needs MVC
namespace declaration in XML file. Or we can use @EnableWebMvc with
@ControllerAdvice annotation.
- · As of Spring 4, @ControllerAdvice can be customized through annotations(), basePackageClasses(), basePackages() methods to select a subset of controllers to assist. I will demonstrate a simple case how to utilize this new feature.
- ·
Allows for more
concise annotation declarations e.g.:
@ControllerAdvice("org.my.pkg")
is equivalent to@ControllerAdvice(basePackages="org.my.pkg")
. - ·
Controllers that
belong to those base packages or sub-packages thereof will be included, e.g.:
@ControllerAdvice(basePackages="org.my.pkg")
or@ControllerAdvice(basePackages={"org.my.pkg", "org.my.other.pkg"})
. - @ControllerAdvice(basePackageClasses = io.github.kazuki43zoo.app.AppControllerAdvice.class)
Spring MVC provides a great
way to handle exceptions and errors. @ExceptionHandler annotation is core to this feature. For each Spring controller we can
simply define a method that automatically gets called if a given exception
occurs. For example:
import org.springframework.web.bind.annotation.ExceptionHandler;
//..
@ExceptionHandler(IOException.class)
public String exception(Exception e) {
//..
return "error";
}
Thus whenever an IOException is raised from any
controller method will call the above method exception(). We mapped
IOException.class to this method using @ExceptionHandler annotation.
One short coming of this annotation is that it
only handles exception getting raised from the controller where it is defined.
It will not handle exceptions getting raised from other controllers. However
this is a way to overcome this problem. @ControllerAdvice annotation
is at your service for that.
@ControllerAdvice
annotation
This annotation is used to define @ExceptionHandler, @InitBinder, and @ModelAttribute methods that apply to all @RequestMapping methods.
import org.springframework.web.bind.annotation.ControllerAdvice;
//..
@ControllerAdvice
public class ExceptionControllerAdvice {
@ExceptionHandler(Exception.class)
public String exception(Exception e) {
return "error";
}
}
Thus if we define our @ExceptionHandler
annotation on method in @ControllerAdvice class, it will be applied to all the
controllers.
One thing worth noting here is that Spring
configuration must define mvc namespace in order to identify @ControllerAdvice annotation.
Thus you must define following in your spring-servlet.xml file.
<mvc:annotation-driven/>
If you have
defined just the <context:annotation-config /> it wouldn’t
work. The @ControllerAdvice will simply wont be loaded. So always remember to
use <mvc:annotation-driven/> in Spring configuration
This will apply to all the classes which ever uses @RestController
as annotation
@ControllerAdvice(annotations=RestController.class)
public
class ExceptionControllerAdvice {
@ExceptionHandler(Exception.class)
public ResponseEntity<String>
getSQLError(Exception exception){
HttpHeaders headers = new
HttpHeaders();
headers.set("HeaderKey","HeaderDetails");
return new
ResponseEntity<String>("<a
href="http://javabeat.net/recommends/rest-with-spring/"
class="thirstylink" rel="nofollow"
target="_blank" title="Rest">Rest</a> Controller
Advice Example",headers,HttpStatus.ACCEPTED);
}
}