@ControllerAdvice is a sub type of @Component annotation and it useful to handle exceptions across the whole application in a single place.
When to use @ControllerAdvice?
If you have number of controllers, handling exception from each controller method is a tedious task. With @ControllerAdvice you can handle all the exceptions in a single(Global) place.
@ControllerAdvice is a annotation-based global exception handling interceptor.
Example of @ControllerAdvice
In this article I’ll explain @ControllerAdvice annotation with a simple REST API.
I’m going to handle exceptions thrown by two controllers: AdminController and CustomerController.

Here I have defined two exceptions: AdminException and CustomerNotFoundException.
I’m going to handle those two exceptions and send a meaningful response to the user using @ControllerAdvice.
@ControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler(CustomerNotFoundException.class)
public ResponseEntity customerNotFoundException(Exception ex){
//Create customer response
String output = "Customer not found " + new Date() + " " + ex.getMessage();
return new ResponseEntity(output, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(AdminException.class)
public ResponseEntity invalidNameException(Exception ex){
//Create customer response
String output = "Invalid Admin " + new Date() + " " + ex.getMessage();
return new ResponseEntity(output, HttpStatus.BAD_REQUEST);
}
}
I have created a class annotated with @ControllerAdvice and inside it I have created separate methods to handle each exception. With @ExceptionHandler annotation, I can define which exception should be handled inside each method.
These are my two controllers. For testing purpose I have thrown the defined exceptions when user sends “Invalid” as the request parameter.
@RestController
public class AdminController {
@GetMapping(value = "/admin")
public ResponseEntity getCustomer(@RequestParam(name = "admin") String admin) throws AdminException {
if (admin.equals("Invalid")){//Just for testing
throw new AdminException("Invalid Admin: " + admin);
}
return new ResponseEntity("Admin Request Success", HttpStatus.OK);
}
}
@RestController
public class CustomerController {
@GetMapping(value = "/customer")
public ResponseEntity getCustomer(@RequestParam(name = "name") String name) throws CustomerNotFoundException {
if (name.equals("Invalid")){//Just for testing
throw new CustomerNotFoundException("Invalid Customer: " + name);
}
return new ResponseEntity("Customer Request Success", HttpStatus.OK);
}
}
Let’s run the application for success scenario.
D:\>curl -i http://localhost:8080/customer?name=Prasad
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 24
Date: Thu, 18 Jun 2020 00:58:49 GMT
Customer Request Success
D:\>curl -i http://localhost:8080/admin?admin=AdminName
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 21
Date: Thu, 18 Jun 2020 01:00:30 GMT
Admin Request Success
Now we know that both APIs are working properly. Let’s execute the exceptional scenario where our Controller advice should send use formatted output.
D:\>curl -i http://localhost:8080/customer?name=Invalid
HTTP/1.1 400
Content-Type: text/plain;charset=UTF-8
Content-Length: 73
Date: Thu, 18 Jun 2020 01:04:33 GMT
Connection: close
Customer not found Thu Jun 18 09:04:33 CST 2020 Invalid Customer: Invalid
D:\>curl -i http://localhost:8080/admin?admin=Invalid
HTTP/1.1 400
Content-Type: text/plain;charset=UTF-8
Content-Length: 65
Date: Thu, 18 Jun 2020 01:07:21 GMT
Connection: close
Invalid Admin Thu Jun 18 09:07:21 CST 2020 Invalid Admin: Invalid
Now you can see that we have handled exceptions thrown by multiple controllers and forwarded a costume response to the user.
How to control the access?
By default ControllerAdvice will apply to all the classes which are annotated with @Controller or @RestController annotations. But there are few ways to control the access.
By specifying the base package
@ControllerAdvice("com.prasadct.controllerAdvice.controllerAdvice.controller")
@ControllerAdvice(value = "com.prasadct.controllerAdvice.controllerAdvice.controller")
@ControllerAdvice(basePackages = "com.prasadct.controllerAdvice.controllerAdvice.controller")
All of the above three configurations are valid. All of them only apply to the controllers inside that specific package: “com.prasadct.controllerAdvice.controllerAdvice.controller”
Also you can specify array of packages by specifying those inside curly brackets.
@ControllerAdvice(value = {"pkg1, pkg2, pkg3"})
By Specifying the class
You can apply ControllerAdvice to a specific class or array of classes.
@ControllerAdvice(basePackageClasses = AdminController.class)
@ControllerAdvice(basePackageClasses = {AdminController.class, CustomerController.class})
Important points
- If there are multiple ControllerAdvices and multiple handlers for same exception, you can’t guaranteed that which method will handle the exception. Better you avoid such kind of cases.
- You can extend your ControllerAdvice with ResponseEntityExceptionHandler and it provides to provide centralized exception handling across all @RequestMapping methods through @ExceptionHandler methods.
- There is a more specialized version of exception handler wrapped with @ResponseBody called @RestControllerAdvice which is convenient for RESTful web services.
Conclusion
Handling exceptions globally with @ControllerAdvice allows us to make our business logic clean and transfer all exception handling to a separate component. Also we can provide a unique error response across all APIs.
Sample Code
Please find my example project from Github.
Related articles:
What is Spring Boot and Why it is the best way to start learning Spring Framework?
Very helpful.Thanks
Cheers
Thank you. (Y)
Wow! At last I got a weblog from where I be able to genuinely take useful facts concerning my study and knowledge. Loella Hermon Chew
Amazing! Its actually remarkable paragraph, I have got much clear idea about from this piece of writing. Denny Puff Felise
I view something really interesting about your site so I bookmarked . Shirlee Neale Sylvie
This is one awesome article. Really looking forward to read more. Keep writing. Ally Stinky Kristoffer
I quite like reading an article that will make people think. Also, thanks for allowing for me to comment. Constance Xavier Wilkens
Either way, you getyoua personfindobtainan individualacquirea person receive the same features in almost every slot machine bank. Eddy Son Schick
I am sure this piece of writing has touched all the internet people, itss really really fastidious paragraph on building up neww webpage. Ninnetta Holden Apthorp
Way cool! Some extremely valid points! I appreciate you penning this post and the rest of the website is extremely good. Maxy Samuele Aron
Utterly pent written content , regards for entropy. Elysha Reese Robbin
Hi friends, its fantastic paragraph concerning tutoringand fully defined, keep it up all the time. Gianina Carroll Placidia
Hi mates, how is everything, and what you want to say on the topic of this piece of writing, in my view its in fact remarkable in favor of me. Haley Esra Rizzo
Some truly quality articles on this site, saved to my bookmarks . Reiko Kristoffer Pandich
I just like the valuable info you supply in your articles. Zorana Manuel Kramlich
There is apparently a lot to identify about this. I think you made some good points in features also. Lynnette Merrill Erie
I enjoyed reading this. You appear to know a lot about this. Thanks for writing this. I really like your article. Noellyn Elihu Rutherford
It has the same meaning either way. You quarrel endlessly. I feel sorry for God for having to put up with you. Lillis Krishna Docila
The facts mentioned in the article are a few of the most effective readily available. Sydney Hebert Emelina
Im thankful for the blog article.Thanks Again. Awesome.
I really love your site.. Excellent colors & theme.
Did you create this website yourself? Please reply back as
I’m wanting to create my own personal blog and would love to know where you got this from or exactly what the theme is called.
Appreciate it!
Hello. impressive job. I did not imagine this. This is a excellent story. Thanks!
very good publish, i actually love this web site, carry on it