Reputation: 62632
I have two types of controllers in my spring application.
Both the API and View controllers are part of the same spring dispatcher servlet. Spring 3.2 introduced the @ControllerAdvice
annotation to allow for a global location to handle exception.
The documentation implies that @ControllerAdvice
will be applied to every controller associated with a Dispatcher Servlet.
Is there a way to configure which controllers @ControllerAdvice
will apply to?
For example in my scenario I want a @ControllerAdvice
for my View Controllers and separate @ControllerAdvice
for my API controllers.
Upvotes: 13
Views: 15307
Reputation: 12938
UPDATE
I am using spring 4. You can do one of 2 below options.
(1) You can add the packages you want. (Inside those packages you have controllers that you want to follow @ControllerAdvice
).
Ex:
@ControllerAdvice(basePackages={"my.pkg.a", "my.pkg.b"})
(2) You can directly add the controller classes you want.
Ex:
@ControllerAdvice(basePackageClasses={MyControllerA.class, MyControllerB.class})
Upvotes: 8
Reputation: 1316
For people that will still find this question:
As from Spring 4 ControlerAdvice's can be limited to Controler's with the specified annotations. Take a look at:
http://blog.codeleak.pl/2013/11/controlleradvice-improvements-in-spring.html
(second half of this article) for more details.
Upvotes: 8
Reputation: 25421
Your exceptions should not dictate the content-type of your response. Instead check the request's Accept
header for what the browser expects.
@ExceptionHandler(Throwable.class)
public @ResponseBody String handleThrowable(HttpServletRequest request, HttpServletResponse response, Throwable ex) throws IOException {
...
String header = request.getHeader("Accept");
if(supportsJsonResponse(header)) {
//return response as JSON
response.setContentType(JSON_MEDIA_TYPE.toString());
return Json.stringify(responseMap);
} else {
//return as HTML
response.setContentType("text/html");
}
Upvotes: 3
Reputation: 330
@ExceptionHandler(value=Exception.class)
public ModelAndView error(Exception ex) {
return new ModelAndView("redirect:/error/m");
}
...//ErrorController
@RequestMapping(value = "/m", produces="text/html")
public ModelAndView error()...
@RequestMapping(value = "/m", produces="application/json")
@ResponseBody
public Map errorJson()...
Upvotes: 1
Reputation: 9295
I do not think this is possible now. If you can make the API and View controllers throw different Exception types, then you could define two different @ExceptionHandlers and achieve what you want.
// For handling API Exceptions
@ExceptionHandler(APIException.class) // Single API Exception
@ExceptionHandler({APIException.class, ..., ,,,}) // Multiple API Exceptions
// For handling View Exceptions
@ExceptionHandler(ViewException.class) // Single View Exception
@ExceptionHandler({ViewException.class, ..., ...}) // Multiple View Exceptions
You could use aop to translate the Exceptions coming out of APIs to a standard APIException. See this thread on spring forums.
Hope it helps.
Upvotes: 3