SpringMVC(7)------ 异常处理

异常处理

异常处理器

SpringMVC(7)------ 异常处理

SpringMVC(7)------ 异常处理

异常分类管理

SpringMVC(7)------ 异常处理

代码

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component//将这句话注释掉,这个异常处理器就不能使用了
public class ExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object handler,
                                         Exception ex) {
        System.out.println("my exception is running ...."+ex);
        ModelAndView modelAndView = new ModelAndView();
        if( ex instanceof NullPointerException){
            modelAndView.addObject("msg","空指针异常");
        }else if ( ex instanceof  ArithmeticException){
            modelAndView.addObject("msg","算数运算异常");
        }else{
            modelAndView.addObject("msg","未知的异常");
        }
        modelAndView.setViewName("error.jsp");
        return modelAndView;
    }
}

注解实现异常处理

SpringMVC(7)------ 异常处理

  • 代码:

    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Component
    //使用注解开发异常处理器
    //声明该类是一个Controller的通知类,声明后该类就会被加载成异常处理器
    @ControllerAdvice//如果将这句话注释掉,这个异常处理器就不能使用了
    public class ExceptionAdvice {
    
        //类中定义的方法携带@ExceptionHandler注解的会被作为异常处理器,后面添加实际处理的异常类型
        @ExceptionHandler(NullPointerException.class)//处理空指针异常
        @ResponseBody//如果不写ResponseBody,它就会去找return的页面,添加过后便不会解析成页面
        public String doNullException(Exception ex){
            return "空指针异常";
        }
    
        @ExceptionHandler(ArithmeticException.class)//处理算术异常
        @ResponseBody
        public String doArithmeticException(Exception ex){
            return "ArithmeticException";
        }
    
        @ExceptionHandler(Exception.class)//处理全部的异常
        @ResponseBody
        public String doException(Exception ex){
            return "all";
        }
    
    }
    

两种异常处理方式对比

注解处理器可以拦截到入参类型转换异常:简单来说就是处理的时间比较早,是在参数转换到controller里面之前加载

非注解处理器无法拦截到入参类型转换异常:这个是在后面加载,二者工作时机不同,这个比较晚

项目异常处理方案(理解)

异常分类

  • 业务异常:用户这么做的

    • 规范的用户行为产生的异常:比如输入年龄,用户输入-1
    • 不规范的用户行为操作产生的异常:比如用户通过某种偶然的方式知道了公司里面财务审批的url地址,直接在地址栏输入敲回车过去了,然后把钱给批了钱领了
  • 系统异常:

    • 项目运行过程中可预计且无法避免的异常:比如连接超时,网络特别慢,特别卡
  • 其他异常:

    • 编程人员未预期到的异常:程序员写的代码有误,不可预料

异常处理方案

  • 业务异常:

    • 发送对应消息传递给用户,提醒规范操作
  • 系统异常:

    • 发送固定消息传递给用户,安抚用户
    • 发送特定消息给运维人员,提醒维护
    • 记录日志
  • 其他异常:

    • 发送固定消息传递给用户,安抚用户
    • 发送特定消息给编程人员,提醒维护
      • 纳入预期范围内
    • 记录日志

自定义异常

SpringMVC(7)------ 异常处理

  • 测试代码

    • 自定义异常类

      • BusinessException.java

        //自定义异常继承RuntimeException,覆盖父类所有的构造方法
        public class BusinessException extends RuntimeException {
            public BusinessException() {
            }
        
            public BusinessException(String message) {
                super(message);
            }
        
            public BusinessException(String message, Throwable cause) {
                super(message, cause);
            }
        
            public BusinessException(Throwable cause) {
                super(cause);
            }
        
            public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
                super(message, cause, enableSuppression, writableStackTrace);
            }
        }
        
        
      • SystemException.java系统异常

        //自定义异常继承RuntimeException,覆盖父类所有的构造方法
        public class SystemException extends RuntimeException {
            public SystemException() {
            }
        
            public SystemException(String message) {
                super(message);
            }
        
            public SystemException(String message, Throwable cause) {
                super(message, cause);
            }
        
            public SystemException(Throwable cause) {
                super(cause);
            }
        
            public SystemException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
                super(message, cause, enableSuppression, writableStackTrace);
            }
        }
        
    • ajax异步请求

      <%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
      
      <a href="javascript:void(0);" id="testException">访问springmvc后台controller,传递Json格式POJO</a><br/>
      
      <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.3.1.min.js"></script>
      
      <script type="text/javascript">
          $(function () {
              $("#testException").click(function(){
                  $.ajax({
                      contentType:"application/json",
                      type:"POST",
                      url:"save",
                      /*通过修改参数,激活自定义异常的出现*/
                      // name长度低于8位出现业务异常
                      // age小于0出现业务异常
                      // age大于100出现系统异常
                      // age类型如果无法匹配将转入其他类别异常
                      data:'{"name":"Jock","age":"111"}',
                      dataType:"text",
                      //回调函数
                      success:function(data){
                          alert(data);
                      }
                  });
              });
          });
      </script>
      
    • error.jsp出错跳转的页面

      <%--异常消息展示页面--%>
      <%@page pageEncoding="UTF-8" language="java" contentType="text/html;UTF-8" %>
      ${msg}
      
    • UserController.java

      import com.itheima.domain.User;
      import com.itheima.exception.BusinessException;
      import com.itheima.exception.SystemException;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      import java.util.ArrayList;
      import java.util.List;
      
      @Controller
      public class UserController {
          @RequestMapping("/save")
          @ResponseBody
          public List<User> save(@RequestBody User user) {
              System.out.println("user controller save is running ...");
      
              //模拟业务层发起调用产生了异常
      //        int i = 1/0;
      //        String str = null;
      //        str.length();
      
              //对用户的非法操作进行判定,并包装成异常对象进行处理,便于统一管理
              if(user.getName().trim().length() < 8){
                  throw new BusinessException("对不起,用户名长度不满足要求,请重新输入!");
              }
              if(user.getAge() < 0){
                  throw new BusinessException("对不起,年龄必须是0到100之间的数字!");
              }
              if(user.getAge() > 100){
                  throw  new SystemException("服务器连接失败,请尽快检查处理!");
              }
      
      
              User u1 = new User();
              u1.setName("Tom");
              u1.setAge(3);
              User u2 = new User();
              u2.setName("Jerry");
              u2.setAge(5);
              ArrayList<User> al = new ArrayList<User>();
              al.add(u1);
              al.add(u2);
      
              return al;
          }
      }
      
      
    • 异常处理器ProjectExceptionAdvice.java

      import org.springframework.stereotype.Component;
      import org.springframework.ui.Model;
      import org.springframework.web.bind.annotation.ControllerAdvice;
      import org.springframework.web.bind.annotation.ExceptionHandler;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      @Component
      @ControllerAdvice
      public class ProjectExceptionAdvice {
      
          @ExceptionHandler(BusinessException.class)
          public String doBusinessException(Exception ex, Model m){
              //使用参数Model将要保存的数据传递到页面上,功能等同于ModelAndView
              //业务异常出现的消息要发送给用户查看
              m.addAttribute("msg",ex.getMessage());
              return "error.jsp";
          }
      
          @ExceptionHandler(SystemException.class)
          public String doSystemException(Exception ex, Model m){
              //系统异常出现的消息不要发送给用户查看,发送统一的信息给用户看
              m.addAttribute("msg","服务器出现问题,请联系管理员!");
              //实际的问题现象应该传递给redis服务器,运维人员通过后台系统查看
              //实际的问题显现更应该传递给redis服务器,运维人员通过后台系统查看
              return "error.jsp";
          }
      
          @ExceptionHandler(Exception.class)
          public String doException(Exception ex, Model m){
              m.addAttribute("msg",ex.getMessage());
              //将ex对象保存起来
              return "error.jsp";
          }
      
      }
      
上一篇:springboot项目自启动浏览器网页


下一篇:只允许在input框输入文字,不能输入数字和其他字符