Spring MVC中异常处理惩罚的类体系布局
下图中,我画出了Spring MVC中,跟异常处理惩罚相关的主要类和接口。
在Spring MVC中,所有用于处理惩罚在请求映射和请求处理惩罚进程中抛出的异常的类,软件开发,都要实现HandlerExceptionResolver接口。AbstractHandlerExceptionResolver实现该接口和Orderd接口,是HandlerExceptionResolver类的实现的基类。ResponseStatusExceptionResolver等详细的异常处理惩罚类均在AbstractHandlerExceptionResolver之上,实现了详细的异常处理惩罚方法。一个基于Spring MVC的Web应用措施中,可以存在多个实现了HandlerExceptionResolver的异常处理惩罚类,他们的执行顺序,由其order属性抉择, order值越小,越是优先执行, 在执行到第一个返回不是null的ModelAndView的Resolver时,不再执行后续的尚未执行的Resolver的异常处理惩罚要领。。
下面我逐个先容一下SpringMVC提供的这些异常处理惩罚类的成果。
DefaultHandlerExceptionResolver
HandlerExceptionResolver接口的默认实现,根基上是Spring MVC内部利用,用来处理惩罚Spring界说的各类尺度异常,将其转化为相对应的HTTP Status Code。其处理惩罚的异常范例有:
handleNoSuchRequestHandlingMethod handleHttpRequestMethodNotSupported handleHttpMediaTypeNotSupported handleMissingServletRequestParameter handleServletRequestBindingException handleTypeMismatch handleHttpMessageNotReadable handleHttpMessageNotWritable handleMethodArgumentNotValidException handleMissingServletRequestParameter handleMissingServletRequestPartException handleBindException
ResponseStatusExceptionResolver
用来支持ResponseStatus的利用,处理惩罚利用了ResponseStatus注解的异常,按照注解的内容,返回相应的HTTP Status Code和内容给客户端。假如Web应用措施中设置了ResponseStatusExceptionResolver,那么我们就可以利用ResponseStatus注解来注解我们本身编写的异常类,并在Controller中抛出该异常类,之后ResponseStatusExceptionResolver就会自动帮我们处理惩罚剩下的事情。
这是一个本身编写的异常,用来暗示订单不存在:
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No such Order") // 404 public class OrderNotFoundException extends RuntimeException { // ... }
这是一个利用该异常的Controller要领:
@RequestMapping(value="/orders/{id}", method=GET) public String showOrder(@PathVariable("id") long id, Model model) { Order order = orderRepository.findOrderById(id); if (order == null) throw new OrderNotFoundException(id); model.addAttribute(order); return "orderDetail"; }
这样,当OrderNotFoundException被抛出时,ResponseStatusExceptionResolver会返回给客户端一个HTTP Status Code为404的响应。
AnnotationMethodHandlerExceptionResolver和ExceptionHandlerExceptionResolver
用来支持ExceptionHandler注解,利用被ExceptionHandler注解所标志的要领来处理惩罚异常。个中AnnotationMethodHandlerExceptionResolver在3.0版本中开始提供,ExceptionHandlerExceptionResolver在3.1版本中开始提供,从3.2版本开始,Spring推荐利用ExceptionHandlerExceptionResolver。
假如设置了AnnotationMethodHandlerExceptionResolver和ExceptionHandlerExceptionResolver这两个异常处理惩罚bean之一,那么我们就可以利用ExceptionHandler注解来处理惩罚异常。
下面是几个ExceptionHandler注解的利用例子:
@Controller public class ExceptionHandlingController { // @RequestHandler methods ... // 以下是异常处理惩罚要领 // 将DataIntegrityViolationException转化为Http Status Code为409的响应 @ResponseStatus(value=HttpStatus.CONFLICT, reason="Data integrity violation") // 409 @ExceptionHandler(DataIntegrityViolationException.class) public void conflict() { // Nothing to do } // 针对SQLException和DataAccessException返回视图databaseError @ExceptionHandler({SQLException.class,DataAccessException.class}) public String databaseError() { // Nothing to do. Returns the logical view name of an error page, passed to // the view-resolver(s) in usual way. // Note that the exception is _not_ available to this view (it is not added to // the model) but see "Extending ExceptionHandlerExceptionResolver" below. return "databaseError"; } // 建设ModleAndView,将异常和请求的信息放入到Model中,指定视图名字,图纸加密,并返回该ModleAndView @ExceptionHandler(Exception.class) public ModelAndView handleError(HttpServletRequest req, Exception exception) { logger.error("Request: " + req.getRequestURL() + " raised " + exception); ModelAndView mav = new ModelAndView(); mav.addObject("exception", exception); mav.addObject("url", req.getRequestURL()); mav.setViewName("error"); return mav; } }