0
点赞
收藏
分享

微信扫一扫

全局异常处理+JSR303验证

艾米吖 2023-09-21 阅读 39

一、前言

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

二、JSR303简介

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

三、导入依赖

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

四、常用注解

约束注解名称约束注解说明
@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规范)
  • 不支持分组校验
  • 可以用在方法、构造函数、方法参数和成员属性(字段)上
  • 可以加在成员属性(字段)上,能够独自完成级联校验

例子:

/**
* 测试 valid
*/

@ResponseBody
@PostMapping("/valid")
public R valid(@Valid @RequestBody StudentEntity studentEntity, BindingResult result) {
System.out.println(studentEntity.toString());
System.out.println(result.getPropertyEditorRegistry());
System.out.println(result.getGlobalError());
System.out.println(result.getModel());
if (result.hasErrors()) {
Map<String, String> map = new HashMap<>();
//1、获取校验的错误结果
result.getFieldErrors().forEach(item -> {
//FieldError 获取到错误提示
String message = item.getDefaultMessage();
//获取错误的属性的名字
String field = item.getField();
map.put(field, message);
});
return R.error(GlobalExceptionEnume.PROCESSOR_EXCEPTION.getCode(), GlobalExceptionEnume.PROCESSOR_EXCEPTION.getMessage()).put("error", map);
} else {
return R.ok();
}
}

 

抽离全局异常处理

1. 心得体会

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

2. 书写ExceptionControllerAdvice

package com.beijing.gulimall.product.exception;


import com.beijing.common.common.GlobalExceptionEnume;
import com.beijing.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

//@ResponseBody
//@ControllerAdvice
@RestControllerAdvice
@Slf4j
public class GlobalException {


@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R Exception(HttpServletRequest req, MethodArgumentNotValidException e){
String url = req.getRequestURL().toString();
String httpMethod = req.getMethod();
log.info("URL :{} " + url);
log.info("HTTP_METHOD {}: ",httpMethod);
BindingResult bindingResult = e.getBindingResult();
Map<String,String> map = new HashMap<>();
for (FieldError fieldError : bindingResult.getFieldErrors()) {
//FieldError 获取到错误提示
String message = fieldError.getDefaultMessage();
//获取错误的属性的名字
String field = fieldError.getField();
map.put(field,message);
}
return R.error(GlobalExceptionEnume.PROCESSOR_EXCEPTION.getCode(),GlobalExceptionEnume.PROCESSOR_EXCEPTION.getMessage()).put("data",map);
}
//info 日志
//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
//2023-09-18 17:00:01.246 INFO 18164 --- [nio-4000-exec-3] c.b.g.product.exception.GlobalException : HTTP_METHOD POST:

}

测试结果:

{
"msg": "处理器异常",
"code": 500,
"data": {
"age": "最小不能小于10"
}
}

定义枚举和R

package com.beijing.common.common;

public enum GlobalExceptionEnume {

PROCESSOR_EXCEPTION(500,"处理器异常");


private int code;
private String message;

GlobalExceptionEnume(int code, String message) {
this.code = code;
this.message = message;
}

public int getCode() {
return code;
}

public String getMessage() {
return message;
}


public static String getMessageByCode(int code){
for (GlobalExceptionEnume value : GlobalExceptionEnume.values()) {
if (value.getCode() == code){
return value.getMessage();
}
}
return null;
}

}

R.class


package com.beijing.common.utils;

import org.apache.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;


public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;

public R() {
put("code", 0);
put("msg", "success");
}

public static R error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}

public static R error(String msg) {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}

public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}

public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}

public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}

public static R ok() {
return new R();
}

public R put(String key, Object value) {
super.put(key, value);
return this;
}
}
举报

相关推荐

0 条评论