zoukankan      html  css  js  c++  java
  • 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);
            }
        }
    }
    

      

     

  • 相关阅读:
    SQL面试题:有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列
    Centos下Yum安装PHP5.5
    docker 容器内服务自启动
    centos6.6系统初始化脚本
    不重启linuxVMWare虚拟机添加虚拟磁盘
    linux(centos6)搭建ftp服务器
    记一次扩容操作
    mongodb数据迁移的两种方式
    mongodb 数据库操作--备份 还原 导出 导入
    关于PHP参数的引用传递和值传递
  • 原文地址:https://www.cnblogs.com/yanxiaoge/p/11285869.html
Copyright © 2011-2022 走看看