美文网首页Java服务器端编程Spring Boot程序员
Spring异常处理:@ExceptionHandler 后端如

Spring异常处理:@ExceptionHandler 后端如

作者: 三汪 | 来源:发表于2017-08-21 09:53 被阅读1123次

本文由作者三汪首发于简书。


近来开始着手基于Spring Boot的Java后端开发,纠结过应该如何优雅地向前端抛异常。幸而发现Spring提供了异常处理的手段。

Spring通过@ExceptionHandler来拦截系统运行时抛出的相应异常。其有效作用域是其所处的Controller,即它声明的异常处理方法无法拦截、处理其他Controller类中抛出的异常。
但是我们还可以通过在类上使用@ControllerAdvice(控制器增强。该注解可以把其声明的类中使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有的 @RequestMapping注解的方法)声明一个拦截全局异常的@ExceptionHandler。这样做可以有效减少代码冗余。具体如何使用,应该视具体业务需求而定。

下面上代码:

ErrorInfo.java(这个类是用来返回给前端的实体)

public class ErrorInfo {
    private boolean success;
    private String msg;
    private Object errors;

    public boolean isSuccess(){
        return this.success; 
    } 
    public String getMsg() { 
        return this.msg; 
    } 
    public Object getErrors() { 
        return this.errors; 
    }


    public void setSuccess(boolean success)
    {
      this.success = success; 
    } 
    
    public void setMsg(String msg) { 
        this.msg = msg; 
    } 
    
    public void setErrors(Object errors) { 
        this.errors = errors; 
    }
}

BizException.java(BizException是我们自定义的业务异常类)

public class BizException extends Exception{

    /** 
     * @fields serialVersionUID 
     */ 
    
    private static final long serialVersionUID = -2420754730135049197L;
    private Object data;
      
    public BizException() {
        super();
    }
    
    public BizException(String message) {
        super(message);
    }

    public Object getData() {
        return this.data;
    }
    public void setData(Object data) {
        this.data = data;
    }
}

GlobalExceptionHandler.java(这个类用于处理所有Controller中抛出的BizException)

@RestController
@ControllerAdvice
public class GlobalExceptionHandler {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @ExceptionHandler({BizException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public  ErrorInfo handleBizException(BizException e){
        this.logger.info("------------全局捕获BIZ异常开始------------");
        ErrorInfo r = new ErrorInfo();
        r.setSuccess(false);
        r.setMsg(e.getMessage());
        this.logger.info("ErrorInfo==" + ToStringBuilder.reflectionToString(r));
        this.logger.info("------------全局捕获BIZ异常结束------------");
        return r;
        
    }
}

在这里,我们只声明拦截了BizException,不过,ExceptionHandler中支持声明拦截多个 Exception,只需要在花括号中增加新的声明即可。
@ResponseStatus用于设置返回给前端的Http状态码,个人建议设置成BAD_REQUEST,即400。

当我们不需要全局拦截异常的时候,我们可以这样写:
AssociationController .java(普通Controller类)

@RestController
public class AssociationController {
    
    private final Logger logger = LoggerFactory.getLogger(getClass());
    
    @Autowired
    IStudentService studentService;
    
    //其余方法略...

    @RequestMapping(value = "/student/get" , method = RequestMethod.GET)
    public Student getStudent(@RequestParam(value="name",required=false)String name) throws BizException{
        Student student = null;
        if (name != null) {
            if (name.equals("Chaves")) {
                throw new BizException("Chaves is invalid!");
            }
            student = studentService.findByName(name);
        }
        return student;     
    }
    
    @ExceptionHandler({BizException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public  ErrorInfo handleBizException(BizException e){
        this.logger.info("------------当前类AssociationController捕获BIZ异常开始------------");
        ErrorInfo r = new ErrorInfo();
        r.setSuccess(false);
        r.setMsg(e.getMessage());
        this.logger.info("ErrorInfo==" + ToStringBuilder.reflectionToString(r));
        this.logger.info("------------当前类AssociationController捕获BIZ异常结束------------");
        return r;
    }
        
}

此时,该ExcetionHandler只能拦截当前类中产生的BizException。


以上。
希望我的文章对你能有所帮助。
我不能保证文中所有说法的百分百正确,但我能保证它们都是我的理解和感悟以及拒绝复制黏贴。
有什么意见、见解或疑惑,欢迎留言讨论。

相关文章

网友评论

    本文标题:Spring异常处理:@ExceptionHandler 后端如

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