当前位置: 首页 > article >正文

Spring MVC中的异常处理

引言

在Spring MVC中有两个级别的异常处理方式:

  • Controller级别: 它只能处理当前Controller类中出现的异常。
  • 全局的异常处理级别:所有的Spring MVC中的拦截机器(HandlerInterceptor),处理器(@Controller)中的异常。

当然,Spring MVC中有内置的异常处理对象,但是呈现的结果对于用户端不友好,所以实际项目我们一般会自定义异常处理。

全局异常处理对象的定义

我们可以在spring boot启动类所在的包或子包中定义Spring MVC全局异常处理类,这个类的特点是需要使用
RestControllerAdvice注解进行描述,并且可以在类中定义多个异常处理方法(需要使用@HandlerException
注解进行描述), 例如:

package cn.tedu.weibo.exception;

import cn.tedu.weibo.common.response.ResultVO;
import cn.tedu.weibo.common.response.StatusCode;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

/**
 * RestControllerAdvice 描述的类型为一个全局异常处理对象类型,
 * 当某个Controller方法中出现了异常,此时在Controller类内部,又没有定义对应的
 * 异常处理方法(使用ExcetpionHandler注解描述的方法),系统底层就会查找有没有定义全局异常处理对象。
 * 这个全局异常处理对象中有没有定义对应的异常处理方法,假如有就调用此方法处理异常。
 */

@Slf4j //lombok提供的日志注解,在代码层面会为我们提供一个org.slf4j.Logger对象
@RestControllerAdvice //=@ControllerAdvice+@ResponseBody
public class GlobalExceptionHandler {
    //private static final Logger log= LoggerFactory.getLogger(GlobalExceptionHandler.class);
    /**
     *  @ExceptionHandler 描述的方法为一个异常处理方法,在此注解内部可以定义具体的异常处理
     *  类型(例如RuntimeException.class),此注解描述的方法需要定义一个异常类型的形式参数,
     *  通过这个参数接收具体的异常对象(也可以接收其异常类型对应的子类类型的异常)。
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public ResultVO doHandleRuntimeException(RuntimeException ex){
        log.error("error is {}",ex.getMessage());//日志级别trace<debug<info<warn<error
        //log中的{}为占位符,后面的ex.getMessage()返回的信息,会显示到{}这个位置
        return new ResultVO(0,ex.getMessage());
    }
}

说明,这里的@Slf4j注解为Lombok提供,此注解描述类时会在类中创建一个日志对象,基于日志对象可以输出一些日志,
日志的级别可以在application.properties文件中进行配置,例如logging.level.cn.tedu=debug,这里的debug
表示日志级别(trace<debug<info<warn<error),当配置的日志界别为debug时,当前这个日志级别以及比这个日志级
别高的日志级别会输出日志。

Spring MVC中的参数校验

引言

在实际项目我们需要对客户端传递到服务端的参数进行校验,用于判定请求参数的合法性,假如请求参数不合法,
不可以再去执行后续的业务了。那如何校验呢?一种方式是我们在控制层方法中每次都自己进行参数有效值的判断,
不合法可以抛出异常,但是工作量和代码复杂度会比较高。第二种方式就是采用市场上主流的Spring Validation
框架去实现校验。

Spring Validation的基本应用

第一步:添加依赖

     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

第二步:通过注解对Controller类、方法参数、dto对象中的属性进行描述

对WeiboDTO中的Content属性进行NotNull标注

@Data
public class WeiboDTO {
    // 微博内容
    @NotBlank(message = "content can not be empty string") //不允许为空串
    private String content;
}

对WeiboController方法中的参数添加@Validated注解描述

    @PostMapping("insert")
    @ApiOperation(value = "发布微博功能")
    public int insert(@Validated @RequestBody WeiboDTO weiboDTO, @ApiIgnore HttpSession session){
    }

第三步:访问WeiboController中的insert方法,给content传null,检测访问效果。

POST http://localhost:8080/v1/weibo/insert
Content-Type: application/json

{
  "content": ""
}

第四步:自己做(可以通过搜索引擎自己进行拓展)-下午模拟面试结束
1)如何对验证时出现的异常进行处理。(重点)

/**
* 对参数校验异常进行处理
* @param ex
* @return
*/
@ExceptionHandler(BindException.class)
public ResultVO doBindException(BindException ex){
ObjectError objectError = ex.getBindingResult().getAllErrors().get(0);
return new ResultVO(StatusCode.VALIDATE_ERROR,
objectError.getDefaultMessage());
}

2)查Spring Validation还有那些注解可以应用。(课后了解)

@NotNull:不允许为null值
可以用于任何类型
@NotEmpty:不允许为空字符串(长度为0的字符串),并且会检查是否为null值(为null时报错)
仅能用于字符串类型的参数
@NotBlank:不允许为空白,即不允许是“仅由空格、TAB等空白值组成的字符串”
仅能用于字符串类型的参数

@Range:通过配置min和max属性来限制数值类型参数的值区间,它不会检查是否为null(为null并不执行任何检查,且不会报错)
仅能用于整型参数
@Pattern:通过配置regexp属性来配置正则表达式
仅能用于字符串类型的参数

第六步:自己做(可以通过搜索引擎自己进行拓展)-下午模拟面试结束
对于非pojo参数(例如参数列表中的int id)的检查,需要先在当前方法所在的类上添加@Validated注解,例如:

@RestController
@RequestMapping("/v1/weibo/")
@Api(tags = "02.微博模块")
@Slf4j
@Validated
public class WeiboController {

}

然后,可以在参数上添加对应的检查注解,例如:

    @GetMapping("selectById")
    @ApiOperation(value = "微博详情功能")
    @ApiImplicitParam(name="id",value = "微博id",required = true,example = "1",dataType = "int")
    public WeiboDetailVO selectDetail(@Range(min = 1, message = "请提交合法的ID值!") int id){
        //System.out.println("id="+id);
        log.debug("id's value is {}",id);
        if(id==-1)
            throw new IllegalArgumentException("id值无效");
        // 无需校验用户登录状态
        return weiboMapper.selectDetail(id);
    }

最后进行访问测试,输入id值小于1的数据,比对进行进行分析

Spring Validation高级应用

Spring Validation在检查请求参数的格式时,会检查所有属性配置的规则,找出所有的错误,
如果希望实现“只要发现错误,就不再向后检查”,需要将其配置为“快速失败”,配置做法是使用配置类:

@Configuration
public class ValidationConfiguration {

    @Bean
    public javax.validation.Validator validator() {
        return Validation.byProvider(HibernateValidator.class)
                .configure() // 开始配置
                .failFast(true) // 配置快速失败
                .buildValidatorFactory() // 构建Validator工厂
                .getValidator(); // 从Validator工厂中获取Validator对象
    }

}

http://www.kler.cn/a/285784.html

相关文章:

  • 刷题DAY24
  • linux tail
  • 使用kafka完成数据的实时同步,同步到es中。(使用kafka实现自动上下架 upper、lower)
  • Spring Cloud Consul入门:服务发现与配置管理的最佳实践
  • 华为OD机试真题 - 荒岛求生 - 栈Stack(Python/JS/C/C++ 2024 E卷 100分)
  • 如何在D盘创建虚拟环境?包括安装PyTorch和配置PyCharm
  • 绝区零苹果电脑能玩吗,如何在Mac上玩绝区零?绝区零MacBook 下载安装保姆级教程
  • 使用 Python 实现自动化办公
  • Spring入门之DI(包含实例代码)
  • IEEE P3233 标准启动会回顾:迈向去中心化存储标准化的第一步
  • C++ 图形框架 Duilib
  • 滚动视图ScrollView
  • 主机安全-网络攻击监测
  • Quartz定时任务
  • 速盾:高防CDN在防御各类攻击方面的重要性和作用
  • 【再回顾面向对象】,关键字Satic、final
  • 【论文阅读】为大规模航空图像应用神经辐射场
  • 【论文阅读】LJP法律判决预测论文笔记
  • Springcloud微服务合并打包,重复路径引发的血案
  • 【微信小程序】分包 - 分包预下载