在SpringMVC框架中统一处理异常及请求参数验证(4)

简介: 在SpringMVC框架中统一处理异常及请求参数验证(4)

8. 在SpringMVC框架中统一处理异常


在SpringMVC框架中提供了统一处理异常的机制(当然,在SpringBoot框架中也可以直接使用),使得每种异常只需要被处理1次即可,即使某种异常在多种请求中都会出现,也不需要反复处理!其核心是开发人员调用了可能抛出异常的方法时,在控制器中,直接将异常再次抛出,则SpringMVC在调用控制器的方法时,就会捕获到对应的异常对象,并且,如果开发人员定义了统一处理异常的方法,则SpringMVC框架就会自动调用该方法来处理异常!


关于统一处理异常的方法:


默认情况下,该方法只能作用于当前控制器类中的相关请求,例如,将该方法写在UserController中,只能作用了UserController 中处理的各个请求,如果在其它控制器的方法执行过程中出现了异常,是不会被处理的!关于这个问题,可选择的解决方案有2种:


将处理异常的方法写在控制器类的基类中,各控制器类都继承自该基类即可;

将处理异常的方法定义在任意类中,并在这个类的声明之前添加@ControllerAdvice或@RestControllerAdvice注解,各控制器类不需要继承自该类;

统一处理异常的方法必须添加@ExceptionHandler注解;


应该使用public权限;


返回值的类型,可参考处理请求的方法的返回值的设计原则;


方法名称可以自定义;


方法的参数列表至少需要添加异常类型的参数,用于表示被框架捕获的异常对象,关于参数的异常类型,要求能够表示任何将被处理的异常;方法的参数列表中还可以添加其它参数,但是,只能添加SpringMVC框架允许的几种参数,例如HttpServletRequest、HttpServletResponse等,不能像处理请求的方法那样随意!


可以在项目的cn.tedu.straw.portal.controller包中创建GlobalExceptionHandler类,用于统一处理异常,在类的声明之前添加@RestControllerAdvice,使得该类中处理异常的方法能作用于整个项目,并在这个类中添加方法来处理异常:

package cn.tedu.straw.portal.controller;
import cn.tedu.straw.portal.service.ex.ClassDisabledException;
import cn.tedu.straw.portal.service.ex.InsertException;
import cn.tedu.straw.portal.service.ex.InviteCodeException;
import cn.tedu.straw.portal.service.ex.PhoneDuplicateException;
import cn.tedu.straw.portal.vo.R;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler
    public R handleException(Throwable e) {
        if (e instanceof InviteCodeException) {
            return R.failure(12, e);
        } else if (e instanceof ClassDisabledException) {
            return R.failure(13, e);
        } else if (e instanceof PhoneDuplicateException) {
            return R.failure(14, e);
        } else if (e instanceof InsertException) {
            return R.failure(15, e);
        } else {
            return R.failure(9999, e);
        }
    }
}


为了便于统一管理错误代号,并增加代码的可读性,应该将这些错误代号声明为静态常量,同时,为了便于声明和管理这些静态常量,可以在R类中使用静态内部接口来声明:

package cn.tedu.straw.portal.vo;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain=true)
public class R {
    private Integer state;
    private String message;
    public static R ok() {
        return new R().setState(State.OK);
    }
    public static R failure(Integer state, String message) {
        return new R().setState(state).setMessage(message);
    }
    public static R failure(Integer state, Throwable e) {
        return failure(state, e.getMessage());
    }
    public static interface State {
        int OK = 0;
        int ERR_INVITE_CODE = 4001;
        int ERR_CLASS_DISABLED = 4002;
        int ERR_PHONE_DUPLICATE = 4003;
        int ERR_INSERT = 4004;
        int ERR_UNKNOWN = 9999;
    }
}


然后,在处理异常时,错误代号就使用这些静态常量:

package cn.tedu.straw.portal.controller;
import cn.tedu.straw.portal.service.ex.ClassDisabledException;
import cn.tedu.straw.portal.service.ex.InsertException;
import cn.tedu.straw.portal.service.ex.InviteCodeException;
import cn.tedu.straw.portal.service.ex.PhoneDuplicateException;
import cn.tedu.straw.portal.vo.R;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler
    public R handleException(Throwable e) {
        if (e instanceof InviteCodeException) {
            return R.failure(R.State.ERR_INVITE_CODE, e);
        } else if (e instanceof ClassDisabledException) {
            return R.failure(R.State.ERR_CLASS_DISABLED, e);
        } else if (e instanceof PhoneDuplicateException) {
            return R.failure(R.State.ERR_PHONE_DUPLICATE, e);
        } else if (e instanceof InsertException) {
            return R.failure(R.State.ERR_INSERT, e);
        } else {
            return R.failure(R.State.ERR_UNKNOWN, e);
        }
    }
}
目录
相关文章
|
7月前
|
前端开发 JavaScript Java
JAVAEE框架技术之4springMVC入门
JAVAEE框架技术之4springMVC入门
138 0
JAVAEE框架技术之4springMVC入门
|
7月前
|
Java 数据库连接 Maven
SSM框架整合:掌握Spring+Spring MVC+MyBatis的完美结合!
SSM框架整合:掌握Spring+Spring MVC+MyBatis的完美结合!
|
7月前
|
Java 数据库 数据安全/隐私保护
基于SSM框架实现管科类考研自我管理系统(分前后台spring+springmvc+mybatis+maven+jsp+jquery)
基于SSM框架实现管科类考研自我管理系统(分前后台spring+springmvc+mybatis+maven+jsp+jquery)
|
4月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
5月前
|
XML 前端开发 Java
深入理解SpringMVC工作原理,像大牛一样手写SpringMVC框架
对于SpringMVC相信诸位并不陌生,这是Java开发过程中使用最频繁的框架,在你的项目中可能不一定用MyBatis,但绝对会使用SpringMVC,因为操作数据库还有Hibernate、JPA等其他ORM框架选择,但SpringMVC这个框架在其领域中,可谓是独领风骚
|
7月前
|
前端开发 Java Apache
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
108 0
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
|
6月前
|
前端开发 Java 应用服务中间件
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
|
7月前
|
Java BI 数据库
基于SSM框架实现面向小微企业的简历管理系统企业简历管理系统(分前后台spring+springmvc+mybatis+maven+jsp+css+echarts)
基于SSM框架实现面向小微企业的简历管理系统企业简历管理系统(分前后台spring+springmvc+mybatis+maven+jsp+css+echarts)
|
7月前
|
前端开发 Java 关系型数据库
基于ssm框架旅游网旅游社交平台前后台管理系统(spring+springmvc+mybatis+maven+tomcat+html)
基于ssm框架旅游网旅游社交平台前后台管理系统(spring+springmvc+mybatis+maven+tomcat+html)
|
7月前
|
前端开发 Java 应用服务中间件
Spring MVC框架概述
Spring MVC 是一个基于Java的轻量级Web框架,采用MVC设计模型实现请求驱动的松耦合应用开发。框架包括DispatcherServlet、HandlerMapping、Handler、HandlerAdapter、ViewResolver核心组件。DispatcherServlet协调这些组件处理HTTP请求和响应,Controller处理业务逻辑,Model封装数据,View负责渲染。通过注解@Controller、@RequestMapping等简化开发,支持RESTful请求。Spring MVC具有清晰的角色分配、Spring框架集成、多种视图技术支持以及异常处理等优点。
90 1