springmvc异常处理机制

        在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一,  也实现了异常信息的统一处理和维护 。

  系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。

Spring/SpringMVC常见的统一异常处方式:

  1) 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver,处理器实现HandlerExceptionResolver 接口,全局异常处理器需要实现该接口

  SimpleMappingExceptionResolver,就是通过简单的映射关系来决定由哪个视图,来处理当前的错误信息。SimpleMappingExceptionResolver提供通过异常类型exceptionMappings,来进行异常与视图之间的映射关系,提供在发生异常时,通过statusCodes来映射异常返回的视图名称和对应的HttpServletResponse的返回码。而且可以通过defaultErrorView和defaultErrorCode来指定默认值,defaultErrorView表示当没有在exceptionMappings里面找到对应的异常类型时,就返回defaultErrorView定义的视图,defaultErrorCode表示在发生异常时,当没有在视图与返回码的映射关系statusCodes里面找到对应的映射时,默认返回的返回码。

  在使用SimpleMappingExceptionResolver时,当发生异常的时候,SimpleMappingExceptionResolver将会把当前的异常对象放到自身属性exceptionAttribute中,当没有指定exceptionAttribute时,exceptionAttribute就是用默认值exception

    首先得在webApplicationContext.xml文件中配置该处理器:

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
          <!--默认的异常处理页面-->
          <property name="defaultErrorView" value="user/error"/>      //错误页面的路径:如果配置modelView.addView("/WEB-INF/views"),就是相对路径
          <!--异常处理页面用来获取异常信息的变量名,默认为exception-->
          <property name="exceptionAttribute" value="ex"/>
          <!--需要特殊处理的异常信息-->
          <property name="exceptionMappings">
               <props>
                    <prop key="com.smart.exception.CustomException">user/custom_error</prop>
               </props>
          </property>
     
<property name="statusCodes"> <!-- 定义在发生异常时视图跟返回码的对应关系 -->  
<props>  
  <prop key="number">500</prop> <!-- 表示在发生NumberFormatException时返回视图number,
然后这里定义发生异常时视图number对应的HttpServletResponse的返回码是500 --> 
<prop key="null">503</prop>
  
</props>
  
</property
     </bean>

  最重要的是要配置特殊处理的异常,自定义一个CustomException

package com.smart.exception;

/**
 * 自定义异常
 * **/
public class CustomException  extends Exception{

    private String message;

    public CustomException(String message){
        super(message);
        this.message=message;
    }
    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

  2) 实现Spring的异常处理接口HandlerExceptionResolver 自定义全局异常处理器

     全局异常处理器处理思路

  1. 解析出异常类型
  2. 如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示
  3. 如果该异常类型不是系统自定义的异常,构造一个自定义的异常类型

    springmvc提供一个HandlerExceptionResolver接口,自定义全局异常处理器必须要实现这个接口

public class CustomExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        ModelAndView modelAndView = new ModelAndView();
        if(ex instanceof CustomException){
            CustomException exception=(CustomException)ex;
            modelAndView.addObject("message",exception.getMessage());
            modelAndView.setViewName("user/custom_error");
            return modelAndView;
        }else{
            modelAndView.addObject("message",ex.getMessage());
            modelAndView.setViewName("user/error");
            return modelAndView;
        }
    }
}

    在springmvc.xml中配置这个自定义的异常处理器:

<!-- 自定义的全局异常处理器 
只要实现HandlerExceptionResolver接口就是全局异常处理器-->
<bean class="com.smart.CustomExceptionResolver"></bean> 

3) 使用@ExceptionHandler注解实现异常处理

          处理局部异常(Controller内)

    @ExceptionHandler
    public ModelAndView exceptionHandler(Exception ex){
        ModelAndView mv = new ModelAndView("error");
        mv.addObject("exception", ex);
        System.out.println("in testExceptionHandler");
        return mv;
    }
    
    @RequestMapping("/error")
    public String error(){
        int i = 5/0;
        return "hello";
    }

  4) 定义一个类并配上注解@ControllerAdvice。然后再该类中定义处理异常的方法并使用注解@ExceptionHandler

    处理全局异常(所有Controller)

//全局异常处理,捕获所有Controller中抛出的异常
@ControllerAdvice
public class testControllerAdvice {
//自定义异常 @ExceptionHandler(CustomException.class)
public ModelAndView exceptionHandler(Exception ex){ ModelAndView mv = new ModelAndView("error"); mv.addObject("exception", ex); System.out.println("in testControllerAdvice"); return mv; }

@ExceptionHandler(Exception.class)
@ResponseBody
public Object exceptionHandler(Exception e){
,,,,
} }

      

参考:

 https://blog.csdn.net/eson_15/article/details/51731567

 

posted on 2018-11-07 12:20  溪水静幽  阅读(1397)  评论(0编辑  收藏  举报