SpringBoot 全局请求参数验证AOP

默认对全局请求参数进行验证,无需加注解 @Validated

定制全局异常处理器GlobalExceptionHandler


/**
 * 全局异常处理
 *
 * @author seer
 * @version 1.0
 * @date 2022/6/9 15:40
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
        log.warn("请求方式不支持 {} {}", request.getServletPath(), e.getMethod());
        return Result.fail(e.getMessage());
    }

    /**
     * 参数验证错误
     */
    @ExceptionHandler(BindException.class)
    public Result handleBindException(BindException e, HttpServletRequest request) {
        String message = e.getAllErrors().get(0).getDefaultMessage();
        log.warn("请求参数错误 {} {}", request.getServletPath(), message);
        return Result.fail(Result.Type.REQUEST_PARAM_ERROR, message);
    }

    /**
     * 参数绑定异常
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result handleBindException(MissingServletRequestParameterException e, HttpServletRequest request) {
        String message = e.getMessage();
        log.warn("参数绑定异常 {} {}", request.getServletPath(), message);
        return Result.fail(Result.Type.REQUEST_PARAM_ERROR, e.getParameterName() + " 未提供");
    }

    /**
     * 参数验证错误
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result handleBindException(ConstraintViolationException e, HttpServletRequest request) {
        String message = e.getMessage();
        log.warn("参数验证错误 {} {}", request.getServletPath(), message);
        return Result.fail(Result.Type.REQUEST_PARAM_ERROR, e.getMessage());
    }
}

自定义AOP GlobalValidAspect

  • 抛出 ConstraintViolationException异常
package com.sdhs.wash.admin.component;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;

/**
 * 请求参数验证
 * 基本数据类型,由@RequestParam注解,走框架
 * 对象由此校验,不区分是否添加 @RequestBody
 *
 * @author seer
 * @date 2022-06-28 22:06:04
 */
@Aspect
@Component
@Slf4j
public class GlobalValidAspect {

    @Autowired
    private SpringValidatorAdapter validator;

    /**
     * 前置
     *
     * @param joinPoint joinPoint
     */
    @Before("execution(public * com.sdhs.oilcoreserver.admin.controller.*.*(..))")
    public void atBefore(JoinPoint joinPoint) {
        for (Object arg : joinPoint.getArgs()) {
            Set> violationSet = validator.validate(arg);
            if (!violationSet.isEmpty()) {
                throw new ConstraintViolationException(violationSet.iterator().next().getMessage(), null);
            }
            return;
        }
    }
}

controller中表现

@RequestBody 注解的json请求参数

 /**
     * 修改密码
     *
     * @param requestDTO requestDTO
     * @return object
     */
    @ApiOperation(value = "修改密码")
    @PostMapping("/change-pwd")
    public Result changePwd(@RequestBody UserChangePwdRequestDTO requestDTO) {
        log.info("修改密码,请求 {}", requestDTO);
        Result response = service.changePwd(requestDTO);
        log.info("修改密码,响应 {}", response.toSensitiveString());
        return response;
    }

封装为实体的form请求参数

   @ApiOperation(value = "用户查询",
            response = UserQryResponseDTO.class)
    @GetMapping("/user/query")
    public Result userQuery(KeywordRequestDTO requestDTO) {
        Result response = service.userQuery(requestDTO);
        if (log.isDebugEnabled()) {
            log.debug("用户查询,响应 {}", response);
        }
        return response;
    }

@RequestParam注解的参数

  • 此类参数,由Spring框架校验,校验失败抛出BindException异常
 /**
     * 字典查询
     *
     * @return object
     */
    @ApiOperation(value = "字典查询", response = DictQryResponseDTO.class)
    @ApiImplicitParam(name = "group", value = "字典分组")
    @GetMapping("/dict-query")
    public Result dictQuery(@RequestParam(value = "group") String group) {
        return service.dictQuery(group);
    }

你可能感兴趣的:(SpringBoot 全局请求参数验证AOP)