Spring-mvc 控制器和异常处理

8

我想问一个关于spring-mvc控制器的最佳实践问题。请查看下面的代码:

    @Autowired
    SomeService service;

    @RequestMapping (...)
    public @ResponseBody Response createSomething () {

       try {

            serviceResponse = service.doSomething();

            //create a success response and return

       }
       catch (SomeServiceException e) {
             //create an error response and return 
       }

}

控制器级别的错误处理是常规做法吗?或者服务类不应该像上面那样抛出异常。请审核并告知。
5个回答

7
我认为根据您的使用情况,有三种策略可供选择。
大致有三种策略:HandlerExceptionResolver、@ExceptionHandler 以及在操作内部处理异常。
这些的应用场景为:为整个应用程序提供通用异常处理程序,为整个控制器提供异常处理程序,或者相应地为特定操作提供异常处理程序。

所有这些处理程序都仅与Spring MVC相关,对吗?我的意思是,我能否处理来自过滤器或控制器范围之外的任何意外异常?因为根据文档所述,Spring HandlerExceptionResolver 实现处理在控制器执行期间发生的意外异常,即在控制器执行期间。 - Aman Gupta
我正在使用Spring Boot和Spring Cloud,其中进行智能路由。因此没有涉及Spring MVC。处理全局级别异常的最佳方法是什么?基于AOP的解决方案? - Aman Gupta

2

我认为最佳做法是使用@ExceptionHandler。在控制器方法中处理异常的缺点是会使代码不够易读,并且可能在许多控制器方法中重复。

我建议您为您的控制器创建一个基类,并定义@ExceptionHandler。这样它就可以用于许多不同的控制器,而没有任何代码重复。这比异常解析器方法更容易阅读,但可以与之结合使用。


1

服务类可以/应该抛出异常。您可以在控制器中处理这些异常以进行日志记录。还可以根据控制器捕获的异常显示适当的错误页面。但是这将很繁琐。最好尝试使用Spring异常处理。http://www.mkyong.com/spring-mvc/spring-mvc-exception-handling-example/


Rajesh:我从这个控制器中没有返回视图。我返回的是json/ResponseBody,因此我没有错误页面可以显示。不过,我喜欢你使用@ExceptionHandler的建议,而不是使用try和catch块。那样行得通吗?谢谢你,感谢你的回复。 - Khush
Khush,你可以在控制器中捕获异常并发送适当的错误消息作为JSON结果,并相应地在屏幕上显示。这在某些小情况下已经完成了。但是还要引入此异常处理程序,在ajax的情况下,您将获得errorpage.html作为ajax响应。然后,您可以在屏幕上的div或iframe上更新此页面。如果您喜欢这个答案,请投票给我,这样我就可以得到一些积分 :) - Rajesh

0

在Bean定义文件中为Handler类定义Bean。 当程序抛出任何异常时,将调用resolveException方法。

  public class Handler
        implements HandlerExceptionResolver
    {

        public Handler()
        {
        }

        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        {
            if(ex instanceof ErrorType1Exception))
            {
                 ModelAndView test = new ModelAndView("errorpage1jsppage");
return test;
            } else
            if(ex instanceof ErrorType2Exception))
            {
                 ModelAndView test1 = new ModelAndView("errorpage2jsppage");
return test1
            }
        }
    }

0
在处理异常方面的一个好习惯是尽早抛出异常,尽晚捕获异常。在您的情况下,这意味着在控制器而不是服务中捕获错误。优势在于您可以根据客户端请求(SOAP/REST/JSON...)编写不同的控制器,以便针对不同的异常进行不同的处理。但如果该逻辑位于服务中,则无法灵活地处理从服务返回的响应,以响应不同的客户端。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接