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);
            }
        }
    }
    

      

     

  • 相关阅读:
    21.Merge Two Sorted Lists 、23. Merge k Sorted Lists
    34. Find First and Last Position of Element in Sorted Array
    leetcode 20. Valid Parentheses 、32. Longest Valid Parentheses 、301. Remove Invalid Parentheses
    31. Next Permutation
    17. Letter Combinations of a Phone Number
    android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
    oc 异常处理
    oc 类型判断
    oc Delegate
    oc 协议
  • 原文地址:https://www.cnblogs.com/yanxiaoge/p/11285869.html
Copyright © 2011-2022 走看看