如何配置将应用Spring @ControllerAdvice的控制器?

时间:2013-01-26 23:12:23

标签: spring spring-mvc spring-3

我的spring应用程序中有两种类型的控制器。

  • 查看转发到视图以生成HTML的控制器
  • 直接从控制器返回JSON的API控制器

API和View控制器都是同一个Spring调度程序servlet的一部分。 Spring 3.2引入了@ControllerAdvice注释,以允许全局位置处理异常。

文档暗示@ControllerAdvice将应用于与Dispatcher Servlet关联的每个控制器。

有没有办法配置哪些控制器@ControllerAdvice适用?

例如,在我的场景中,我希望我的视图控制器使用@ControllerAdvice,并为我的API控制器分隔@ControllerAdvice

5 个答案:

答案 0 :(得分:6)

对于仍会发现此问题的人:

从Spring 4开始,ControlerAdvice可以限制为带有指定注释的Controler。看看:

http://blog.codeleak.pl/2013/11/controlleradvice-improvements-in-spring.html

(本文的后半部分)了解更多详情。

答案 1 :(得分:3)

我认为现在不可能。如果你可以让API和View控制器抛出不同的Exception类型,那么你可以定义两个不同的@ExceptionHandler并实现你想要的。

// 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

您可以使用aop将来自API的异常转换为标准的APIException。请参阅此thread on spring forums

希望它有所帮助。

答案 2 :(得分:3)

您的例外不应规定您的回复的内容类型。而是检查请求的Accept标题以了解浏览器的期望。

@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");
}

答案 3 :(得分:1)

@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()...

答案 4 :(得分:1)

更新

我正在使用spring4。您可以执行以下2个选项之一。

(1)您可以添加所需的软件包。 (在这些软件包中,您有要遵循@ControllerAdvice的控制器)。

例如:

@ControllerAdvice(basePackages={"my.pkg.a", "my.pkg.b"})

(2)您可以直接添加所需的控制器类。

例如:

@ControllerAdvice(basePackageClasses={MyControllerA.class, MyControllerB.class})