Java后端优雅验证参数合法性

一、统一异常处理器

package com.clicks.intercepter;

import com.clicks.pojo.response.CodeMsg;
import com.clicks.pojo.response.Result;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 方延杰
 * @version 1.0
 * @since 2018/10/19 8:11 下午
 */
@RestControllerAdvice
public class ExceptionInterceptor {
    /**
     * @param e 异常信息
     * @return 类异常
     */
    @ExceptionHandler(BindException.class)
    public Result<String> handleEx(BindException e) {
        List<FieldError> fieldErrors = e.getFieldErrors();
        String message = fieldErrors.stream().map(fe -> fe.getField() + fe.getDefaultMessage()).collect(Collectors.joining(","));
        return fail(400, message);
    }

    /**
     * @param e 异常信息
     * @return 方法异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<String> handleEx(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> set = e.getConstraintViolations();
        String message = set.stream().map(fe -> fe.getPropertyPath() + fe.getMessage()).collect(Collectors.joining(","));
        return fail(400, message);
    }

    /**
     * @param failMessage 参数校验错误信息
     * @return 封装响应体
     */
    private Result<String> fail(Integer code, String message) {
        CodeMsg codeMsg = new CodeMsg(code, message);
        return Result.fail(codeMsg);
    }

    /**
     * @param e 异常信息
     * @return 全局信息
     */
    @ExceptionHandler(Exception.class)
    public Result<String> handleEx(Exception e) {
        e.printStackTrace();
        return fail(500, e.getMessage());
    }
}

二、ValidatedUtils校验工具类

package com.clicks.util;

import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.constraints.Length;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 方延杰
 * @version 1.0
 * @since 2018/10/19 9:18 下午
 */
@SuppressWarnings("unused")
public class ValidatedUtils {
    // 线程安全
    private static final Validator validator;
    // 快速失败
    private static final Validator failFastValidator;
    // 校验入参或返回值的
    private static final ExecutableValidator executableValidator;

    static {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
        failFastValidator = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();
        executableValidator = validator.forExecutables();
    }

    /**
     * @param object          this
     * @param method          方法名
     * @param parameterValues 对象数组
     * @param groups          组别
     * @return 校验信息
     */
    public static String validNotBean(Object object, Method method, Object[] parameterValues, Class<?>... groups) {
        Set<ConstraintViolation<Object>> set = executableValidator.validateParameters(object, method, parameterValues, groups);
        return getMessage(set);
    }

    /**
     * 方法非bean类型的入参校验
     * 1.方法参数前加注解
     * 2.执行入参校验,真正要用的话可以使用aop编程的思想来使用
     *
     * @param name 参数
     * @return 校验信息
     */
    public String getByName(@Length(min = 3) String name) {
        StackTraceElement st = Thread.currentThread().getStackTrace()[1];
        String methodName = st.getMethodName();
        Method method = null;
        try {
            method = this.getClass().getDeclaredMethod(methodName, String.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return validNotBean(this, method, new Object[]{name});
    }

    public static void main(String[] args) {
        String byName = new ValidatedUtils().getByName("");
        System.out.println(byName);
    }

    /**
     * 快速失败
     *
     * @param object 实体对象
     * @param groups 组别
     * @return 校验信息
     */
    public static String validFailFast(Object object, Class<?>... groups) {
        Set<ConstraintViolation<Object>> set = failFastValidator.validate(object, groups);
        return getMessage(set);
    }

    /**
     * @param object 实体对象
     * @param groups 组别
     * @return 校验信息
     */
    public static String valid(Object object, Class<?>... groups) {
        Set<ConstraintViolation<Object>> set = validator.validate(object, groups);
        return getMessage(set);
    }

    /**
     * @param set 不符合规则集
     * @return 校验信息以逗号隔开
     */
    private static String getMessage(Set<ConstraintViolation<Object>> set) {
        return set.stream().map(v -> v.getPropertyPath() + v.getMessage())
                .collect(Collectors.joining(","));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值