• 全局异常处理+JSR303验证


    一、前言

    我们在日常开发中,避不开的就是参数校验,有人说前端不是会在表单中进行校验的吗?在后端中,我们可以直接不管前端怎么样判断过滤,我们后端都需要进行再次判断, 为了安全 。因为前端很容易拜托,当测试使用 PostMan 来测试,如果后端没有校验,不就乱了吗?肯定会有很多异常的。今天小编和大家一起学习一下JSR303专门用于参数校验的,算是一个工具吧!

    二、JSR303简介

    JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,

    三、导入依赖

    
        javax.validation
        validation-api
        2.0.1.Final
    

    四、常用注解

    约束注解名称约束注解说明
    @Null用于验证对象为null
    @NotNull用于对象不能为null,无法查检长度为0的字符串
    @NotBlank只用于String类型上,不能为null且trim()之后的size>0
    @NotEmpty用于集合类、String类不能为null,且size>0。但是带有空格的字符串校验不出来
    @Size用于对象(Array,Collection,Map,String)长度是否在给定的范围之内
    @Length用于String对象的大小必须在指定的范围内
    @Pattern用于String对象是否符合正则表达式的规则
    @Email用于String对象是否符合邮箱格式
    @Min用于Number和String对象是否大等于指定的值
    @Max用于Number和String对象是否小等于指定的值
    @AssertTrue用于Boolean对象是否为true
    @AssertFalse用于Boolean对象是否为false

    所有的大家参考jar包

    五、@Valid

    @Valid:

    • JDK提供的(标准JSR-303规范)
    • 不支持分组校验
    • 可以用在方法、构造函数、方法参数和成员属性(字段)上
    • 可以加在成员属性(字段)上,能够独自完成级联校验

    例子:

    1. /**
    2. * 测试 valid
    3. */
    4. @ResponseBody
    5. @PostMapping("/valid")
    6. public R valid(@Valid @RequestBody StudentEntity studentEntity, BindingResult result) {
    7. System.out.println(studentEntity.toString());
    8. System.out.println(result.getPropertyEditorRegistry());
    9. System.out.println(result.getGlobalError());
    10. System.out.println(result.getModel());
    11. if (result.hasErrors()) {
    12. Map map = new HashMap<>();
    13. //1、获取校验的错误结果
    14. result.getFieldErrors().forEach(item -> {
    15. //FieldError 获取到错误提示
    16. String message = item.getDefaultMessage();
    17. //获取错误的属性的名字
    18. String field = item.getField();
    19. map.put(field, message);
    20. });
    21. return R.error(GlobalExceptionEnume.PROCESSOR_EXCEPTION.getCode(), GlobalExceptionEnume.PROCESSOR_EXCEPTION.getMessage()).put("error", map);
    22. } else {
    23. return R.ok();
    24. }
    25. }

    抽离全局异常处理

    1. 心得体会

    上面我们要在每个校验的接口上面写,所以我们要抽离出来做个全局异常。并且要改进一下,原来的是把错误信息放到data里,但是正常情况下的data是返回给前端的数据。!

    2. 书写ExceptionControllerAdvice

    1. package com.beijing.gulimall.product.exception;
    2. import com.beijing.common.common.GlobalExceptionEnume;
    3. import com.beijing.common.utils.R;
    4. import lombok.extern.slf4j.Slf4j;
    5. import org.springframework.validation.BindingResult;
    6. import org.springframework.validation.FieldError;
    7. import org.springframework.web.bind.MethodArgumentNotValidException;
    8. import org.springframework.web.bind.annotation.ExceptionHandler;
    9. import org.springframework.web.bind.annotation.RestControllerAdvice;
    10. import javax.servlet.http.HttpServletRequest;
    11. import java.util.HashMap;
    12. import java.util.Map;
    13. //@ResponseBody
    14. //@ControllerAdvice
    15. @RestControllerAdvice
    16. @Slf4j
    17. public class GlobalException {
    18. @ExceptionHandler(value = MethodArgumentNotValidException.class)
    19. public R Exception(HttpServletRequest req, MethodArgumentNotValidException e){
    20. String url = req.getRequestURL().toString();
    21. String httpMethod = req.getMethod();
    22. log.info("URL :{} " + url);
    23. log.info("HTTP_METHOD {}: ",httpMethod);
    24. BindingResult bindingResult = e.getBindingResult();
    25. Map map = new HashMap<>();
    26. for (FieldError fieldError : bindingResult.getFieldErrors()) {
    27. //FieldError 获取到错误提示
    28. String message = fieldError.getDefaultMessage();
    29. //获取错误的属性的名字
    30. String field = fieldError.getField();
    31. map.put(field,message);
    32. }
    33. return R.error(GlobalExceptionEnume.PROCESSOR_EXCEPTION.getCode(),GlobalExceptionEnume.PROCESSOR_EXCEPTION.getMessage()).put("data",map);
    34. }
    35. //info 日志
    36. //2023-09-18 17:00:01.245 INFO 18164 --- [nio-4000-exec-3]c.b.g.product.exception.GlobalException : URL :{}http://127.0.0.1:4000/product/skuinfo/valid2
    37. //2023-09-18 17:00:01.246 INFO 18164 --- [nio-4000-exec-3] c.b.g.product.exception.GlobalException : HTTP_METHOD POST:
    38. }

    测试结果:

    1. {
    2. "msg": "处理器异常",
    3. "code": 500,
    4. "data": {
    5. "age": "最小不能小于10"
    6. }
    7. }

    定义枚举和R

    1. package com.beijing.common.common;
    2. public enum GlobalExceptionEnume {
    3. PROCESSOR_EXCEPTION(500,"处理器异常");
    4. private int code;
    5. private String message;
    6. GlobalExceptionEnume(int code, String message) {
    7. this.code = code;
    8. this.message = message;
    9. }
    10. public int getCode() {
    11. return code;
    12. }
    13. public String getMessage() {
    14. return message;
    15. }
    16. public static String getMessageByCode(int code){
    17. for (GlobalExceptionEnume value : GlobalExceptionEnume.values()) {
    18. if (value.getCode() == code){
    19. return value.getMessage();
    20. }
    21. }
    22. return null;
    23. }
    24. }

    R.class

    1. package com.beijing.common.utils;
    2. import org.apache.http.HttpStatus;
    3. import java.util.HashMap;
    4. import java.util.Map;
    5. public class R extends HashMap {
    6. private static final long serialVersionUID = 1L;
    7. public R() {
    8. put("code", 0);
    9. put("msg", "success");
    10. }
    11. public static R error() {
    12. return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
    13. }
    14. public static R error(String msg) {
    15. return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
    16. }
    17. public static R error(int code, String msg) {
    18. R r = new R();
    19. r.put("code", code);
    20. r.put("msg", msg);
    21. return r;
    22. }
    23. public static R ok(String msg) {
    24. R r = new R();
    25. r.put("msg", msg);
    26. return r;
    27. }
    28. public static R ok(Map map) {
    29. R r = new R();
    30. r.putAll(map);
    31. return r;
    32. }
    33. public static R ok() {
    34. return new R();
    35. }
    36. public R put(String key, Object value) {
    37. super.put(key, value);
    38. return this;
    39. }
    40. }

  • 相关阅读:
    电商前台项目(三):完成Search搜索模块业务
    leetCode 76. 最小覆盖子串 + 滑动窗口 + 哈希Hash
    深入理解Linux中信号处理过程
    OpenCV开发笔记(七十五):相机标定矫正中使用remap重映射进行畸变矫正
    2分钟,带你走完企业经营分析全流程,更有通用分析框架直接套用
    Eclipse插件RCP桌面应用开发的点点滴滴
    【LeetCode-中等题】 222. 完全二叉树的节点个数
    Pytorch获取特征图
    自动化测试的类型​以及自动化测试的几个误区!
    DAY9-力扣刷题
  • 原文地址:https://blog.csdn.net/weixin_42383680/article/details/132981659