zoukankan      html  css  js  c++  java
  • SpringMVC 异常处理

    Using HTTP Status Codes

    在我们自定义的异常上使用ResponseStatus注解。当我们的Controller抛出异常,并且没有被处理的时候,他将返回HTTP STATUS 为指定值的 HTTP RESPONSE,比如:

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

    这时候会返回404,转到404页面而不是错误页面

    Controller Based Exception Handling

    在一个Controller中,通过增加使用注解@ExceptionHandler的方法来处理@RequestMapping方法抛出的异常,注意这种只在单个Controller中有效。这么做可以:

    1. 发生异常后,改变Response status,一般而言,发生异常返回HTTP STATUS 500.我们可以变为其他。
    2. 发生错误后转到错误页面
    3. 可以为不同异常定义不同处理(如不同的错误页面,不同的Response status)

    举例说明

    @Controller
    public class ExceptionHandlingController {
    
      // 我们标注了@RequestMapping的方法
      ...
      
      //处理异常的方法。
      
      // 把我们定义的异常转换为特定的Http status code
      @ResponseStatus(value=HttpStatus.CONFLICT, reason="Data integrity violation")  // 409
      @ExceptionHandler(DataIntegrityViolationException.class)
      public void conflict() {
        // Nothing to do
      }
      
    
      // 捕获到SQLException,DataAccessException异常之后,转到特定的页面。
      @ExceptionHandler({SQLException.class,DataAccessException.class})
      public String databaseError() {
        //仅仅转到错误页面,我们在页面上得不到这个Exception的值,要得到值,我们可以通过下面的方法得到
        return "databaseError";
      }
    
      // 通过ModelAndView返回页面,以及往页面传相应的值
      @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;
      }
    }
    

    Global Exception Handling

    在类上使用 @ControllerAdvice注解,可以使得我们处理整个程序中抛出的异常。然后在类中的方法上使用@ExceptionHandler来定义处理不同的异常。
    举例:

    class GlobalControllerExceptionHandler {
        @ResponseStatus(HttpStatus.CONFLICT)  // 409
        @ExceptionHandler(DataIntegrityViolationException.class)
        public void handleConflict() {
            // Nothing to do
        }
        
       //转到特定页面 。。。。。
    }
    

    如果我们要处理程序中所有的异常可以这么做:

    
    @ControllerAdvice
    class GlobalDefaultExceptionHandler {
        public static final String DEFAULT_ERROR_VIEW = "error";
    
        @ExceptionHandler(value = Exception.class)
        public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
            // If the exception is annotated with @ResponseStatus rethrow it and let
            // the framework handle it - like the OrderNotFoundException example
            // at the start of this post.
            // AnnotationUtils is a Spring Framework utility class.
            if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
                throw e;
            }
            // Otherwise setup and send the user to a default error-view.
            ModelAndView mav = new ModelAndView();
            mav.addObject("exception", e);
            mav.addObject("url", req.getRequestURL());
            mav.setViewName(DEFAULT_ERROR_VIEW);
            return mav;
        }
    }
    

    Going Deeper

    实现HandlerExceptionResolver接口,SpringMvc可以使用他来处理Controller中抛出的异常

    public interface HandlerExceptionResolver {
        ModelAndView resolveException(HttpServletRequest request, 
                HttpServletResponse response, Object handler, Exception ex);
    }
    

    SpringMvc使用三种默认的HandlerExceptionResolver来处理我们的异常

    1. ExceptionHandlerExceptionResolver:处理匹配@ExceptionHandler定义的异常。
    2. ResponseStatusExceptionResolver: 处理添加@ResponseStatus注解的异常
    3. DefaultHandlerExceptionResolver:把Spring定义的一些标准异常,转换为HTTP STATUS CODE.

    Spring内置的SimpleMappingExceptionResolver实现了HandlerExceptionResolver接口,也是我们经常使用的,XML配置如下:

    <bean id="simpleMappingExceptionResolver"
              class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <map>
                    <!-- key为异常类型,value为要转到的页面 -->
                    <entry key="DatabaseException" value="databaseError"/>
                    <entry key="InvalidCreditCardException" value="creditCardError"/>
                </map>
            </property>
            <!-- 默认的异常页面 -->
            <property name="defaultErrorView" value="error"/>
            <!-- 在页面我们可以通过ex拿到异常信息 -->
            <property name="exceptionAttribute" value="ex"/>
            
            <!-- Name of logger to use to log exceptions. Unset by default, so logging disabled -->
             <!-- log异常信息,默认不设置-不记录异常信息 -->
            <property name="warnLogCategory" value="example.MvcLogger"/>
        </bean>
    
  • 相关阅读:
    二分图最大匹配的K&#246;nig定理及其证明
    HDOJ 2389 Rain on your Parade
    HDOJ 1083 Courses
    HDOJ 2063 过山车
    POJ 1469 COURSES
    UESTC 1817 Complete Building the Houses
    POJ 3464 ACM Computer Factory
    POJ 1459 Power Network
    HDOJ 1532 Drainage Ditches
    HDU 1017 A Mathematical Curiosity
  • 原文地址:https://www.cnblogs.com/hupengcool/p/4586910.html
Copyright © 2011-2022 走看看