Spring MVC异常处理

作者: ssttIsme | 来源:发表于2018-09-11 16:09 被阅读8次

客户端向服务端发起一个请求,请求到达了Controller,Controller方法在执行的过程中出现了异常,这个异常要处理。数据层产生的SQLException或者一些绑定的异常要处理,不能抛出,sql语句有问题项目不能上线。业务层出现异常要抛给控制层(如:转账操作的业务异常:余额不足不能转账。又如密码输入错误要告诉用户),控制层要对异常进行简单的处理,不能在页面显示500。在业务层可以写ServiceException抛给用户。控制端把异常交给@ControllerAdvice全局处理类处理。数据层的异常基本上没有处理,业务层的异常分情况:用户相关的(业务层相关的)异常要抛给控制层处理,与用户无关的要进行系统监控。与运维或呈现有关要进行报警,给运维人员发短信。
Spring MVC中异常处理机制总结:

  1. 为什么要进行异常处理?(提高系统的容错能力,让系统表现的更加友好)
  2. Spring MVC中异常处理的方式?(局部的,全局的)
  3. 局部方式异常处理如何实现?(Controller类中直接定义异常处理方法,使用@ExceptionHandler进行修饰)
  4. 全局方式异常处理如何实现?(通过继承将共性提取到父类或者
    通过@ControllerAdvice注解修饰类,然后类中定义异常处理方法)
  5. 出现异常后,异常处理的具体机制是怎样的(首先会在当前Controller(包含父类)中查找有没有定义异常处理方法,假如有则查看注解中定义的异常类型是否与当前异常类型相匹配,假如匹配则直接处理,假如不匹配则查看当前类中有没有父类类型的异常处理方法与当前异常匹配,假如有则直接处理,没有则找全局异常处理。全局也没有则直接不友好的输出错误信息)

说明:实际项目中在controller的方法中除了要对正确的业务数据进行封装之外,还会对异常信息进行封装(例如封装到JsonResult),然后转换为json格式的字符串,输出到客户端。

http://localhost/spring-mvc-v2/exp/doHandleRequest.do?a=10&b=0

package com.in.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/exp/")
public class ExceptionController {
    @RequestMapping("doHandleRequest")
    @ResponseBody
    public String doHandleRequest(Integer a,Integer b)
    {
        int result=a/b;
        return "result is "+result;
    }//此方法假如没有处理异常,此异常会抛出到客户端
    
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public String doHandleArithmeticException(ArithmeticException e){
        return "Arithmetic Exception "+e.getMessage();
        
    }
}

import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/exp/")
public class ExceptionController {
    @RequestMapping("doHandleRequest")
    @ResponseBody
    public String doHandleRequest(Integer a,Integer b)
    {
        int result=a/b;
        return "result is "+result;
    }//此方法假如没有处理异常,此异常会抛出到客户端
    
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public String doHandleArithmeticException(RuntimeException e){
        return "Arithmetic Exception "+e.getMessage();
        
    }
}

http://localhost/spring-mvc-v2/exp/doHandleRequest.do?a=10&b=0

Arithmetic Exception / by zero
package com.in.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/exp/")
public class ExceptionController {
    @RequestMapping("doHandleRequest")
    @ResponseBody
    public String doHandleRequest(Integer a,Integer b)
    {
        int result=a/b;
        return "result is "+result;
    }//此方法假如没有处理异常,此异常会抛出到客户端
    
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public String doHandleArithmeticException(ArithmeticException e){
        return "Arithmetic Exception "+e.getMessage();
        
    }
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public String doHandleArithmeticException(RuntimeException e){
        return "RuntimeException Exception "+e.getMessage();
    }
}

http://localhost/spring-mvc-v2/exp/doHandleRequest.do?a=10&b=0
就近原则

Arithmetic Exception / by zero
package com.in.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/exp/")
public class ExceptionController {
    @RequestMapping("doHandleRequest")
    @ResponseBody
    public String doHandleRequest(Integer a,Integer b)
    {
        int result=a/b;
        return "result is "+result;
    }//此方法假如没有处理异常,此异常会抛出到客户端
    
}
package com.in.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 使用此注解描述的类表示是一个全局异常处理类
 * spring底层创建
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public String doHandleArithmeticException(ArithmeticException e){
        return "Global Arithmetic Exception "+e.getMessage();
        
    }
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public String doHandleArithmeticException(RuntimeException e){
        return "Global RuntimeException Exception "+e.getMessage();
    }
}

http://localhost/spring-mvc-v2/exp/doHandleRequest.do?a=10&b=0

Global Arithmetic Exception / by zero
package com.in.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 使用此注解描述的类表示是一个全局异常处理类
 * spring底层创建
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(value={RuntimeException.class,ArithmeticException.class})
    @ResponseBody
    public String doHandleArithmeticException(RuntimeException e){
        return "Global Exception "+e.getMessage();
    }
}
Global Exception / by zero
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {

    /**
     * Exceptions handled by the annotated method. If empty, will default to any
     * exceptions listed in the method argument list.
     */
    Class<? extends Throwable>[] value() default {};

}
@ExceptionHandler(value={IllegalArgumentException.class,ClassCastException.class,IOException.class})
    @ResponseBody
    public String doHandleMultipartExctpion(Exception e){
        return "Excetption "+e.getMessage();
    }

相关文章

网友评论

    本文标题:Spring MVC异常处理

    本文链接:https://www.haomeiwen.com/subject/uuyugftx.html