Spring MVC----spring MVC 异常处理

出现异常后,跳转指定的页面

不配置spirng-MVC.xml

Controller

方式1;

    //处理异常,注意入参中,不能有Model,Map等,如果需要给requestion添加对象,使用ModelAndView
    @ExceptionHandler({ArithmeticException.class})
    public ModelAndView ArithmeticException(Exception ex){
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("ex",ex);
        return modelAndView;
    }
    @RequestMapping(value = "/testexception",method = RequestMethod.GET)
    public String testexception(){
        int a = 1/0;
        return "login";
    }

方式2: 

我们重新创建一个类(类名无关),将上面处理异常的方法放进去;

@ControllerAdvice
public class HandleException {
    @ExceptionHandler({ArithmeticException.class}) //捕获指定的异常
    public ModelAndView ArithmeticException(Exception ex){
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("ex",ex);
        return modelAndView;
    }
}

配置spirng-MVC.xml

controller不需要在写异常处理的方法了。

    <!--key:需要些错误的全限定路径-->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!--配置异常的名字-->
        <property name="exceptionAttribute" value="ex"></property>
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.ArithmeticException">error</prop>
            </props>
        </property>
    </bean>

 

@ResponseStatus注解

1、如果这个注解放在的方法上:直接放回一个错误页面

    @ResponseStatus(reason = "测试",value = HttpStatus.NOT_FOUND)
    @RequestMapping(value = "/testexception",method = RequestMethod.GET)
    public String testexception(){
        return "login";
    }

1、注解类

定义一个错误的类

@ResponseStatus(reason = "错误消息",value = HttpStatus.BAD_REQUEST)
public class MyException extends Exception{
    public MyException(){
        super();
    }
    public MyException(String message){
        super(message);
    }
}

controller

    @RequestMapping(value = "/testexception",method = RequestMethod.GET)
    public String testexception() throws MyException {
        if (true){
            MyException myException = new MyException();
            throw myException;
        }
        return "login";
    }

 

 

 

 

编写统一处理异常类

可预知异常处理(由程序员自己抛出的异常)

  1、编写一个错误类继承RunTimeException,不继承Exception的原因是,在代码中手动抛出RunTimeException异常,在代码中不需要进行try...cache等

public class CustomException extends RuntimeException {

    //错误代码信息(自己定义)
    ResultCode resultCode;

    public CustomException(ResultCode resultCode){
        this.resultCode = resultCode;
    }
    public ResultCode getResultCode(){
        return resultCode;
    }
}

 

  2、service层抛出异常

        if(cmsPage1!=null){
            //页面已经存在
            //抛出异常,异常内容就是页面已经存在
            throw new CustomException(CmsCode.CMS_ADDPAGE_EXISTSNAME);
        }

  3、编写捕获异常类

@ControllerAdvice//控制器增强
public class ExceptionCatch {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);

    //捕获CustomException此类异常
    @ResponseBody //返回给前端json数据
    @ExceptionHandler(CustomException.class) //捕获相应的错误类
    public ResponseResult customException(CustomException customException){
        //记录日志
        LOGGER.error("catch exception:{}",customException.getMessage());
        //获取错误码(自定义的)
        ResultCode resultCode = customException.getResultCode();
        return new ResponseResult(resultCode);
    }
}    

  4、springboot配置(由于我们的捕获类写在了common模块中,所以spring boot启动的时候,需要扫描这个模块)

@SpringBootApplication
@EntityScan("com.xuecheng.framework.domain.cms")//扫描实体类
@ComponentScan(basePackages={"com.xuecheng.framework"}) //扫描common模块
public class ManageCmsApplication {
    public static void main(String[] args) {
        SpringApplication.run(ManageCmsApplication.class,args);
    }
}

  

不可预知异常处理(由框架自己抛出)

  1、对捕获异常类进行扩展

  总结:捕获Exception异常(所有的异常),如果该异常在map中有对应的错误码(我们提前将可能出现的异常用map存储起来),返回该错误码

@ControllerAdvice//控制器增强
public class ExceptionCatch {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);

    //定义map,配置异常类型所对应的错误代码
    private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
    //定义map的builder对象,去构建ImmutableMap(ImmutableMap的使用需要定义builder对象,如果使用其他HashMap就不需要了)
    protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder();
    //提前将系统可能抛出的异常代码添加相应的错误代码块
    static {
        //定义异常类型所对应的错误代码(注意此时ImmutableMap还没有数据,需要等待build())
        builder.put(HttpMessageNotReadableException.class,CommonCode.INVALID_PARAM);
    }


    //捕获CustomException此类异常
    @ResponseBody
    @ExceptionHandler(CustomException.class)
    public ResponseResult customException(CustomException customException){
        //记录日志
        LOGGER.error("catch exception:{}",customException.getMessage());
        ResultCode resultCode = customException.getResultCode();
        return new ResponseResult(resultCode);
    }

    //捕获其他框架抛出的异常
    @ResponseBody
    @ExceptionHandler(Exception.class)
    public ResponseResult exception(Exception exception){
        //记录日志
        LOGGER.error("catch exception:{}",exception.getMessage());
        if(EXCEPTIONS == null){
            //此时,ImmutableMap构建成功,ImmutableMap有了数据,且ImmutableMap不能在被修改了(只读)
            EXCEPTIONS = builder.build(); //我们可以直接put完数据之后,直接执行build()
        }
        //从EXCEPTIONS中找异常类型所对应的错误代码,如果找到了将错误代码响应给用户,如果找不到给用户响应99999异常
        ResultCode resultCode = EXCEPTIONS.get(exception.getClass());
        if(resultCode !=null){
            return new ResponseResult(resultCode);
        }else{
            //返回99999异常
            return new ResponseResult(CommonCode.SERVER_ERROR);
        }
    }
}

  

 

 

 

 

 

 

 

 

 

posted @ 2019-08-01 22:45  小名的同学  阅读(191)  评论(0编辑  收藏  举报